OR Key
drop another .md file to compare - side-by-side diff against pod-dispatch

pod-dispatch

Lets several helpers work on the same project without stepping on each other.
description: "Triggers on prompt mention of 'pod-dispatch' or 'commit-discipline'."
personal 2 files 10 recent evals

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.

Work with me
For developers how this skill is built, graded, and how it runs

at a glance- the short version

actorLint script
auditorA separate shell
eval modeauto-shape (commit-discipline lint — staged files ≤ 10 AND top-level dirs ≤ 2)
categoryOps
stages3

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.

The skill
state/skills/pod-dispatch/SKILL.md present
the skill itself, in plain text
The main file. It says what the skill is and lays out the steps in plain English.
Code
state/lib/pod-dispatch.ts not present
code the skill can run
Optional. Many skills are just words and need no code at all.
Scripts
state/bin/pod-dispatch/ not present
helper scripts
Optional. Added when a skill has a few commands to run.
Loader
state/skills/pod-dispatch/AGENTS.md present
what the AI loads on the fly
Loaded automatically the moment this skill is needed. Kept short on purpose.

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.

name
kind
check
lint_passes_for_last_n_commits
deterministic
Executing `npx tsx state/lint/commit-discipline.ts --n=10 --json` returns JSON with `ok: true`, indicating no violations within the last 10 commits.
commit_message_format
judge
The most recent commit message adheres to the pattern `pod-<id>: <scope> — <action>` (e.g., `pod-7: byline — fix debounce-swallow`).
staged_file_specificity
judge
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 `.`.
evolve_guard_condition
deterministic
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`.

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.

makes the work The worker
present
Lint script the worker
Does the actual work. Whatever it produces is what gets checked next.
checks the work The reviewer
present
A separate shell the checker
A separate checker grades the work, so the part that made it can't approve its own work.
frame
learns Self-correction
present
fixes itself learns from gaps
When a run hits a gap, the skill gets edited on the spot [FIXED] or queued for a bigger rewrite [LOGGED], so it keeps getting better.
tidies up Background fixes
present
queued for rewrite runs in the background
Bigger fixes that can't be made on the spot get queued and rewritten in the background later.
remembers Run history
present
state/log/evals.ndjson auto-shape runs
Every run is written down here, so the next time this skill is used it already knows how the last runs went.
Critical rules the things this skill must not get wrong
  1. 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).
  2. 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>/).
  3. 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 ....
  4. 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.
  5. 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).
  6. 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.
  7. +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.

  1. Loading feedback rows…

how the work flows- who makes it, who checks it

actor Lint script
1 control
Commit message prefix: pod-<id>: <scope> — <acti
Shape:
pod-7: byline — fix debounce-swallow on rapid statusline refresh
what this step does
Shape: 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, or dir/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 —
auditor A separate shell

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, or dir/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 revert output.
  • 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:

  1. Counts staged files (git diff --cached --name-only | wc -l).
  2. Derives top-level dirs from staged paths.
  3. 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: true when violations is empty; ok: false and 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/, 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.
  • Stash-pop after git pull --rebase can SILENTLY revert your work. Conflict resolution drops files back to baseline with no error. After every rebase: wc -l <your-files> or git diff <ref-before-pull> -- <your-files>. Recovery: git checkout stash@{0} -- <your-files> (check git stash list for stash@{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 headless claude -p whose global commit-protocol can rewrite commit messages or stage unrelated files during attended-subagent windows. Now gated by a dirty-worktree check (excluding state/log/*), but if you see a commit message swap on commits you authored, suspect the auto-regen overlap and check state/log/auto-regen.log.

When to invoke the lint

Run npx tsx state/lint/commit-discipline.ts --n=10 at these moments:

  1. Pre-commit self-check - before git push, verify your last N commits pass.
  2. Parallel-batch verification - after a fan-out wave lands, scan the last 20 commits to catch any sweep.
  3. Evolve preflight - state/bin/evolve/run.ts already gates HEAD; manual lint surfaces older bundled commits in the recent window.
  4. Recovery widen - after a friction row about a bundled commit, run with --n=50 to find adjacent damage.
  5. Auto-shape eval (background) - the eval-row-mandatory drain runs lint with --json and writes pass/fail to state/log/evals.ndjson.

Commands

| ui dashboard | state/skills/pod-dispatch/resources/ui.openui |

stepcommand
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 hookstate/bin/pod-dispatch/install-hook.sh
bypass (rare)SNAPPY_POD_DISPATCH_BYPASS=1 git commit -m "..."
race-free commitgit commit -m "msg" -- path/a path/b
eval logstate/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: branded in 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 -am implicitly -a's unstaged tracked files - same failure mode as git add -A.
  • git stash push -u (without pathspec) sweeps every parallel agent's untracked WIP into one stash. Always git stash push -- <your-paths>.
  • Stash-pop on rebase conflict can silently revert files. Detection: post-rebase wc -l / git diff against pre-rebase ref.
  • TOCTOU race on shared index: another agent's git add between your add and commit pollutes your tree. Use pathspec on commit.
  • Auto-regen headless claude -p may rewrite commit messages during overlap. Verify your message on git log -1 after push.

Self-Test

  1. [ ] Did I list specific paths to git add, never a directory or -A?
  2. [ ] Does my commit message start with pod-<id>: or a concrete <scope>:?
  3. [ ] After staging, did I git status to confirm no other pod's file is in?
  4. [ ] File count ≤ 10 and top-level dirs ≤ 2?
  5. [ ] Did I use git commit -- <pathspec> (or verify the index is clean) to defeat TOCTOU index races?
  6. [ ] After any git pull --rebase, did I verify my files survived the auto-stash-pop with wc -l or git 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 LOGGED is 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

rubric auto-shape commit-discipline lint — staged files ≤ 10 AND top-level dirs ≤ 2
recent mean 1.00 · 10 runs actor/auditor: unverifiable
deps none declared
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 - -