Skip to content

Skills path parity: install_skills, skills_status and skill_usage join global paths as skills 1.7.0 does - #482

Merged
seathatflowsinourveins merged 6 commits into
mainfrom
claude/skills-path-normalization-20260928
Sep 29, 2026
Merged

seathatflowsinourveins merged 6 commits into
mainfrom
claude/skills-path-normalization-20260928

Conversation

@seathatflowsinourveins

Copy link
Copy Markdown
Collaborator

Scope

This finishes the path-resolution parity that #467 started. Every global path that tools/adoption/install_skills.py, scripts/skills_status.py and tools/skill-usage/skill_usage.py read now matches the pinned skills 1.7.0 CLI. A rollback read-back or a status report can therefore no longer look somewhere other than where the CLI wrote.

  • Lane: lane:foundation. manifests/evidence.json is only re-registered.
  • install_skills.py:
    • lock_file_path and the global canonical_skill_dir now follow Node path.join semantics through one shared node_path_join.
    • project_containment_problem compares the CLI's lexical home, not the physically resolved --home.
  • skills_status.py:
    • The lock, canonical folder and Claude link folder are joined the way the CLI joins them.
    • The Claude link folder honours CLAUDE_CONFIG_DIR, trimmed with the JS trim set.
    • settings.json follows Claude Code's own relocation rule.
    • config.toml follows CODEX_HOME as Codex 0.157.1 resolves it.
  • skill_usage.py: any non-empty XDG_STATE_HOME is used, as the CLI uses it, joined with node_path_join.
  • evidence/artifacts/skills-listing-restore-20260928/README.md gets an appended dated erratum only. tree_drift_check.py and its recorded outputs stay byte-identical.
  • catalogs/foundation/manifest.json: the M6 gate's drifted docs/secret-storage.md citations are repaired.
  • Not touched: blueprints/runtime-workers/*, docs/secret-storage.md, the PR-H: E2E preregistration for the token-save-practice stack (frozen tasks, metrics, gate, procedure) #381 artifacts and every dated receipt. The Runtime-worker skills program: project-scoped installs and a 137-skill manifest #429 program owner (token-save-practice-e2e-status) was told before this PR opened and confirmed there's no collision, because its resolver calls the installer only in project mode.

SOTA sources

  • The skills 1.7.0 CLI as installed (dist/cli.mjs, sha256 fde68534…):
    • L1396-1399: codexHome and claudeHome, with CLAUDE_CONFIG_DIR?.trim();
    • L1511: the claude-code globalSkillsDir;
    • L2208-2210: getCanonicalSkillsDir;
    • L3746-3750: getSkillLockPath, which uses any truthy XDG_STATE_HOME, untrimmed, through path.join.
  • The same code upstream: vercel-labs/skills@7407f389 src/skill-lock.ts L67-72 and src/installer.ts L128-131.
  • Claude Code's CLAUDE_CONFIG_DIR behaviour: the settings and env-vars pages at code.claude.com, read 2026-09-28, and a review of the installed 2.1.284 bundle for the untrimmed, empty-counts and NFC details.
  • Codex CODEX_HOME: openai/codex rust-v0.157.1 (@36650394) codex-rs/utils/home-dir/src/lib.rs L13-51, and the Codex config-advanced docs page.
  • Precedent: install_skills: read back a global rollback like #429's project path; M4 host removal receipt #467's claude_skills_dir, and the JS trim set that node --version v24.21.0 measured.

Evidence-class table

Evidence Class Result
Unit and integration tests (fake CLI) our-integration tests.test_install_skills tests.test_skills_status tests.test_skill_usage: 219 OK, 0 skipped.
Failing first our-integration Against the pre-repair code, the round's 9 new tests all fail or error (18 failures and 1 error, counting subtests). None of the 210 older tests newly failed. The first round's tests also failed first against f0219263.
Node parity upstream-unchanged runtime A verifier compared node path.join with Python for 6 adversarial inputs: 0 mismatches. Both copies of JS_TRIM_CHARS equal node's trim set of 25 code points.
Registry our-integration validate.py passes with 165 receipts; component_matrix.py --check and new_host_grand_list.py --check both pass; the three pre-push registry tests pass.

Review loop

  • Round 1: two Claude reviewers (a verifier and an evidence-reviewer) and a GPT-6 cross-family review (codex exec -s read-only -m gpt-6-astra, effort max). GPT-6 said MERGE-AFTER-FIXES with 3 majors and 1 minor, and the Claude reviewers independently agreed on the same items.
  • One repair round (4caf5611) closed all of them, plus the Claude nits and the same-contract skill_usage.py gap.
  • Delta checks on the repaired head:
    • The GPT-6 re-check found F1-F3 FIXED, each with a regression test that fails when reverted, and no new defects. F4 was partial: "set" should read "non-empty". That is fixed in 17c5aee1.
    • The Claude verifier confirmed 9 of 9 claims.

Residuals (recorded, not fixed here)

  • An empty-string HOME: node's homedir() returns "", so the CLI's canonical folder becomes relative to its working folder, while Python's Path.home() gives /. The --home default in both scripts is affected. This is low severity and pathological.
  • A CLAUDE_CONFIG_DIR set only in a settings file's env block is invisible to the checker.
  • With CLAUDE_CODE_SUBPROCESS_ENV_SCRUB on, a checker run from inside Claude Code reads the default location.
  • The untrimmed, empty-counts and NFC settings rules are mirrored from the 2.1.284 bundle; no live run observed them.
  • cowork_settings.json isn't read.
  • A relative --home in project mode is untested (this predates the PR).
  • The report doesn't say which location it read.
  • The changed checker was not run against this host's real configuration. All evidence is fixtures plus source review.

Local commands run

  • python3 -m unittest tests.test_install_skills tests.test_skills_status tests.test_skill_usage: exit 0, Ran 219 tests … OK.
  • python3 scripts/validate.py: exit 0, "receipts": 165, "status": "passed".

Decision record

No new decision; this closes the parity gap the #467 addendum names. The erratum records the behaviour change for the dated tree_drift_check.py re-runs.

Host evidence

None. Tests and source review only.

Checklist

  • One review, one repair round and one delta check. Main was merged in, and registration is current.

🤖 Generated with Claude Code

Scout and others added 6 commits September 28, 2026 20:16
…path.join does

The pinned skills 1.7.0 CLI builds the global lock path and the canonical
skill folder with Node's path.join, which collapses "..": getSkillLockPath
(vercel-labs/skills@7407f389 src/skill-lock.ts:67-72, npm dist/cli.mjs
L3746-3750) and getCanonicalSkillsDir (src/installer.ts:128-131,
dist/cli.mjs L2208-2210). os.homedir() returns HOME verbatim, so only that
join removes a ".." from --home. pathlib keeps it. With a ".." through a
missing folder in --home or XDG_STATE_HOME, a canonical folder or lock
entry that the rollback's remove kept read as removed ('rolled-back'),
and a matching add read as unverified and was rolled back.

- tools/adoption/install_skills.py: one node_path_join helper, the #467
  claude_skills_dir rule (normpath of the non-empty parts joined with /,
  a leading // collapsed to /), now builds both lock_file_path branches,
  canonical_skill_dir's global branch and claude_skills_dir. Project
  paths are unchanged. Lines 1-481 keep the numbers the #467 addendum
  cites.
- scripts/skills_status.py: resolve_lock_path applies the same join. Its
  copy of the helper sits after main(), so cited lines keep their numbers,
  and stays local because tree_drift_check.py executes this file from its
  own bytes and records their sha256.
- tests: the fake CLI joins its global paths the same way. New tests cover
  ".." in --home and XDG_STATE_HOME (rollback read-back 'error', a
  'rolled-back' control, a verified install), the unchanged project
  branches, and the helper against node's own path.join. Against
  f021926's scripts they fail: 6 failures and 1 error in
  test_install_skills, 1 failure in test_skills_status; the control and
  every earlier test pass there.
- evidence/artifacts/skills-listing-restore-20260928/README.md: dated
  erratum naming resolve_lock_path and load_lock (tree_drift_check.py
  L284-285) and what a re-run now matches. The script and its outputs
  are unchanged.
- catalogs/foundation/manifest.json: the sandbox gate cites
  docs/secret-storage.md line 30 and "Follow-ups not in this change"
  lines 1221-1225 (were line 29 and 1171-1175).

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Hot-file protocol (docs/lanes.md): re-registers the six files changed in
the previous commit with scripts/host_receipts.py register_file. No new
receipt. component_matrix.py --check and new_host_grand_list.py --check
exit 0, so neither output is rewritten; scripts/validate.py exits 0.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…uilds it (repair round)

- install_skills.py: compare --project-dir with --home joined as the CLI joins HOME
  (path.join), then resolved; a '..' after a symlink no longer passes containment.
- skills_status.py: the canonical and claude-code link folders are joined as the
  skills 1.7.0 CLI joins them. A set CLAUDE_CONFIG_DIR moves the link folder (JS trim,
  path.join) and settings.json (Claude Code 2.1.284's own rule: untrimmed, NFC,
  path.resolve). A set CODEX_HOME moves config.toml (Codex rust-v0.157.1 canonicalizes
  it; the default ~/.codex is normalized lexically).
- skill_usage.py: any non-empty XDG_STATE_HOME, as the CLI takes it, joined with
  install_skills.py's node_path_join (one copy).
- Tests: fail-first cases for each change; the paths skills_status builds from its
  copies of the join and trim agree with install_skills.py's.
- skills-listing-restore README erratum: the lock read differs from the recorded
  code's only when a '..' follows a missing folder or a symlink.
- Nits: fake-CLI fidelity helper, test-module docstring, "final part" wording.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Re-registers the eight changed files with host_receipts.register_file.
component_matrix.py --check and new_host_grand_list.py --check passed without
--write; scripts/validate.py passed.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…back to HOME; cross-family re-check F4)

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@seathatflowsinourveins seathatflowsinourveins added the lane:foundation Foundation lane: Claude/Codex setup, hosts, memory, RAG, research, workers label Sep 29, 2026
@seathatflowsinourveins
seathatflowsinourveins merged commit b0fb65b into main Sep 29, 2026
25 checks passed
@seathatflowsinourveins
seathatflowsinourveins deleted the claude/skills-path-normalization-20260928 branch September 29, 2026 02:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lane:foundation Foundation lane: Claude/Codex setup, hosts, memory, RAG, research, workers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant