Repository navigation
v2.8.4 - an approved fix can no longer be written through a planted link
An approved fix can no longer be written through a planted link.
Security
- Applying an approved fix no longer writes through a planted link. When you approve fixes at the final consent step (GATE 3), the board used to name each target by its path in the digest and then write to it. If that path was, or passed through, a symlink or junction planted in a cloned repository, the write landed on the link's target, which could be a file outside the project. The skill now runs a shipped checker,
skills/coalboard/scripts/apply-target.mjs, on every apply target before the digest and again immediately before each live write. It refuses a target when a link sits at or below the project root (a link above the root is your own layout and is allowed), when the target's real path leaves the root, or when the path cannot be resolved (fail closed). It walks an absolute target's..steps against the real parent before it judges the target, so<root>/ln/../x.jsis judged by where the link really points. A refused target is never written: the digest and the report name it with its real path as not applicable, so "apply all" never covers it, and you can apply that fix by hand. The checker writes nothing and reads only path metadata. — test:scripts/lib/apply-target.test.mjs - Be exact about what is enforced. That the agent runs the checker is an instruction in
SKILL.mdthe agent follows, so it is a mitigation and not a guarantee. Once the checker runs its verdict is exact, because it is code. One residue remains: a window between the last check and the write, which a local process that plants a link in that gap could use; the check does not stop it. If the checker cannot run (no shell, no Node), the skill writes no live file and hands you the fixes instead.scripts/lib/conductor-links.test.mjspins that the instruction is present, not that the agent obeys it.
Fixed
- The memory cleanup says what to do when
rmdirrefuses. After removing the files the run created, by name, the skill removesmemory/with a non-recursivermdir; ifrmdirrefuses, it leaves the directory and says so (neverrm -r, never a trailing-slash or*remove). — test:scripts/lib/conductor-links.test.mjs - The hook tests no longer read your real environment. The test sandbox now points
TEMP,TMPandTMPDIRat its throwaway folder and clearsCLAUDE_PROJECT_DIR,CLAUDE_PLUGIN_ROOTandCLAUDE_PLUGIN_DATA, so a value inherited from a real session can no longer reach a test. Not shipped in the plugin.
Notes
- The
skills/coalboard/SKILL.mdbody is now 49,796 characters (49,085 in 2.8.3), against the last declared bound of 45,959 ([2.3.1]). The growth is the apply-target rule, a rail, not explanation; the body was already past the declared bound before this release, and a re-carve is open.