Repository navigation
install_skills: read back a global rollback like #429's project path; M4 host removal receipt - #467
Merged
seathatflowsinourveins merged 3 commits intoSep 28, 2026
Conversation
… M4 host removal receipt The skills 1.7.0 CLI's scoped `remove <name> -g -y -a claude-code codex` exits 0 yet keeps the canonical ~/.agents/skills/<name> folder and its lock entry whenever another detected universal agent resolves to that folder (vercel-labs/skills src/remove.ts at 7407f389; installed dist/cli.mjs L6883-6907). Codex reads that folder (openai/codex codex-rs/ext/skills/src/host_roots.rs L103-108, rust-v0.157.1). The global rollback still reported 'rolled-back' without a read-back. - install_skills.py: the global rollback reads back canonical folder, lock entry and Claude link and reports #429's 'error' with its reason strings; a remove that cannot run returns 'error' instead of raising. Tests on main's fake-CLI fixtures; failing-first 6 of 52 against bdf25d2. - Receipt for the M4 host removal on this host (scoped remove kept canonical + lock; set asserted; unscoped remove completed; profile install read-back; skills_status 28; override drop). - Correction addendum to the M4 host step; one anti-pattern row cross-linked with #429's. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…nverifiable lock (review repair) Repair round for the cross-family review of #467 at 6744c2e (codex exec, gpt-6-astra, effort max: MERGE-AFTER-FIXES) and the independent verifier's coverage note. - claude_skills_dir: the global Claude link is read back where skills 1.7.0 puts it, $CLAUDE_CONFIG_DIR/skills when set and not blank (npm dist/cli.mjs L1398, L1511), else ~/.claude/skills. - lock_retains: only a missing lock or a parsed lock without the entry confirms removal; a malformed or unreadable lock, or any OSError/ValueError during the read-back, is 'error' with "rollback could not be verified" in both modes. - Tests: fake CLI mirrors CLAUDE_CONFIG_DIR, adds lock_after_remove faults and a deleted binary; the module strips a host CLAUDE_CONFIG_DIR. 57 OK; 5 fail against 6744c2e's installer. - Native: m4_claude_config_dir_probe.py (pinned CLI links only under CLAUDE_CONFIG_DIR; a blank value falls back; pre-repair installer false 'error' on an unrelated ~/.claude copy, repaired 'rolled-back'); the unchanged reproduction rerun with the repaired installer matches its first output. - Receipt data.review_repair_round, a limitation, addendum and anti-pattern row updated; addendum nit (skillOverrides, not settings). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ath.join rules Final round after the re-check of bb3c88f (codex exec, gpt-6-astra, effort max: F1 partial) and a second stack-verifier (9/10 confirmed; the same gaps): - JS_TRIM_CHARS: the 25 code points node's String.prototype.trim removed over every code point (str.strip keeps U+FEFF and strips U+001C-U+001F, U+0085); test compares it with node on PATH. - The global Claude folder is normalized as path.join does (os.path.normpath; a leading // collapses). - Fake CLI mirrors both; 59 OK; against bb3c88f's installer 3 subtests fail and 1 errors. - Probe arms for a '..' value and U+FEFF alone, and node's trim set and version; probe and the unchanged reproduction rerun with the final installer; receipt block, limitation and addendum (line references recomputed: L17-33, L125-136, L449-451, L452-478) updated. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
seathatflowsinourveins
deleted the
claude/m4-host-removal-global-rollback-20260928
branch
September 28, 2026 21:45
This was referenced Sep 28, 2026
Open
Grand dashboard: integrity-lane rows after #476 (actionlint M2, CodeQL M4, skills-trial window)
#478
Merged
seathatflowsinourveins
added a commit
that referenced
this pull request
Sep 29, 2026
…n global paths as skills 1.7.0 does (#482) * install_skills, skills_status: join global skills paths as the CLI's 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) <noreply@anthropic.com> * Register the path-join change's files in manifests/evidence.json 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) <noreply@anthropic.com> * Read each global skills path as the program that writes or reads it builds 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) <noreply@anthropic.com> * Register the repair round's files in manifests/evidence.json 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) <noreply@anthropic.com> * Erratum: 'non-empty' XDG_STATE_HOME, not 'set' (an empty value falls back to HOME; cross-family re-check F4) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Scout <scout@local> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
What
Follow-up to #464 (M4) on #429's convention. On this host, the M4 removal of the trial skill
verification-before-completionexposed a gap. The scoped native remove,skills remove <name> -g -y -a claude-code codex, exits 0, yet it leaves the canonical~/.agents/skills/<name>folder and its lock entry in place whenever another detected universal agent resolves to that folder. Codex keeps reading the folder, so the removal is only partial.#429 already reads back the project rollback. The global rollback still reported
rolled-backwithout checking.tools/adoption/install_skills.py:errorstate with Runtime-worker skills program: project-scoped installs and a 137-skill manifest #429's reason strings ("rollback retained, in use by another agent" / "rollback incomplete");errorinstead of raising;tests/test_install_skills.py: the new cases run on main's fake-CLIretain_after_removefixtures. Failing-first against bdf25d2: 6 of 52 fail.evidence/receipts/skills-m4-host-removal-20260928.json, with artifacts: the scoped-remove reproduction, the host read-back and the redacted override-drop script. It records:skills_statusover 28 skills;skillOverrideskey.docs/harness-defaults.md, cross-linked with Runtime-worker skills program: project-scoped installs and a 137-skill manifest #429's rollback row;manifests/evidence.json.Review repair round (bb3c88f)
The cross-family review at 6744c2e (
codex exec, gpt-6-astra, effort max) returned MERGE-AFTER-FIXES. The independent stack-verifier confirmed all 8 claims. The repair covers every finding:~/.claude. It now resolves it as skills 1.7.0 does:$CLAUDE_CONFIG_DIR/skillswhen that is set and not blank (dist/cli.mjsL1398, L1511).lock_retainsnow reads the lock strictly.OSErrororValueErrorduring the read-back is nowerror, "rollback could not be verified", in both modes.skillOverrides.m4_claude_config_dir_probe.py: the pinned CLI links only underCLAUDE_CONFIG_DIR. With an unrelated~/.claudecopy present, the pre-repair installer reported a falseerror; the repaired one reportsrolled-back.Final round (after the re-check at bb3c88f)
The GPT-6 re-check found the lock, error and nit findings fixed and the
CLAUDE_CONFIG_DIRfinding partial. A second stack-verifier confirmed 9 of 10 claims and found the same gaps:str.strip()differs from JStrim(): it keeps U+FEFF and strips U+001C-U+001F and U+0085.pathlibkeeps.., which Nodepath.joincollapses.The fix:
JS_TRIM_CHARSholds the 25 code points node'strim()removed over every code point. A test compares it with node when node is on PATH.path.joindoes.…/missing/../xvalue links underxand never createsmissing. A U+FEFF-only value falls back to~/.claude.SOTA sources
src/remove.ts:isStillUsedkeeps the canonical folder and the lock entry while another detected agent's path is canonical. Installed 1.7.0dist/cli.mjsL6853-6907;getAgentBaseDirL2214;isUniversalAgentL2180.dist/cli.mjsL1398 (CLAUDE_CONFIG_DIR?.trim()) and L1511 (join(claudeHome, "skills")); ECMA-262String.prototype.trim(WhiteSpace and LineTerminator), measured with node v24.21.0.codex-rs/ext/skills/src/host_roots.rsL103-108: Codex reads~/.agents/skills.Evidence classes
tests/test_install_skills.py: 59 OK (final-round tests fail against bb3c88f's installer; 5 repair-round tests fail against 6744c2e's; 6 of the original 52 failed against bdf25d2)python3 scripts/validate.py: passed, 165 receiptsCLAUDE_CONFIG_DIRprobeThe project-mode native reproduction was not run. The malformed-lock, unreadable-lock and missing-binary cases are fake-CLI fault injections only; the receipt records both limits.
🤖 Generated with Claude Code