Landing blocker for #61 and #63: the deployment checkout is 12 commits behind and `merge --ff-only` refuses while tracked paths are dirty. Discard is not available here (workspace policy: no `checkout`/`stash` on shared state), so the dirt is committed. - `agent/APPEND_SYSTEM.md`: the point-of-use / one-work-log / PR-link doctrine, already byte-identical to `origin/main` (`cmp` against the trunk blob: no difference). No new prose — the commit exists so the trunk merge can proceed. - `agent/config.yml` and `agent/managed-skills/**`: the machine-live tier the heartbeat owns (AGENTS.md § Live-sync tiers). `ALLOW_SECRETS=1` was used, deliberately and after auditing the staged diff by hand: the only credential-shaped strings in it are two copies of `AKIA0000000000000EXAMPLE` — the inert all-zero AWS example id — and they appear inside the two skill pages that teach that exact placeholder shape. This checkout is still running the pre-#61 hook; the merged gate (value-scoped placeholder filter, `71601f7`) exempts this value, so the refusal dies with this landing. No `--no-verify` was used: the gate ran and its verdict is recorded here. Refs #61
4.0 KiB
name, description
| name | description |
|---|---|
| dotfiles-deployment-truth-audit | Answer "is my X config actually tracked and deployed?" per package: classify every file by readlink, expose tracked-then-ignored debt, and re-derive census numbers from the command printed on the page. |
Answer to "does this repo still track my settings?" must be a measurement, never a remembered count. The tracked unit is the file, not the directory: a live directory can be a real directory and still be fully tracked, because every file inside it is a symlink into the repo.
Run in the deployment checkout (the checkout IS the deployment).
1. Tracked set, per package, both tiers
cd ~/.omp # or the repo that owns dotfiles/
git ls-files dotfiles/<pkg> # base tier
git ls-files dotfiles/zz-$(hostname) | grep <pkg> # host override tier — counted separately
The zz-* tier overrides base files by the same relative path, so a per-package count
that ignores it under-reports what a machine actually runs.
2. Live wiring — classify every tracked file (never by directory)
for f in $(git ls-files dotfiles/<pkg>); do
rel=${f#dotfiles/<pkg>/}; live="$HOME/$rel"
if [ -L "$live" ]; then printf 'link %-50s -> %s\n' "$rel" "$(readlink "$live")"
elif [ -e "$live" ]; then printf 'REAL %-50s (NOT a link)\n' "$rel"
else printf 'absent %s\n' "$rel"; fi
done
REAL= the repo copy is a fiction: live state diverged, deployment never reached it.absent= tracked relic, nothing consumes it (candidate forgit rm --cached).- Spaces in filenames break the
forloop (palettes/Gruber Red.jsonsplits into two rows). Usegit ls-files -z | tr '\0' '\n'+while read -rwhen names can hold spaces. - Reverse direction finds untracked-but-load-bearing files:
find ~/.config/<pkg> -maxdepth 2 \( -type f -o -type l \) | while read -r p; do case "$(realpath "$p")" in $PWD/dotfiles/*) ;; *) echo "not from repo: $p";; esac; done
3. Live state that must stay untracked
Generated palette output and app state are expansion, not authorship. Distinguish by
mtime cluster, not by name: find ~/.local/state/<app> -type f -printf '%TY-%Tm-%Td %p\n' —
a same-second mass write is a generator; single later re-stamps are re-runs. Pointers a
switcher script writes (e.g. cfg/display.kdl -> desk-1-home.kdl) are machine state too.
Then check the hazard this creates: grep the entrypoint for includes of those generated
files. A non-optional include of a correctly-untracked generated file bricks a fresh
box (include "noctalia.kdl" with no optional=true = niri cannot start until the theme
pipeline has run once). Report it as a fresh-box failure, not a style note.
4. Tracked-then-ignored debt (invisible to every normal check)
git ls-files dotfiles | grep AGENTTRASH # trash committed inside the tree
git check-ignore --no-index -v <that path> # does an ignore rule match it?
.gitignore patterns without an interior slash (.AGENTTRASH/) match at any depth, so
the rule was fine all along — the file simply entered history before the rule existed, and
an ignore rule never reaches an already-tracked path. Only repair: git rm --cached <path>
plus moving the working copy to the root .AGENTTRASH/ (never rm). git check-ignore
without --no-index prints nothing for tracked paths and reads as "not ignored" — that
false negative is the trap.
5. A census number is only valid with its command
If a page prints a classifier command, every number on it must be reproducible by running that command. A row that the command does not reproduce was written from memory — wrong, not merely stale. Fix the row, and state the correction in the commit message rather than silently editing the number.
Verification before landing
bats tests/, scripts/kb-lint.sh omp-docs, scripts/kb-coverage.py omp-docs, and
scripts/deploy.sh --check from the worktree — --check is read-only; never run the
real deploy from a worktree, it repoints live symlinks into the worktree the heartbeat reaps.