Remove over-engineered code paths flagged by the audit - #202
Merged
Conversation
A repo-wide clone scan plus a semantic pass found ~85 verified places where the same logic existed more than once. This removes them, mostly by routing callers through a helper or base type that already existed. Backend: - Five retention services shared a byte-identical ExecuteAsync loop; they now derive from LeaderGatedRetentionService. The broad catch stays in each service's RunIterationAsync, one level below the host-fatal boundary. - fileOperation/folderOperation share FileSystemOperationActivityBase; the marker-envelope PostProcess preamble is now one helper used by seven activities. - The AES-GCM envelope (version byte + nonce + ciphertext + tag) had two independent implementations; both now use SecretEnvelope. Header validation stays outside the metrics scope, as before. - Crypto call/latency instrumentation collapses into DataMetrics.MeasureCrypto. - The ExecRow projection, the long-running/queued-long collectors, the NotificationDispatcher send tail, CsvField, the trigger manual.* extraction and the folder-tree helpers each exist once now. - ScimProvisioningService now forwards audits through AuditEventForwarder instead of hand-rolling the ECS scope. This fixes a real inconsistency: it hard-coded event.category=iam where the shared classifier returns "configuration" for SCIM_GROUP_* codes. Clients: - ApiException, the response plumbing and the config.json read side move to NodePilot.Core.Clients, shared by the CLI and the MCP server. The DTO copies stay duplicated on purpose (ApiDtoParityTests). Frontend: - The AI chat message mutators and the thread picker were duplicated between the designer panel and the global chat page; both now share one module. - LoggingTelemetrySection carried a private fork of useSectionForm. The fork had drifted and was the better version (it re-sends the mapped payload after a 412), so that behaviour moved into the shared hook before the fork was removed. - useDashboardFeed/useOperationsFeed, the type-the-phrase confirm dialog and the node context menu now use shared implementations. Dead code: three unused DbErrorClassifier predicates, a deprecated cloneableConfigKeys alias, four unused frontend exports, two orphaned stress scripts and an unused npm dependency. Test doubles: FakeSmtpServer, CapturingLogger, StubHttpClientFactory, StubGlobalVariableStore and FakeEngine each existed in two places; they now live in TestCommons or a shared Helpers file. ActivityConfigReferenceTests learned to follow an executor's base class and helpers, so config keys that moved into shared types stay verified instead of being exempted. Net effect: 1407 fewer lines of code. Full backend suites (5486 tests) and the frontend suite (2596 tests) pass; the solution builds clean.
Folding the three field pickers onto one PickerPopover passed the whole useSearchablePicker() result through as a prop. Inside the component that object is opaque, so the React Compiler treats every read on it as a ref access during render and eslint fails the build with seven "Cannot access refs during render" errors. Destructure once at the top of the component instead. The refs are then forwarded as plain values, which is what the pre-dedup code did and what AnchoredPickerPopover expects.
Sev7eNup
force-pushed
the
refactor/remove-dead-abstractions
branch
from
August 14, 2026 18:53
cc27104 to
d7ed3e2
Compare
Both armed-trigger blackout tests split their evaluator verdict on "now + 30 seconds", while the fixture's cron fires at the top of the coming hour. Whenever the suite runs in the last half minute of an hour the cutoff lands past the fire time and the split inverts, so the flagged case reports no window and the not-flagged case reports one. CI hit exactly that at 19:00:20Z. Derive the cutoff from the hour boundary instead and place it midway, so it is strictly between "now" and the fire time at every wall-clock moment.
A repo-wide sweep looked for code that a smaller solution would cover just as well. These twelve findings survived an adversarial check for hidden consumers, test doubles and documented conventions. Engine - ReturnDataActivity: drop the refcounted per-execution semaphore registry. It guarded a single atomic ExecuteUpdateAsync, and the determinism it implied is explicitly not promised (last-write-wins). - WorkflowDbWriteMetrics: SaveChangesMeasuredAsync now delegates to ExecuteMeasuredAsync instead of repeating its body; the two error catches collapse into one that keeps the cancelled/failure split. - BaseRemoteActivity: delete the unreachable four-argument constructor and make _configuration non-nullable. All thirteen subclasses already passed a configuration, so the null-config branches in StartProgramActivity, PowerManagementActivity and WaitForConditionActivity were dead - and they silently permitted useShellExecute and skipped the path guards. Api - CmTraceFormatter: replace the hand-rolled in-place substitution loop with StringBuilder.Replace. - Observability: drop four DTO records that were never constructed and three response fields that were always empty, plus their TypeScript mirrors. Mcp - DefinitionDiff: replace the custom canonicalising serializer and its JsonEquals(a, b) => a == b wrapper with JsonNode.DeepEquals. Ai - LlmConfiguredProxy: drop the six-field cache record and its SequenceEqual comparison. It avoided constructing a WebProxy on a path capped at 20 requests per minute. Frontend - NodeLibrary: remove the 23-entry Tailwind colour table that shadowed the generated --act-* tokens without a dark variant, and read the shared activity visual instead. Six catalog types that the table missed are now coloured correctly. - configClone: drop the skip-key registry for a provably empty set. - SystemSettingsPage: remove the unreachable comingSoon branch and replace the nine-way || chain and ternary with a lookup record. Tooling - dev-reset.ps1: remove the SkipTests switch that defaulted to true and therefore disabled its own block. - Delete the MockRemoteSession test helper; its single caller now builds the mock inline like the other fifteen activity test files.
SystemSettingsPage had no vitest file, so the LABEL_KEYS record that replaced the nine-way || chain went in unguarded. It doubles as the whitelist for the ?section= deep link, which makes the mapping worth pinning: one tab per sub-tab, every label translated (a missing key would render as "adminSettings:subTabX"), each section reachable by deep link, an unknown value falling back to integrations, and a click writing tab=system§ion=<id> back into the query string.
Sev7eNup
force-pushed
the
refactor/remove-dead-abstractions
branch
from
August 14, 2026 19:09
d7ed3e2 to
29b0417
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A repo-wide sweep looked for code that a smaller solution would cover just as well: 994 source
files were read across 15 partitions, producing 109 candidates. Each one was then handed to a
skeptic tasked with refuting it — is there a second consumer, is the type mocked in tests, does
CLAUDE.md or a guard test mandate the structure, does the simpler variant actually work under
the dependency rules. 42 candidates fell there. These twelve are what survived.
Net effect: -299 lines of source, +360 lines of test.
Engine
ReturnDataActivity: drop the refcounted per-execution semaphore registry. It guarded asingle atomic
ExecuteUpdateAsync, and the determinism it implied is explicitly notpromised —
docs/claude-reference.mddocuments last-write-wins on the whole JSON.WorkflowDbWriteMetrics:SaveChangesMeasuredAsyncdelegates toExecuteMeasuredAsyncinstead of repeating its body; the duplicated catches collapse into one that keeps the
cancelled/failure split. New tests pin the metric names, tags and ordering via a
MeterListener.BaseRemoteActivity: delete the unreachable four-argument constructor and make_configurationnon-nullable. All thirteen subclasses already passed a configuration, so thenull-config branches in
StartProgramActivity,PowerManagementActivityandWaitForConditionActivitywere dead — and they silently permitteduseShellExecuteandskipped the path guards. Removing them is a net security gain.
Api / Mcp / Ai
CmTraceFormatter: replace the hand-rolled in-place substitution loop withStringBuilder.Replace. Equivalence checked for multiple occurrences and overlap before theswap; a multi-occurrence test was added.
that were always empty, plus their TypeScript mirrors.
DefinitionDiff: replace the custom canonicalising serializer and itsJsonEquals(a, b) => a == bwrapper withJsonNode.DeepEquals.LlmConfiguredProxy: drop the six-field cache record and itsSequenceEqualcomparison. Itavoided constructing a
WebProxyon a path capped at 20 requests per minute.IOptionsMonitoris still read per request, so the section stays hot-reloadable.Frontend
NodeLibrary: remove the 23-entry Tailwind colour table that shadowed the generated--act-*tokens without a dark variant, and read the shared activity visual instead. Sixcatalog types the table had missed (
textFileEdit,forEach,startWorkflow,returnData,llmQuery,generateText) are now coloured instead of grey. Behaviour change: anunknown activity type now renders the runScript visual rather than a grey help icon — the
price of matching the canvas.
configClone: drop the skip-key registry for a provably empty set.SystemSettingsPage: thecomingSoonbranch was unreachable (ready: falseexists nowherein the repo); the nine-way
||chain and ternary become a lookup record that doubles as the?section=deep-link whitelist. A new vitest covers the sub-tab routing, which had none.Tooling
dev-reset.ps1: remove theSkipTestsswitch that defaulted to$trueand thereforedisabled its own block.
MockRemoteSessiontest helper; its single caller now builds the mock inline likethe other fifteen activity test files.
Verification
Scoped suites for every touched area plus the guard tests the changes trigger:
ActivityCatalogTests,ActivityConfigReferenceTests,ActivityCatalogFrontendSyncTests,MetricsDashboardCatalogTests,AdminSettingsFrontendSyncTests,ApiDtoParityTests. Fullbackend suite (5612) and full frontend unit suite (2657) pass;
tsc --noEmitclean; no newcompiler warning in any touched file.
Stacked on #201 — merge that one first.