.md file to compare - side-by-side diff against pod-dispatch
pod-dispatch
description: "Triggers on prompt mention of 'pod-dispatch' or 'commit-discipline'."
What it does for you
Lets several helpers work on the same project without stepping on each other.
What it produces
A recent result, so you can see the kind of work it returns.
loading…
How to get it
These run inside the Snappy workspace. Want this working in your business? I set skills like this up with you, in one focused week.
For developers how this skill is built, graded, and how it runs
at a glance- the short version
what's inside - the parts that make up a skill 2/4 present
A skill is just a few plain-text files. Only the main one is required. The rest are optional, added as the work needs them. This is what the skill is made of; how it runs is just below.
state/skills/pod-dispatch/SKILL.md
present
state/lib/pod-dispatch.ts
not present
state/bin/pod-dispatch/
not present
state/skills/pod-dispatch/AGENTS.md
present
how it's graded - what counts as a good run 4 criteria · 2 deterministic · 2 judge
Each row is one thing a good run has to get right. deterministic means a quick check decides, pass or fail. judge means the AI reads the result and rates it. Grading each piece on its own (instead of one overall score) shows exactly where a run fell short, so the fix is obvious.
how it runs - the shared frame every skill uses 5/5 present
Every skill runs the same way. One part does the work, a separate part checks it, and a short loader hands the AI exactly what it needs for the job. Anything this skill doesn't use shows a one-line note saying why, on purpose, not by accident.
state/log/evals.ndjson - NEVER git add -A, git add ., git add state/, or git commit -a/-am. All four sweep other pods' / parallel subagents' unstaged tracked + new files into your commit. Each has caused a real incident in the 2026-04-27 fan-outs (commit 227b0ef shipped 7 other agents' WIP).
- ALWAYS stage specific paths by name — git add state/skills/x/SKILL.md state/lint/y.ts. Wildcards only when scoped to a single pod-owned subdir (e.g. git add state/bin/<my-only-dir>/).
- ALWAYS prefix commit messages pod-<id>: <scope> — <action> (or <scope>: <action> for standalone work). Imperative verb, no "update"/"fix" alone. Exempt: evolve iter N:, Revert "...", Merge ....
- If another pod's file appears staged, git restore --staged <file> before committing. Run git status after every git add to confirm. If it's already committed, file a P1 friction row in state/log/frictions.ndjson with the offending SHA.
- NEVER bypass the pre-commit hook silently. SNAPPY_POD_DISPATCH_BYPASS=1 is the explicit escape and logs a friction row. No prefix carve-outs (port: / phase-0.5: were dropped in P2-12 / b6d1ff6).
- Use git commit -- <pathspec> to defeat TOCTOU index races. Even with explicit git add paths, parallel agents can pollute the index between your add and commit. Pathspec on commit limits the tree regardless of index state. Recovery from polluted-index commit: git reset HEAD~1, restage, re-commit with pathspec on commit.
- +2 more in AGENTS.md →
what it has learned - fixes written back in over time sample
When a run hits something this skill didn't handle, the fix gets written back into the skill so it doesn't happen again. FIXED means it was corrected on the spot. LOGGED means it's queued for a bigger rewrite. Either way, the skill gets a little better and never makes the same mistake twice.
- Loading feedback rows…
how the work flows- who makes it, who checks it
pod-7: byline — fix debounce-swallow on rapid statusline refresh
what this step does
SKILL.md- the skill, written out in plain English
pod-dispatch - atomic commit discipline
Pods operate on a shared working tree. When Pod A runs git add -A or git add state/ it sweeps every other pod's unstaged edits into its commit. The resulting commit is unrevertable without destroying unrelated work. The evolve harness's keep-or-revert primitive - the ONLY safety the 999-loop has - breaks silently when iteration N commits iteration N-1's orphan edits, and the revert then deletes N-1's work too.
This skill exists so a pod-N commit contains only pod-N's edits, full stop. The lint (state/lint/commit-discipline.ts) and the pre-commit hook enforce this mechanically - pods cannot silently opt out.
The three rules
1. Stage only your own edits
Forbidden:
git add -A # sweeps every other pod's unstaged work
git add state/ # same problem, narrower
git add . # same problem, scoped to cwd
Required:
git add state/skills/my-skill.md state/lint/my-lint.ts
# List the specific paths you wrote. No directories. No wildcards
# unless scoped to a single pod-owned subdir.
If you genuinely edited an entire subdir that only you own (e.g. a new state/bin/<pod-owned-dir>/), git add state/bin/<pod-owned-dir>/ is fine - the directory itself is the scope.
2. Commit message prefix: pod-<id>: <scope> — <action>
Shape:
pod-7: byline — fix debounce-swallow on rapid statusline refresh
Fields:
pod-<id>- the pod number or letter assigned at dispatch (pod-3,
pod-A, pod-27). No pod ID? Use scope-<name> for standalone work (sync-integrity:, evolve:, brain:).
<scope>- the single area of change. One word, ordir/subdir. If you
have two scopes, you have two commits.
<action>- imperative present tense, specific. Not "update" or "fix" -
"fix debounce-swallow", "add commit-discipline lint", "revert iter 4".
The evolve iter N: auto-commits are exempt - they're harness-generated and the iter counter IS the scope. Same for Revert "..." auto-commits from git revert.
3. If another pod's file sneaks in, un-stage it
When you run git status and see a file you didn't touch listed as staged, un-stage it before committing:
git restore --staged state/bin/other-pods-file.ts
If it's already committed, the damage is done - file a friction row in state/log/frictions.ndjson with severity P1 and the offending SHA, so the orphaned pod can recover their work.
Enforcement
Lint
state/lint/commit-discipline.ts scans the last N commits (default 10) and flags any commit where:
- Staged file count > 10 - pod scopes rarely need more than 10 files. A
commit of 40 files is either a port or an accident.
- Top-level dirs touched > 2 - a pod that edits
state/skills/,
state/bin/, state/docs/, AND bin/ in one commit is conflating scopes.
Exempted scopes (whitelisted by commit-message prefix):
evolve iter N:- harness-generated mutation (catalog guards the scope).Revert "..."-git revertoutput.Merge- git merge commits.
Invoke:
npx tsx state/lint/commit-discipline.ts # last 10
npx tsx state/lint/commit-discipline.ts --n=50 # last 50
npx tsx state/lint/commit-discipline.ts --json # machine output
Exits non-zero when any non-exempt commit exceeds the thresholds.
Pre-commit hook
.git/hooks/pre-commit runs on every git commit. It:
- Counts staged files (
git diff --cached --name-only | wc -l). - Derives top-level dirs from staged paths.
- If count > 10 OR dirs > 2, aborts with a pointer to this skill page.
Operator override (emergencies only):
SNAPPY_POD_DISPATCH_BYPASS=1 git commit -m "..."
Every bypass logs a row to state/log/frictions.ndjson so it's visible.
Install (idempotent):
state/bin/pod-dispatch/install-hook.sh
Evolve guard
state/bin/evolve/run.ts checks, before starting the loop:
- HEAD's last commit changes < 20 files.
- HEAD's last commit touches < 3 top-level dirs.
If HEAD is a bundled commit, the harness exits 5 with a pointer here. Rationale: revert-safety is compromised when git revert HEAD would delete unrelated work. The operator must either (a) split HEAD into atomic commits or (b) rebase past the bundled commit before running evolve.
Eval
Shape gate on the lint output:
- Runs lint with
--n=10 --json. - Output MUST be valid JSON with
{ok: bool, violations: [...]}. - Every violation row has
sha,msg,file_count,top_dirs,reason. ok: truewhen violations is empty;ok: falseand exit=1 otherwise.- Actor = the lint script. Auditor = a separate shell read of
git log+
path counts - same logic independently implemented.
Log to state/log/evals.ndjson with skill: "pod-dispatch" and primary_issue set to the first violation's reason (or null on pass).
Known pitfalls
- Untracked files are not staged. The hook only checks `git diff
--cached. If a pod forgets to git add`, the file stays untracked - that's a separate problem (lost work) but not a discipline violation.
- Merge commits and reverts are exempt. A revert can legitimately span
many files; a merge is not pod-authored. Both are whitelisted by the lint.
- No port/phase-0.5 carve-out. The lint used to exempt
port:and
phase-0.5: prefixes for upstream imports; that escape was dropped in P2-12 (commit b6d1ff6). Genuine large imports must be split into scoped commits or pre-approved on a case-by-case basis - there is no prefix bypass.
- Bypassing the hook is fine, silently bypassing is not.
SNAPPY_POD_DISPATCH_BYPASS=1
is the explicit escape and the operator should record the rationale in the commit message; the PID loop surfaces non-conforming commits in the next dashboard refresh.
Self-improvement
When a bundled commit slips through anyway, append a line to the feedback log:
echo "[$(date -u +%FT%TZ)] pod-dispatch: <sha> bundled <scope-a> + <scope-b>" \
>> state/log/loader-feedback.log
Then file a friction, and propose a tighter threshold (lower file count, lower dir count, or a new whitelist) in the next regen brief.
Rubric
criteria:
- name: lint_passes_for_last_n_commits
kind: deterministic
check: "Executing `npx tsx state/lint/commit-discipline.ts --n=10 --json` returns JSON with `ok: true`, indicating no violations within the last 10 commits."
- name: commit_message_format
kind: judge
check: "The most recent commit message adheres to the pattern `pod-<id>: <scope> — <action>` (e.g., `pod-7: byline — fix debounce-swallow`)."
- name: staged_file_specificity
kind: judge
check: "An auditor using `git show --name-only <commit-sha>` can confirm that the last commit adds/modifies specific file paths, not broad directories like `state/` or `.`."
- name: evolve_guard_condition
kind: deterministic
check: "The `eval` field of the skill's `state/log/evals.ndjson` entry (for a `pod-dispatch` eval) confirms that HEAD's last commit changed fewer than 20 files and touched fewer than 3 top-level directories, or an appropriate exemption for `evolve iter N:` exists if `eval` is `false`."AGENTS.md- what the AI loads when this skill comes up
pod-dispatch - loader
Per-turn rules. Full reference: state/skills/pod-dispatch/SKILL.md. Do not skip these.
Critical Rules
- NEVER
git add -A,git add .,git add state/, orgit commit -a/-am. All four sweep other pods' / parallel subagents' unstaged tracked + new files into your commit. Each has caused a real incident in the 2026-04-27 fan-outs (commit227b0efshipped 7 other agents' WIP). - ALWAYS stage specific paths by name -
git add state/skills/x/SKILL.md state/lint/y.ts. Wildcards only when scoped to a single pod-owned subdir (e.g.git add state/bin/<my-only-dir>/). - ALWAYS prefix commit messages
pod-<id>: <scope> — <action>(or<scope>: <action>for standalone work). Imperative verb, no "update"/"fix" alone. Exempt:evolve iter N:,Revert "...",Merge .... - If another pod's file appears staged,
git restore --staged <file>before committing. Rungit statusafter everygit addto confirm. If it's already committed, file a P1 friction row instate/log/frictions.ndjsonwith the offending SHA. - NEVER bypass the pre-commit hook silently.
SNAPPY_POD_DISPATCH_BYPASS=1is the explicit escape and logs a friction row. No prefix carve-outs (port:/phase-0.5:were dropped in P2-12 /b6d1ff6). - Use
git commit -- <pathspec>to defeat TOCTOU index races. Even with explicitgit addpaths, parallel agents can pollute the index between your add and commit. Pathspec oncommitlimits the tree regardless of index state. Recovery from polluted-index commit:git reset HEAD~1, restage, re-commit with pathspec on commit. - Stash-pop after
git pull --rebasecan SILENTLY revert your work. Conflict resolution drops files back to baseline with no error. After every rebase:wc -l <your-files>orgit diff <ref-before-pull> -- <your-files>. Recovery:git checkout stash@{0} -- <your-files>(checkgit stash listforstash@{1}if you stashed twice). - Auto-regen clobber window - be aware of headless dispatch overlap. The Stop hook (
state/hooks/snappy-os-auto-regen.sh) spawns a headlessclaude -pwhose global commit-protocol can rewrite commit messages or stage unrelated files during attended-subagent windows. Now gated by a dirty-worktree check (excludingstate/log/*), but if you see a commit message swap on commits you authored, suspect the auto-regen overlap and checkstate/log/auto-regen.log.
When to invoke the lint
Run npx tsx state/lint/commit-discipline.ts --n=10 at these moments:
- Pre-commit self-check - before
git push, verify your last N commits pass. - Parallel-batch verification - after a fan-out wave lands, scan the last 20 commits to catch any sweep.
- Evolve preflight -
state/bin/evolve/run.tsalready gates HEAD; manual lint surfaces older bundled commits in the recent window. - Recovery widen - after a friction row about a bundled commit, run with
--n=50to find adjacent damage. - Auto-shape eval (background) - the eval-row-mandatory drain runs lint with
--jsonand writes pass/fail tostate/log/evals.ndjson.
Commands
| ui dashboard | state/skills/pod-dispatch/resources/ui.openui |
| step | command |
|---|---|
| invoke (last 10) | npx tsx state/lint/commit-discipline.ts --n=10 |
| invoke (last 50) | npx tsx state/lint/commit-discipline.ts --n=50 |
| invoke (json) | npx tsx state/lint/commit-discipline.ts --n=10 --json |
| install hook | state/bin/pod-dispatch/install-hook.sh |
| bypass (rare) | SNAPPY_POD_DISPATCH_BYPASS=1 git commit -m "..." |
| race-free commit | git commit -m "msg" -- path/a path/b |
| eval log | state/log/evals.ndjson (skill: "pod-dispatch") |
OpenUI Resource
- Skill-owned OpenUI Lang resource:
state/skills/pod-dispatch/resources/ui.openui. Read it before rendering or editing this skill's generated component surface. - Treat this resource as a first-class artifact of the skill, not a generic chat response. Improve it when the skill's user-facing output needs to become richer.
- System resources compose OpenUI primitives and inherit SnappyChat tokens. Use
ui_contract: brandedin SKILL.md only for deliberate platform or client visuals.
Known Pitfalls
- Bundled commit sweeps someone else's in-flight work, then a revert deletes it too (Pod 27 / Pod 28 recovery pattern).
- Evolve harness's keep-or-revert primitive silently breaks when HEAD is bundled.
git commit -amimplicitly-a's unstaged tracked files - same failure mode asgit add -A.git stash push -u(without pathspec) sweeps every parallel agent's untracked WIP into one stash. Alwaysgit stash push -- <your-paths>.- Stash-pop on rebase conflict can silently revert files. Detection: post-rebase
wc -l/git diffagainst pre-rebase ref. - TOCTOU race on shared index: another agent's
git addbetween your add and commit pollutes your tree. Use pathspec oncommit. - Auto-regen headless
claude -pmay rewrite commit messages during overlap. Verify your message ongit log -1after push.
Self-Test
- [ ] Did I list specific paths to
git add, never a directory or-A? - [ ] Does my commit message start with
pod-<id>:or a concrete<scope>:? - [ ] After staging, did I
git statusto confirm no other pod's file is in? - [ ] File count ≤ 10 and top-level dirs ≤ 2?
- [ ] Did I use
git commit -- <pathspec>(or verify the index is clean) to defeat TOCTOU index races? - [ ] After any
git pull --rebase, did I verify my files survived the auto-stash-pop withwc -lorgit diff?
Self-report
If this loader fell short, append a line:
echo "[$(date -u +%FT%TZ)] pod-dispatch: <what was missing>" >> state/log/loader-feedback.log
<!-- kernel-ok: historical attribution for the PID-loader pattern. -->
Self-correcting loader (PID feedback)
This is the rule that makes loaders learn. Ported from snappy-kernel, where it demonstrably worked: the snappy-dom-cartographer skill mapped Skool admin UI once, every later ship-agent inherited the full map for free.
Before you finish, do two things:
1. Fix gaps (P - proportional). MANDATORY. If this loader didn't cover your case - if you had to read another file, run an undocumented command, work around a wrong selector, or discover a quirk - you MUST attempt an Edit to this AGENTS.md before you log.
- Default action: edit this file. Surgical. Add the missing line, table
row, or code example where it belongs. No restructuring.
- Only
LOGGEDis allowed when: the fix needs >10 lines, spans multiple
files, or requires a structural rewrite. In that case the state/regen/drain.sh queue picks it up asynchronously.
- "I didn't have time" / "it's minor" / "the next agent will figure it out"
are NOT valid reasons. Minor gaps compound - that's the whole point of this loop.
- Concrete example of a valid P-fix: discover
agent-browser screenshot
takes path positionally not as --output <path>. One line in a table. Edit it in. Do not just log it.
- The goal: the next agent never has to leave the loader.
2. Log the result.
echo "[$(date -u +%FT%TZ)] pod-dispatch: <what was missing or fixed> [FIXED|LOGGED]" >> state/log/loader-feedback.log
FIXED= you patched this loader inline (P-fix).LOGGED= too large for inline; the PostToolUse enqueue + Stop-hook drain
will rewrite the loader from scratch on next session-end.
Do not skip this. Every agent run must leave the system better than it found it. The loader is the setpoint; you are the sensor; the gap is the error signal; closing the gap is the correction.
api.ts- the code it can call
⚠ no api.ts - this skill has no typed action surface
scripts- helper scripts it can run
prose-only skill - 9 inline code blocks live in SKILL.md above (no state/bin/ sidecar yet).
how we check it- the checks, plus the last 10 runs
| timestamp | verb | score | primary_issue | artifact |
|---|---|---|---|---|
| 2026-04-27 05:53Z | - | 1.00 | - | - |
| 2026-04-25 04:11Z | - | 1.00 | - | - |
| 2026-04-21 15:58Z | - | 1.00 | - | - |
| 2026-04-21 15:56Z | - | 1.00 | - | - |
| 2026-04-21 03:53Z | - | 1.00 | - | - |
| 2026-04-27 05:53Z | - | 1.00 | - | - |
| 2026-04-25 04:11Z | - | 1.00 | - | - |
| 2026-04-21 15:58Z | - | 1.00 | - | - |
| 2026-04-21 15:56Z | - | 1.00 | - | - |
| 2026-04-21 03:53Z | - | 1.00 | - | - |