| name | maintain-filemap |
| description | Use whenever the directory shape of a Lossless pseudomonorepo (or any child repo) changes — a new top-level directory is added, a submodule is mounted or unmounted, a major subsystem is renamed — or on a weekly cadence, or before any release that would land on GitHub, to regenerate the `FILEMAP.md` at each affected repo's root so collaborators see the current shape without cloning. Triggers when the user mentions "filemap", "tree", "directory layout", "repo overview", "what does this repo even contain", "new collaborator joining"; also when the agent itself proposes adding/removing a top-level dir or a submodule, because that's exactly the moment the discipline matters.
|
maintain-filemap · Loop
When the directory shape changes, regenerate the map. The committed FILEMAP.md at each repo root is the artifact a new collaborator opens first.
What this loop does
Keeps a FILEMAP.md at the root of each Lossless repo current with the actual on-disk tree. Each FILEMAP.md has two parts:
- A curator preface — hand-authored prose explaining what each top-level directory IS (purpose, ownership, conventions). Edited rarely (only when the meaning of a directory changes, not when its contents do).
- A generated tree — produced by
tree -L 3 with a curated ignore set, spliced between <!-- TREE-START --> and <!-- TREE-END --> sentinels in a fenced code block. Regenerated by the loop's script every time the discipline fires.
Why both: a raw tree dump is useful but doesn't tell a newcomer what they're looking at. The curator preface is what makes the file legible; the generated tree is what makes it accurate.
When this loop fires
Three triggers:
| Trigger | Cadence | How it fires |
|---|
| Directory-shape change | as-it-happens | Pre-commit hook, OR manually as part of the commit that changes shape |
| Weekly cadence | every Monday | Manual or cron; produces a no-op commit if nothing changed |
| Pre-release | before each main/master ship | Manual; bundled into the release commit |
The hook is optional but recommended. Without it, the discipline lives in the agent's working memory: "Did I just add corpus/? → regen FILEMAP."
What changes is a "directory-shape change"
Triggers the loop:
- A new top-level directory was added (
mkdir context-v/loops/)
- A submodule was mounted or unmounted (
.gitmodules changed)
- A major subsystem was renamed (
apps/dididecks-shell/ → apps/deck-shell/)
- A top-level file like
CLAUDE.md or pnpm-workspace.yaml was added
- A new client-site landed under
client-sites/
Does NOT trigger the loop:
- A new file under an existing directory (e.g., adding
context-v/plans/Some-Plan.md)
- A small refactor that doesn't change directory names
- A typo fix, dependency bump, or doc edit
- Adding a new variant under an existing client-site's
src/pages/scroll/{deck}/
Rule of thumb: if the change makes the FILEMAP's depth-3 view different, run the loop.
The recipe
bash context-v/loops/maintain-filemap/scripts/regen-filemap.sh
The script:
cd to the repo root (via git rev-parse --show-toplevel)
- Runs
tree -L 3 -I '<curated-ignore-pattern>' --noreport --dirsfirst
- Reads the current
FILEMAP.md
- Splices the new tree between
<!-- TREE-START --> and <!-- TREE-END --> markers, preserving everything else
- Writes back to
FILEMAP.md
- Reports git diff status; if changed, suggests
git add FILEMAP.md for the next commit
The ignore pattern is the load-bearing knob — see scripts/regen-filemap.sh for the canonical set (node_modules, .git, .astro, dist, .vercel, .output, cache, *.lock, .DS_Store, public). Edit only when a new "noise" directory consistently appears across repos.
The artifact
A FILEMAP.md at every repo root that participates. Per the pseudomonorepos discipline, every level of the tree has its own:
| Repo level | FILEMAP carries |
|---|
Parent pseudomonorepo (dididecks-ai/) | Tree of apps/, client-sites/ (submodule mount points + one level deep), context-v/, changelog/, corpus/, splash/, data/ if present |
Client-site (client-sites/<client>/) | Tree of the client's src/, data/, db/, corpus/, context-v/, public/ |
| Shell submodule etc. | Each carries its own |
The PARENT's FILEMAP.md does NOT try to deeply enumerate submodule contents. It stops at the submodule mount + the submodule's own top-level dirs (depth 3 from parent ≈ depth 1 within submodule). For deeper detail, the reader follows the submodule's own FILEMAP.md.
Detection — how to tell the loop is overdue
Two signals:
- Run the script. If
git diff FILEMAP.md is non-empty after running, the committed map is stale. Trivial to catch.
- Eyeball test. If you
ls the repo root and see a directory that's not in FILEMAP.md, the loop is overdue.
A future enhancement: a CI check that runs the script and fails the build if git diff --quiet FILEMAP.md would fail. Today it's local-discipline; promote to CI when a collaborator misses the discipline twice.
Composition with other skills
| Companion skill | When it fires alongside this loop |
|---|
git-conventions | Always — the FILEMAP regen commit follows the standard chore(filemap): regenerate after <change> header pattern |
changelog-conventions | Usually no — a filemap regen alone doesn't warrant a changelog entry; the underlying change (new submodule, etc.) might |
pseudomonorepos | When the change touches submodule mounts — the pseudomonorepos branch-alignment + relocation rules govern, and the FILEMAP regen is one part of the cleanup |
context-vigilance | When the change is to context-v/ itself — the loop regenerates the map; context-vigilance governs the contents of the map |
Anti-patterns
- Don't auto-commit FILEMAP.md from a hook. The regen should stage the file but let the human approve. Auto-commits churn git history with no-op commits when the tree didn't actually change.
- Don't autogenerate the curator preface. The preface is what makes the file legible; an LLM-generated "this directory contains files" preface is worse than no preface at all.
- Don't try to render submodule contents deeply in the parent. Submodules carry their own FILEMAP. Parent stops at depth 3 and links into children.
- Don't ignore the ignore set. Generated
dist/ directories, node_modules/, and .lock files in the tree are noise that makes the map unreadable. The curated ignore pattern is load-bearing.
See also