Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,15 @@ Real workspaces mix forms (a record library whose records are mini knowledge bun
- **Contract** — describes how a step works (becomes a `CONTEXT.md`)
- **Factory** — stable reference (→ `_shared/`, `_system/`, or `references/`)
- **Product** — run-specific artifacts (→ stage `output/` or record folders)
- **Dead** — stale, duplicated, or superseded (→ propose `_archive/`, never silently delete)
- **Dead** — stale, duplicated, or superseded (→ propose `_archive/`, never silently delete). *A file is Dead only after step 4 confirms nothing depends on it — apparent disuse is not proof.*

**4. Propose before moving.** Present the target tree and a migration map (old path → new pathrole). Get approval. This is a human gate in a method built on human gates — honor it.
**4. Verify reference integrity — before proposing.** Apparent disuse is not proof of safety: a file with no obvious references can still be load-bearing for a live script, a sibling folder, or a system *outside* this workspace. Before any file is proposed for a move — especially a `Dead → _archive/` move — enumerate what actually points at it across four scopes: **in-vault**, **sibling-path** (`../`), **symlink**, and **external/cross-boundary** (other repos or systems that hardcode paths in). This doesn't add a role — it flags a move: any file with a live referrer is **held** (not moved), or moved only if every referrer is updated in the same change. A file can't be classified Dead until this comes back clean. This is impact analysis — it turns the approval gate in step 5 from a guess into an informed decision. See [references/reference-integrity.md](references/reference-integrity.md).

**5. Migrate.** Move files, write the entry file and contracts, de-duplicate toward one-home-per-fact (leave a link where the copy lived if anything might reference it). Separate method from instance: if the structure will be reused elsewhere, the blank template lives apart from this filled-in deployment.
**5. Propose before moving.** Present the target tree and a migration map (old path → new path → role → *referrers found*). Get approval. This is a human gate in a method built on human gates — honor it. The reviewer approves against the reference report from step 4, not against a hunch.

**6. Validate with the walk test.**
**6. Migrate — copy, verify, then remove.** Never move-and-hope. Copy to the new home, verify parity (file count and content hash) against the source, and only then remove the original. Write the entry file and contracts, de-duplicate toward one-home-per-fact (leave a link where the copy lived if anything referenced it). Separate method from instance: if the structure will be reused elsewhere, the blank template lives apart from this filled-in deployment.

**7. Validate with the walk test.**

## The walk test

Expand All @@ -91,6 +93,7 @@ Validate any ICM — new or restructured — by walking it cold, as an agent wit
- Can you state pipeline status purely by scanning what exists in `output/` folders (or node frontmatter)?
- Is any routing file carrying content payload? Move the payload to a shelf; leave a pointer.
- Is any fact stored in two places? Pick one home; link from the other.
- After a restructure: does every reference that existed *before* the move still resolve? A moved file that something still points at is a break, not a tidy-up — no orphaned references, no dangling links, inside the vault or out.
- Token check: entry file + one contract + its inputs should land in roughly 2k–8k tokens.
- System map only: can a cold agent answer *what is X* and *what else moves if I change X* from `map/CLAUDE.md` plus one card? Extra checks are in [references/system-map.md](references/system-map.md).

Expand All @@ -107,4 +110,5 @@ If a step fails, fix the structure — not by explaining more, but by moving or
- [references/core.md](references/core.md) — the five design principles, the five-layer context hierarchy, naming conventions, token discipline. Read when writing contracts or when a structural call is contested.
- [references/forms.md](references/forms.md) — the six forms in depth: skeletons, moves, failure modes. Read at step 2 of Build mode or step 2 of Restructure mode.
- [references/system-map.md](references/system-map.md) — audit pipeline for the System map form. Read when that form is chosen.
- [references/reference-integrity.md](references/reference-integrity.md) — the reference-integrity gate: the four reference scopes, the "presence is not position" principle, and copy-verify-parity-then-remove. Read at step 4 of Restructure mode, or any time a move is contested.
- [assets/templates/](assets/templates/) — copyable starters: `CLAUDE.md`, workspace `CONTEXT.md`, `stage-CONTEXT.md`, `node.md`, `object.md`, `process.md`, `schema.md`, `questionnaire.md`.
65 changes: 65 additions & 0 deletions references/reference-integrity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Reference Integrity — the move-safety gate

Restructure mode's job is to move files without breaking anything. The walk test proves the *result* is navigable. It does **not** prove the *move itself* was safe. This gate fills that hole: before any file is proposed for a move, prove what depends on it. It is [impact analysis](https://en.wikipedia.org/wiki/Change_impact_analysis) applied to a folder — the same discipline a data team applies before altering a shared table.

## The one principle: presence is not position

A file's apparent disuse is not evidence that moving it is safe. The two are unrelated:

- The **oldest, most obviously superseded** file can be the **most referenced** — old outputs get wired into downstream scripts precisely because they were the stable ones.
- A file with **zero references you can see** can still be load-bearing, because you only searched where it was easy to look.

So the gate is not "does this look dead?" It is "**can I enumerate everything that points at this, everywhere it could point from?**" Until you can, the file is not classifiable as Dead — it is unproven.

## The four scopes

A reference can reach a file from four places. A search that covers only the first is the usual cause of a broken restructure.

1. **In-vault** — other files inside the workspace that name this path.
2. **Sibling-path** — relative `../other-folder/` references inside scripts or configs. These break the moment you regroup folders, even though nothing "outside" is involved.
3. **Symlink** — links pointing into or out of the move candidate. A moved target orphans the link; a moved link orphans nothing but disappears.
4. **External / cross-boundary** — the scope the walk test is structurally blind to: **other repositories, deploy scripts, cron jobs, running systems** that hardcode a path into this workspace. These cannot be updated atomically with your move, which makes them the highest-risk class. A workspace that looks self-contained rarely is.

Anything a scope turns up is **Blocked**, not Dead. A Blocked file is held in place (or moved only if every referrer is updated in the same change). Record the referrers on the migration map so the human approves against facts.

## Location durability (a fifth check, once per workspace)

Before trusting a workspace at all, confirm it lives somewhere durable. Outputs written into an **ephemeral or ignored location** — a temp dir, a git worktree, anything under a `.gitignore` — exist only until that location is cleaned up. Verify the workspace root is tracked/backed up before you reorganize *within* it; reorganizing files that were one cleanup away from gone is rearranging deck chairs.

## Migrate safely: copy, verify, then remove

A move is `copy → verify → remove`, never a single `mv` you trust:

1. **Copy** the file or subtree to its new home.
2. **Verify parity** — file count and content hash (or byte-for-byte compare) between source and destination. Zip-based formats (`.pptx`, `.docx`, `.xlsx`) embed metadata, so compare *unzipped content*, not the archive's outer hash.
3. **Remove** the original only after parity passes. Leave a pointer where a copy lived if anything referenced it.

A partial or corrupted copy that you never verified looks exactly like a successful one until someone opens the file.

## Illustrative commands (adapt to your tools)

ICM runs under any agent, so treat these as *shapes of the check*, not required tooling.

```sh
# 1. in-vault references to a move candidate
grep -rIl 'candidate-name' . --exclude-dir='candidate-name'

# 2. sibling-path (../) references among candidates
grep -rnI -e '\.\./[A-Za-z0-9_-]*/' . | grep -i 'candidate-name'

# 3. symlinks into/out of the tree
find . -type l -exec ls -l {} +

# 4. external / cross-boundary referrers (search OTHER repos and configs)
grep -rIl 'workspace-name' ~/other-repos ~/deploy ~/.config 2>/dev/null

# 5. durability: is the workspace root ignored or untracked?
git check-ignore -v . ; git ls-files . | head -1 # empty tracked-list = unbacked

# migrate parity
diff <(cd SRC && find . -type f | sort) <(cd DEST && find . -type f | sort)
```

## The gate, in one line

**Zero visible references is not a green light — it is an unfinished search.** Prove the dependencies, then move; verify the move, then delete.