Skip to content

T-U2JP-guard-cross-package-relative-reaches

State: open/ready · Impact: medium · Complexity: small

AUTO-DEFINED: this spec was best-effort machine-authored by /sdlc:task-auto-define on 2026-09-13 because the task is autonomy: autonomous/pr. Review the Goal, Approach, Today, Files-to-touch, and Acceptance-criteria carefully before trusting it.

A package git mv move recipe checks for the moved paths with a literal string grep, but a live cross-package relative import (e.g. resolve(__dirname, '../../other-package/x')) does not contain the moved path as a substring, so it survives the grep and only fails at build/test time. Make the move recipe (or a repo-wide guard) catch these.

Two live relative paths (tests/ui/mvux/vault-nodes.vaults.e2e.ts, experiences/fitness/tests/admin-registry.test.ts) resolved into the moved package by .. segments and were invisible to a path grep — a move recipe should grep for resolve( and ../ reaches into the moved directory, or the repo should ban cross-package relative reaches.

— from T-4VNC-learning-p1-scaffold-solution’s post-mortem

LocationRole today
solutions/ontological/lib/model/entities/task/implementation-ready.mdUnder “Files to touch”, the delete-row paragraph mandates enumerating files that reference a removed/moved path as modify rows, but says nothing about finding an indirect relative-path reach — only a literal-path grep is implied
solutions/ontological/skills/task-define/SKILL.mdStep 4’s Today/Files-to-touch drafting bullet (“When the gap is in ## Today or ## Files to touch”) covers table shape and the five-form Location grammar, but has no reference-sweep methodology for delete rows
solutions/ontological/skills/task-auto-define/SKILL.mdStep 5’s codebase-context bullet tells the synthesizer to confirm cited modify/delete paths exist, but says nothing about finding indirect reaches
solutions/determined/experiences/fitness/tests/admin-registry.test.tsReads a sibling package’s generated file via new URL('../../../packages/vault-platform-client/src/generated/transport.ts', import.meta.url) — a live relative reach whose specifier never spells out solutions/determined/packages/vault-platform-client, so a literal grep for that path misses it
solutions/determined/tests/ui/mvux/vault-nodes.vaults.e2e.tsReaches the same generated file via resolve(here, '..', '..', '..', 'packages/vault-platform-client/src/generated/transport.ts') — same gap, a resolve() call rather than a new URL() call

Extend the delete-row reference-enumeration paragraph in implementation-ready.md with a second-grep mandate: alongside the literal-path grep for the moved/removed path, the sweep must also search for resolve( and new URL( call sites that contain a .. path segment, then check whether each hit’s joined path lands inside the directory being moved. task-define and task-auto-define gain a matching one-line reminder at the point where they draft delete-row touchpoints, pointing back at the contract so the mandate is discoverable at the moment a sweep is run — the same contract-plus-two-skill-mirrors shape T-PSR1-reference-sweep-greps-unfiltered used for its unfiltered-grep mandate (that task was superseded before it landed; this task carries the shape through for this adjacent gap).

  1. In solutions/ontological/lib/model/entities/task/implementation-ready.md, extend the existing delete-row enumeration sentence under “Files to touch” (the “also enumerate every file that references the removed path” paragraph). Add: the sweep must also grep for resolve( and new URL( call sites that contain a .. path segment, not rely on the literal-path grep alone — a relative-path reach built from separate segments can land inside the moved directory without the moved path ever appearing as a substring. State this as a parenthetical failure-pattern note, matching the style of the existing “(the recurring shape: …)” note already in that paragraph.
  2. In solutions/ontological/skills/task-define/SKILL.md, Step 4 (“Resolve gaps one at a time”), inside the ## Today / ## Files to touch drafting bullet block, add one line: when a row is delete, also grep for resolve(/new URL( call sites with a .. segment when enumerating references, per the implementation-ready contract.
  3. In solutions/ontological/skills/task-auto-define/SKILL.md, Step 5 (“Synthesize gap fills”), inside the ## Today / ## Files to touch codebase-context bullet, add the matching one-line reminder for delete rows.
  4. Keep the three edits consistent in wording — the rule is stated once, in the contract, and referenced (never restated) in the two skills.
AreaNote
solutions/ontological/lib/model/entities/task/implementation-ready.mdExtend the delete-row reference-enumeration paragraph under “Files to touch”: mandate a second grep for resolve(/new URL( call sites containing a .. segment, and name the generic failure pattern (a relative climb reaching the moved directory without the moved path appearing as a substring).
solutions/ontological/skills/task-define/SKILL.mdIn Step 4’s Today/Files-to-touch drafting bullet: add a one-line reminder that a delete row’s reference sweep must also grep for indirect relative reaches, pointing at the contract.
solutions/ontological/skills/task-auto-define/SKILL.mdIn Step 5’s codebase-context bullet: add the matching one-line reminder for delete-row reference enumeration.
  • AC-1: implementation-ready.md’s delete-row paragraph (under “Files to touch”) states that the reference sweep must also check for resolve( or new URL( call sites containing a .. segment, not only a literal grep for the moved path.
  • AC-2: That same paragraph names the generic failure pattern: a relative-path reach built from separate segments can land inside the moved directory without the moved path ever appearing as a substring.
  • AC-3: solutions/ontological/skills/task-define/SKILL.md contains a one-line reminder, at its Today/Files-to-touch drafting guidance (Step 4), to also grep for indirect relative reaches when enumerating references for a delete row, pointing back at the contract rather than restating the rule.
  • AC-4: solutions/ontological/skills/task-auto-define/SKILL.md contains the matching one-line reminder at its delete-row codebase-context guidance (Step 5).
  • AC-5: solutions/ontological/cli/sdlc entities validate against this file, docs/planning/tasks/T-U2JP-guard-cross-package-relative-reaches.md, exits 0.
  • Building an automated CI guard or script that runs the indirect-reach grep for the implementer. This task mandates the methodology in prose, the same route T-PSR1-reference-sweep-greps-unfiltered took for the unfiltered-grep mandate; mechanizing it is separate work if the manual sweep proves too easy to skip.
  • Fixing the two existing relative reaches cited above (admin-registry.test.ts, vault-nodes.vaults.e2e.ts) — they remain as-is; migrating them off a relative climb is separate work.
  • Auditing the rest of the repo for other instances of the same pattern.
  • Changing the five-form Location grammar or the Files-to-touch/Today table shapes — only the delete-row enumeration methodology changes.
  • none

Spawned by /sdlc:spawn-task-pr on 2026-09-13 UTC from T-4VNC-learning-p1-scaffold-solution in git@github.com:sksizer/dev.git.


← Back to Tasks