Context
Leaf of #13056. The cross-family review of #13126 (LockRegistry) required, as a Post-Merge contract, that "the enforcement slice constructs subtreePath as the absolute root→node component-id path" — because LockRegistry.pathsOverlap is sound only for absolute paths (a relative path lets unrelated subtrees sharing a head id false-overlap). This leaf delivers that derivation as a pure, reusable function: the bridge between a live component id and the subtreePath that WriteGuard (#13134) / LockRegistry (#13125) consume.
Release classification: boardless — harness coordination line. Unblocked (off dev; does not import LockRegistry/WriteGuard).
Scope (this leaf — pure)
deriveSubtreePath(componentId, parentOf):
- walks the parent chain from
componentId up to the root via the injected parentOf(id) → parentId|null lookup, returning the absolute root→node id array [rootId, …, componentId];
- stops at a falsy parent or Neo's top-level sentinel
'document.body' (the top component is the root; the body is not a component);
- cycle-guarded (a repeated id in the chain → fail-closed
null, never an infinite loop);
- fail-closed on a malformed
componentId (null).
parentOf is injected so the function is pure and unit-testable with a mock tree; the wiring supplies the live lookup (id => Neo.getComponent(id)?.parentId, built on Neo.component.Base#parentId / #up).
Out of Scope (named follow-up: the enforcement-wiring slice)
- The live
parentOf lookup + intercepting InstanceService.setInstanceProperties (and the other write-class client services) to call WriteGuard.requestWrite and deny on conflict — the integration / whitebox-e2e slice.
WriteGuard itself (#13134) and LockRegistry (#13125).
Contract Ledger
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Evidence |
deriveSubtreePath(componentId, parentOf) |
this leaf + #13126 review absolute-path contract |
absolute root→node id array; stops at falsy parent / document.body |
malformed id or cycle → null (fail-closed) |
unit: linear chain, root/body stop, cycle, missing id |
Decision Record impact
Satisfies the #13126 Post-Merge absolute-subtreePath contract. aligned-with ADR 0020 guardrail #1. No ADR amendment.
Acceptance Criteria
Related
Parent: #13056. Refs #13012, #13125 / PR #13126 (the absolute-path contract), #13134 / PR #13135 (WriteGuard consumer), src/ai/client/InstanceService.mjs:75.
Origin Session ID: 4c598c8f-d8a7-4288-9420-e825a45d310e
Retrieval Hint: "derive absolute subtree path root to node component id parentOf cycle-guard NL topological lock enforcement subtreePath"
Context
Leaf of #13056. The cross-family review of #13126 (
LockRegistry) required, as a Post-Merge contract, that "the enforcement slice constructssubtreePathas the absolute root→node component-id path" — becauseLockRegistry.pathsOverlapis sound only for absolute paths (a relative path lets unrelated subtrees sharing a head id false-overlap). This leaf delivers that derivation as a pure, reusable function: the bridge between a live component id and thesubtreePaththatWriteGuard(#13134) /LockRegistry(#13125) consume.Release classification:boardless — harness coordination line. Unblocked (offdev; does not importLockRegistry/WriteGuard).Scope (this leaf — pure)
deriveSubtreePath(componentId, parentOf):componentIdup to the root via the injectedparentOf(id) → parentId|nulllookup, returning the absolute root→node id array[rootId, …, componentId];'document.body'(the top component is the root; the body is not a component);null, never an infinite loop);componentId(null).parentOfis injected so the function is pure and unit-testable with a mock tree; the wiring supplies the live lookup (id => Neo.getComponent(id)?.parentId, built onNeo.component.Base#parentId/#up).Out of Scope (named follow-up: the enforcement-wiring slice)
parentOflookup + interceptingInstanceService.setInstanceProperties(and the other write-class client services) to callWriteGuard.requestWriteand deny on conflict — the integration / whitebox-e2e slice.WriteGuarditself (#13134) andLockRegistry(#13125).Contract Ledger
deriveSubtreePath(componentId, parentOf)document.bodynull(fail-closed)Decision Record impact
Satisfies the #13126 Post-Merge absolute-
subtreePathcontract. aligned-with ADR 0020 guardrail #1. No ADR amendment.Acceptance Criteria
deriveSubtreePathreturns the absolute root→node id path via an injectedparentOf, unit-tested (linear chain; root anddocument.bodystops; mid-chain absent parent; cycle → null; malformed id → null).Neo.getComponentlookup at the write site) is the named e2e residual.Related
Parent: #13056. Refs #13012, #13125 / PR #13126 (the absolute-path contract), #13134 / PR #13135 (WriteGuard consumer),
src/ai/client/InstanceService.mjs:75.Origin Session ID: 4c598c8f-d8a7-4288-9420-e825a45d310e Retrieval Hint: "derive absolute subtree path root to node component id parentOf cycle-guard NL topological lock enforcement subtreePath"