jobcard-system
Skill1 starsChanged 50 days agoMITView on GitHub
Use when working in the jobcard repository, dispatching agents, writing specs, creating cards, or understanding the card lifecycle. This is a multi-agent task orchestration system — NOT the transit data standard.
In this repository113 other files it gives its agents.
- AGENTS.mdAGENTS.md
- ac-ideateSkill
- ac-listSkill
- ac-roadmapSkill
- agentbridge-mcpSkill
- almanacSkill
- almquist-shellSkill
- ansible-fleetSkill
- apfsSkill
- apple-siliconSkill
- arena-actorsSkill
- asustor-nasSkill
- a-teamSkill
- atem-miniSkill
- at-tuiSkill
- autoresearchSkill
- babysitSkill
- bonzibuddySkill
- bop-brainstormSkill
- bop-catalogSkill
- bop-onSkill
- bop-teamSkill
- bop-workflowSkill
- bsd-portabilitySkill
- code-refactoringSkill
- codex-personasSkill
- context-graphSkill
- councilSkill
- datadog-backupSkill
- dd-tagsSkill
- delegateSkill
- deming-pdsaSkill
- deterministic-replaySkill
- dispatch-nuSkill
- durable-commitSkill
- elixir-gastown-opsSkill
- ergo-ircSkill
- esp32-tang-bridgeSkill
- fleet-evalSkill
- fleet-ircSkill
- freebsd-build-vmSkill
- freebsd-piSkill
- freebsdSkill
- ganttSkill
- gastown-opsSkill
- gastown-slingSkill
- gh-authSkill
- gitea-releaseSkill
- gitea-runnerSkill
- henshuSkill
- irclaw-cluster-opsSkill
- irclaw-research-teamSkill
- irc-taskSkill
- jail-factorySkill
- jjSkill
- kubernetesSkill
- leptosSkill
- loreSkill
- lower-bound-reviewSkill
- macvlan-netSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
12 rules. About 0 are common, 3 are distinctive, and 9 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
9
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 51
Every file has exactly one job
- Very specific: line 98
Use filename prefix for poker visibility while keeping meta.id canonical.
- Very specific: line 102
Keep meta.id stable as feat-auth (CLI queries stay stable)
- Very specific: line 106
Only rename outside running/ (prefer pending/.
- Very specific: line 109
If poker consensus finalized a glyph, write meta.glyph in the same critical section.
- Very specific: line 123
When a stage finishes (exit 0), dispatcher reads stage_chain, creates next-stage child card in pending/ inheriting spec + glyph + prior …
- Very specific: line 126
All four fields are on the Meta struct (landed 2026-03-01).
- Distinctive: line 145
Every token earns its slot.
- Very specific: line 184
Keep default atomic replacement behavior.
- Very specific: line 272
All zsh scripts use ROOT=${0:A:h:h}.
- Very specific: line 273
Never use done as a variable (zsh reserved — use n_done).
- Distinctive: line 286
Every dispatched agent is shaped by (inner wins):
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Jobcard System (bop)
Naming — COMPLETE (2026-03-01)
| Role | Name |
| CLI binary | bop |
| Quick Look bundle | sh.bop.ql |
| Host app bundle | sh.bop |
| Card UTI | sh.bop.card |
| launchd labels | sh.bop.dispatcher, sh.bop.merge-gate |
bop new implement feat-auth # deal a card into pending/
bop status # card counts by state
bop dispatcher --once # process one pending card
bop merge-gate --once # process one done card
bop inspect <id> # show meta + spec + log tail
bop approve <id> # clear decision_required gate
bop kill <id> # terminate running agent
bop logs <id> # colorized log tail (tailspin-style)
bop poker open <id> # start estimation round
bop poker submit <id> [--glyph 🂻] [--name alice]
bop poker reveal <id> # reveal all estimates
bop poker consensus <id> --glyph 🂻 # lock in final estimate
bop factory install # generate + load launchd plists
bop factory status # check if services are running
bop factory start # start both services
bop factory stop # stop both services
bop factory uninstall # unload + remove plists
bop icons # FSEvents watcher: auto-updates Finder icons on state change
bop gantt # ANSI Gantt timeline in terminal (auto-fits pane)
bop gantt -w 80 # force width (Zellij panes)
bop gantt --html # write .cards/bop-gantt.html
bop gantt -o # write HTML + open in browser
bop events # OpenLineage event stream
bop events --card <id> # filter events by cardbop factory install also sets up the icon watcher alongside dispatcher and merge-gate.
MICROCLAW Principle
Fewer files. Sharper precision. Minimum viable factory.
- Every file has exactly one job
- Agents can participate with just
mkdir+echo '{}' > meta.json - The FORMAT is the product; the CLI is one thin reference impl
- Like Apache Iceberg (table format, any engine reads/writes)
Core Framing
The filesystem IS the state machine. Playing cards ARE the identity system. The FORMAT is the product.
# Minimum viable card — no CLI needed
mkdir -p .cards/pending/my-task.jobcard
echo '{"id":"my-task","stage":"implement","created":"2026-03-01T00:00:00Z"}' \
> .cards/pending/my-task.jobcard/meta.json
echo "# My Task\nDo X" > .cards/pending/my-task.jobcard/spec.mdArchitecture
.cards/
stages/ ← stage instruction files (spec.md, plan.md, implement.md, qa.md)
templates/ ← factory recipes (implement, full, cheap, qa-only)
system_context.md ← prepended to every agent prompt
<team>/<state>/<id>.jobcard/
meta.json ← card identity, stage pipeline, glyph, labels, subtasks
spec.md ← what to build
prompt.md ← rendered from template, sent to agent
logs/ ← stdout.log, stderr.log, pid, lease.json
output/ ← result.md, cards.yaml (child card seeds)
QuickLook/ ← Thumbnail.png for Finder previewState Machine
pending/ → running/ → done/ → merged/
↓
failed/Transitions are atomic fs::rename. Dispatcher owns pending/→running/.
Merge-gate owns done/→merged/ (runs acceptance_criteria first).
Filename Glyph Lifecycle (Poker)
Use filename prefix for poker visibility while keeping meta.id canonical.
- Before consensus:
🂠-feat-auth.jobcard - After consensus:
🂻-feat-auth.jobcard - Keep
meta.idstable asfeat-auth(CLI queries stay stable)
Safe rename flow (filesystem-first, same volume):
- Only rename outside
running/(preferpending/; allowdone//failed/for cleanup). - Hold card lock / ownership gate; assert destination path does not exist.
- Apply atomic rename (
fs::rename). - If poker consensus finalized a glyph, write
meta.glyphin the same critical section. - Refresh visual artifacts (
QuickLook/Thumbnail.png+ Finder icon).
Stage Pipeline (Factory Engine)
Templates define the stage pipeline via these meta.json fields:
| Field | Type | Example |
stage_chain | Vec<String> | ["implement", "qa"] |
stage_models | Map<String,String> | {"implement":"opus","qa":"sonnet"} |
stage_providers | Map<String,String> | {"implement":"claude","qa":"codex"} |
stage_budgets | Map<String,u64> | {"implement":32000,"qa":8000} |
When a stage finishes (exit 0), dispatcher reads stage_chain, creates next-stage
child card in pending/ inheriting spec + glyph + prior output. Final stage → done/.
All four fields are on the Meta struct (landed 2026-03-01). render_prompt substitutes
{{stage_instructions}}, {{stage_index}}, {{stage_count}}, {{prior_stage_output}}.
Dispatcher auto-advances stages via maybe_advance_stage().
Stage Instruction Files
.cards/stages/ — one markdown file per stage, ~50 tokens each:
| File | Agent's job |
spec.md | Write a spec under 500 words. No code. |
plan.md | Read spec, produce ordered steps under 800 words. |
implement.md | Write code, run tests, exit 0 when green. |
qa.md | Review as a different agent. Be skeptical. |
Custom stages: create .cards/stages/<name>.md, add to template's stage_chain.
Context Window Architecture
Every token earns its slot. Dispatcher builds prompts by layering:
system_context.md ~150 tokens domain fix
stages/<stage>.md ~50 tokens stage behavior
card header ~20 tokens id + glyph + stage index
spec.md variable the work
prior_stage_output variable previous stage result
acceptance_criteria ~10 tokens shell gatesTemplate variables in prompt.md:
{{system_context}}—.cards/system_context.md(WORKS){{stage_instructions}}—.cards/stages/<stage>.md(WORKS){{stage_index}}/{{stage_count}}— position in chain (WORKS){{prior_stage_output}}— previous stage'soutput/result.md(WORKS){{spec}},{{plan}},{{acceptance_criteria}},{{memory}}— WORK
Templates
Live in .cards/templates/. Four shipping templates:
| Template | Stages | Models | Cost | Use When |
| implement | implement → qa | opus → sonnet | $$ | Clear requirements |
| full | spec → plan → implement → qa | sonnet → sonnet → opus → sonnet | $$$ | Complex/ambiguous |
| cheap | implement | ollama-local | free | Small fix, local model |
| qa-only | qa | sonnet | $ | Code review, audit |
Create your own: cp -c -R .cards/templates/implement.jobcard .cards/templates/mine.jobcard
then edit meta.json (stage_chain, stage_models, stage_providers, stage_budgets).
See plan.md §8 for annotated meta.json reference.
COW-clone: cp -c (macOS APFS) or cp --reflink=auto (Linux).
APFS Copy, Dedupe, Compression (macOS)
- Fast template clone:
cp -c -R(clonefile/COW on APFS). - Metadata-safe bundle copy:
ditto --clone --extattr --acl --qtn --preserveHFSCompression <src> <dst>. - Keep default atomic replacement behavior; avoid
ditto --nonAtomicCopiesfor card bundles. - Cold-card storage option:
ditto --hfsCompression(or preserve existing compression with default--preserveHFSCompression). - For archive export/import, use
ditto -c -k/ditto -x -k; prefer staging + atomic move into.cards/.
Filename Tooling Compatibility (macOS 26.3 validation)
With 🂠-feat-auth.jobcard on APFS, these worked in tests:
rg,tail,eza,batbop inspect feat-authbop logs feat-authbop logs -f feat-authwhen the card is inrunning/
exa is no longer a Homebrew formula; standardize on eza.
Filesystem Hardening
- Dispatcher lock:
.cards/.locks/dispatcher.lock/owner.json- Acquire with atomic
mkdir; reject if live owner PID exists - Reclaim stale lock (dead PID) and continue
- Acquire with atomic
- Run lease per card:
logs/lease.json- Fields:
run_id,pid,pid_start_time,started_at,heartbeat_at,host - Dispatcher heartbeats every 5s; stale floor is 30s
- Fields:
- Orphan reaping: reap when PID dead OR lease stale
- Normalize stale stage metadata (
running → pending/failed)
- Normalize stale stage metadata (
- Idempotent controls:
bop kill <id>succeeds even with stale PIDbop retry <id>clears failure reason + normalizes stage
Meta.json Fields
| Field | Meaning |
glyph | SMP playing card (suit=team, rank=priority) |
token | BMP symbol for terminals/filenames |
stage | Current stage: spec / plan / implement / qa |
stage_chain | Full pipeline: ["implement","qa"] |
stage_models | Model per stage: {"implement":"opus"} |
stage_providers | Adapter per stage: {"implement":"claude"} |
stage_budgets | Token budget per stage: {"implement":32000} |
stages.<s>.status | pending / running / done / blocked / failed |
zellij_session | Zellij session name for running card |
zellij_pane | Zellij pane ID for running card |
worktree_branch | Git branch — never touch main |
acceptance_criteria | Shell commands merge-gate runs |
decision_required | true = merge-gate holds; bop approve clears |
provider_chain | Failover order: ["claude","codex","ollama-local"] |
timeout_seconds | Kill agent after this many seconds |
estimates | Planning poker: {"alice":"🂻","bob":"🂺"} |
poker_round | "open" / "revealed" / absent |
labels | [{"name":"High Impact","kind":"effort"}] |
subtasks | [{"id":"s1","title":"Do X","done":false}] |
progress | 0–100 overall completion % |
Adapter Contract
adapter.zsh <workdir> <prompt_file> <stdout_log> <stderr_log> [timeout]| Exit | Meaning | Action |
| 0 | Success | → done/ |
| 75 | Rate-limited | → pending/, rotate provider |
| other | Failure | → failed/ |
Available: claude.zsh, codex.zsh, ollama-local.zsh, goose.zsh, aider.zsh, opencode.zsh, mock.zsh.
Planning Poker
Suit → perspective: ♠=complexity ♥=effort ♦=risk ♣=value. Rank → magnitude: Ace=1, 2-10=face, Jack=13, Queen=21, King=40. Joker (🃟/🃏) → needs breakdown, blocks consensus.
Scripts
| Script | Purpose |
scripts/land_safe.zsh | JJ/git safe-landing with gate checks |
scripts/bop_bop.zsh | Goal→card→Zellij session bootstrap |
scripts/bop_focus.zsh | Navigate Zellij panes by card id |
scripts/macos_cards_maintenance.zsh | Thumbnail refresh, cold card compression |
scripts/render_card_thumbnail.swift | Generate QuickLook/Thumbnail.png |
scripts/set_card_icon.swift | Stage-coloured Finder icons for .jobcard bundles |
All zsh scripts use ROOT=${0:A:h:h}. setopt NULL_GLOB for .jobcard globs.
Never use done as a variable (zsh reserved — use n_done).
Quick Look / macOS
- Xcode project:
macos/macos.xcodeproj - Extension:
macos/bop/PreviewViewController.swift - Host app:
macos/JobCardHost/(registersbop://URL scheme) - Build: Xcode → Product → Build
- Register:
lsregister -f ~/Applications/JobCardHost.app - Bundle IDs:
sh.bop(host),sh.bop.ql(extension),sh.bop.card(UTI)
Three Steering Layers
Every dispatched agent is shaped by (inner wins):
- Skills (
~/.claude/skills/) — HOW to approach work - CLAUDE.md — project constraints, shell rules, architecture
system_context.md— runtime domain fix ("NOT GTFS transit data")
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

