Skip to content

Remove over-engineered code paths flagged by the audit - #202

Merged
Sev7eNup merged 5 commits into
mainfrom
refactor/remove-dead-abstractions
Aug 14, 2026
Merged

Remove over-engineered code paths flagged by the audit#202
Sev7eNup merged 5 commits into
mainfrom
refactor/remove-dead-abstractions

Conversation

@Sev7eNup

Copy link
Copy Markdown
Owner

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 a
    single atomic ExecuteUpdateAsync, and the determinism it implied is explicitly not
    promised — docs/claude-reference.md documents last-write-wins on the whole JSON.
  • WorkflowDbWriteMetrics: SaveChangesMeasuredAsync delegates to ExecuteMeasuredAsync
    instead 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
    _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.
    Removing them is a net security gain.

Api / Mcp / Ai

  • CmTraceFormatter: replace the hand-rolled in-place substitution loop with
    StringBuilder.Replace. Equivalence checked for multiple occurrences and overlap before the
    swap; a multi-occurrence test was added.
  • Observability: drop four DTO records that were never constructed and three response fields
    that were always empty, plus their TypeScript mirrors.
  • DefinitionDiff: replace the custom canonicalising serializer and its
    JsonEquals(a, b) => a == b wrapper with JsonNode.DeepEquals.
  • 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.
    IOptionsMonitor is 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. Six
    catalog types the table had missed (textFileEdit, forEach, startWorkflow, returnData,
    llmQuery, generateText) are now coloured instead of grey. Behaviour change: an
    unknown 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: the comingSoon branch was unreachable (ready: false exists nowhere
    in 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 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.

Verification

Scoped suites for every touched area plus the guard tests the changes trigger:
ActivityCatalogTests, ActivityConfigReferenceTests, ActivityCatalogFrontendSyncTests,
MetricsDashboardCatalogTests, AdminSettingsFrontendSyncTests, ApiDtoParityTests. Full
backend suite (5612) and full frontend unit suite (2657) pass; tsc --noEmit clean; no new
compiler warning in any touched file.

Stacked on #201 — merge that one first.

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
Sev7eNup force-pushed the refactor/remove-dead-abstractions branch from cc27104 to d7ed3e2 Compare August 14, 2026 18:53
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&section=<id> back into the query string.
@Sev7eNup
Sev7eNup force-pushed the refactor/remove-dead-abstractions branch from d7ed3e2 to 29b0417 Compare August 14, 2026 19:09
@Sev7eNup
Sev7eNup merged commit 29b0417 into main Aug 14, 2026
8 of 10 checks passed
@Sev7eNup
Sev7eNup deleted the refactor/remove-dead-abstractions branch August 14, 2026 19:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant