← LinchpinCONTENT HISTORY

Update to Linchpin

Snapshot Sep 30, 2026 · 23:13 UTC · version 0.6.2

Collection source: not recorded for this historical snapshot.

WHAT CHANGED · RULE-BASED ANALYSIS

First saved snapshot

No earlier snapshot is available to establish a change.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "description": "Execute one or many conforming PRDs through contract-preserving Codex lanes with bounded parallelism, inherited gates, review, and honest delivery states.",
  "included_files": [],
  "name": "prd-swarm-coordinator",
  "skill_md_contents": "---\nname: prd-swarm-coordinator\ndescription: Execute one or many conforming PRDs through contract-preserving Codex lanes with bounded parallelism, inherited gates, review, and honest delivery states.\nlicense: MIT\n---\n\n# PRD Swarm Coordinator\n\n## Scope and runtime contract\n\nOwn one or many PRDs through the same intake, brief, scheduling, worker,\nreview, repair, and delivery path. A single PRD is a swarm of one; it does not\ntake a shortcut. The `references/` directory is at the plugin root, beside\n`skills/`; from this file resolve it as `../../references/`. Read `references/prd-contract.md` and\n`references/intake.md` before intake, and read `references/runtime.md` before\nany preflight or delegation. The executable checks live in\n`scripts/linchpin.sh`.\n\nThe manager is the current session's Manager role. Workers, repair workers,\nintegration workers, and conflict workers use the Worker role only through\nthe `codex exec` subprocess shape in `references/runtime.md`. The reviewer is a\nfresh `codex exec --sandbox read-only` process at the Reviewer row's model and\neffort. Read those values from the table; an effort written into this sentence\nis a second copy that goes stale the first time the pin changes. Never use a native\nsubagent for Luna, never change tier after a failed attempt, and use\n`codex exec resume <session-id>` only for a recorded continuation.\n\nThis skill does not support generic non-PRD swarm requests, and it does not arm\nthe optional goal loop.\n\nUse the referenced documents and `scripts/linchpin.sh` subcommands as interfaces:\ninvoke the specific check you need and inspect its output; do not read the full\nhelper source into context.\n\n## Intake branch\n\n1. Read the complete input artifact. Do not summarize it, and do not rewrite it.\n2. **Execute the PRD the user pointed at, as written.** A missing\n   `prd_contract: v1` marker, a legacy heading, a prose file list, or an absent\n   ledger does not block execution and is not a reason to migrate, re-author, or\n   draft a replacement. `scripts/linchpin.sh brief <prd>` transfers whatever\n   sections exist verbatim and marks the rest `NOT DECLARED`; the worker follows\n   the PRD's own phases and file lists from there. Standardize only when the user\n   asks. The only blocker is a path that is not on disk.\n3. Preserve whatever the artifact does declare — Integration Ledger, Negative\n   Controls, Acceptance Criteria, Checkpoint Protocol — verbatim. Do not\n   re-derive a shorter checklist, and do not add a gate the author never asked\n   for to compensate for a section the PRD does not have.\n4. A creator output never auto-starts this skill. Require explicit confirmation\n   after creation or upgrade and before preflight.\n5. Use `references/intake.md` for intent, complexity-floor refusal, config, and\n   capability routing. Repository state cannot override a direct write-PRD\n   request.\n\n## Preflight and configuration\n\nRead optional `.linchpin.toml` using the defaults and validation in\n`references/intake.md`. Its absence is valid. Record the resolved values in the\nrun ledger and persist typed natural-language overrides before scheduling.\n\nRun these checks before branches or workers:\n\n- verify the target is a Git repository;\n- run `scripts/linchpin.sh preflight` against `$CODEX_HOME/models_cache.json`;\n  it resolves both role models and confirms `$CODEX_HOME` is writable, which is\n  what every worker and reviewer subprocess needs before its model starts;\n- inspect current status, default branch, remotes, and delivery capability;\n- parse every phase `Files (N)` list; a malformed list is an error, never an\n  assumption of disjointness;\n- verify the review setting was explicitly chosen if it is false.\n\nOnly a missing Git repository or missing worker capability is a refusal. A\nmissing worktree, dirty unstashable tree, missing remote, or missing PR client\nis a named degradation unless the user explicitly forced the unavailable mode.\n\n## Contract-preserving worker brief\n\nGenerate each brief with the resolved lane metadata, writing it to a file:\n`scripts/linchpin.sh brief <prd> <lane-id> <lane-mode> <delivery-mode> --config-dir <target-repo> --out <brief-file>`,\nthen verify it with\n`scripts/linchpin.sh brief-check <prd> <brief-file> --config-dir <target-repo>`\nand pass that file's contents as the worker prompt. Pass `--config-dir` to both:\nyour working directory is not necessarily the target repository, and a brief\nemitted with the repository's config but checked without it fails its own\nverification on a stale runtime pin. The brief is the handoff; a\nprompt you compose yourself instead is a dropped ledger and a dropped scope rule.\nResolve these values before invocation from `.linchpin.toml`, the\nfile-intersection group, and delivery capability. With no config file, the\nhelper's `brief <prd>` form remains a lane-1/parallel/pr default for direct\ncallers; production lanes pass all three resolved values. The brief contains,\nin this order:\n\n1. source PRD path and lane identity;\n2. every parsed file path from every phase;\n3. the complete Integration Ledger copied verbatim, including every row's Live\n   caller and Negative control;\n4. the complete Negative Controls table copied verbatim;\n5. the complete Acceptance Criteria and Checkpoint Protocol copied verbatim;\n6. the runtime-derived worker/reviewer invocation shapes, lane mode, delivery\n   mode, and prohibited actions. Model and mechanism come only from\n   `references/runtime.md`. Effort comes from there too unless the target\n   repository's `.linchpin.toml` sets `worker_effort` or `reviewer_effort`,\n   which is why the brief is generated with `--config-dir`. Read the emitted\n   values out of the brief rather than restating a pin from memory.\n\nBefore launch, compare ledger row ids between source and brief. A missing row,\ncaller, or control rejects the brief. The worker must not be asked to infer\nmissing acceptance criteria from a summary.\n\n## Per-group mode selection\n\nRun `scripts/linchpin.sh mode <resolved-execution> [--config-dir <target-repo>] <prd...>` after all lists parse. It\nbuilds the file-intersection graph and emits one group per connected component:\n\n- disjoint groups use parallel worktrees when worktree creation succeeds;\n- groups with intersecting file sets run sequentially, one lane at a time;\n- a PRD with no `Files (N)` list has its set derived from its prose `**Files:**`\n  paragraphs, for grouping only — the file on disk is never rewritten;\n- a PRD that declares no file set at all takes its own group with its isolation\n  announced as unproven; it never drags the rest of the batch into its queue;\n- explicit sequential mode makes all groups sequential;\n- explicit parallel mode fails loudly on intersection or worktree failure;\n- auto mode degrades only the affected group and announces the reason;\n- `max_lanes` is a real concurrency bound; each group reports `active=` and\n  `queued=` lanes when capacity is exceeded;\n- one lane uses the same output, gate, review, and delivery fields as any other\n  group and has no special branch.\n\nWhen a group must degrade, run `scripts/linchpin.sh schedule auto <status>\n[--config-dir <target-repo>] ...` with the status that actually happened —\n`worktree-fail`, `dirty-tree`, `unparsed-files`, or `config`. Attempt the real\n`git worktree add` before you claim it failed; the announcement the user reads\nmust name the true reason. Announce the sequential fallback before starting the\nfirst lane, and preserve the same brief and gates. The schedule output identifies active and queued\nlanes under `max_lanes`. Never abort a normal auto run for unavailable\nisolation. For a forced parallel run, fail with the exact capability error so\nthe user can correct the environment.\n\nMode is per group. A colliding pair may be sequential while an independent pair\nremains parallel. A worker never receives a weaker gate because its group is\nsequential.\n\n## Lane lifecycle\n\nRun `scripts/linchpin.sh workspace <target-repo>` **before the first write to\n`.linchpin/`**, including the ledger. It creates the directory and adds\n`.linchpin/` and `.worktrees/` to that repository's `.git/info/exclude` unless\nthey are already ignored. Run output is Linchpin's scratch space, not the\nuser's work: it must never appear in `git status`, never be staged into a lane\ncommit, and never force a manual cleanup after the batch. The entries go in\n`.git/info/exclude` rather than `.gitignore` on purpose — ignoring our own\noutput must not itself leave a modified tracked file behind. If the user asks\nfor the ignore to be committed instead, add `.linchpin/` to `.gitignore` and\nsay so; do not do it unasked.\n\nKeep a run ledger at `.linchpin/run-<timestamp>.md` in the target repository,\nwritten before the first worker starts and updated as each lane changes state.\nWrite every row with the helper, never by hand:\n\n```sh\nscripts/linchpin.sh lane .linchpin/run-<timestamp>.md <lane-id> \\\n  --set state=RUNNING --set prd=<path> --set branch=<branch> --set pid=<pid>\n```\n\nEach call upserts that lane's row and keeps the fields earlier calls wrote, so\nrecord what you know when you know it. For every lane record the PRD, slug,\nbaseline, branch, worktree or shared-tree mode, file set, overlap group,\ndependencies, process id, subprocess session id, brief path, verification\ncommands, review state, repair rounds, delivery mode, and terminal evidence.\n\n`lane` refuses a row it cannot verify: an unknown state, `MERGED` as a product\nstate, a `commit` sha that does not resolve in the repository, a\n`DELIVERED(...)` row missing its prd, branch, commit, gates, or review, a\n`gates` path that is not on disk, or a `BLOCKED` row with no `reason` and\n`resume`. That refusal is the point — a lane recorded as committed whose sha the\nworker never created is the false ledger row this run exists to make impossible,\nand it is not a claim you can talk your way past. Fix the row or fix the lane.\n\nA run with no ledger file on disk is not resumable, and an unresumable run is\nnot a run.\n\n1. **Every lane gets its own branch**, sequential ones included:\n   `git switch -c linchpin/<lane-slug>` from the same detected base branch.\n   Never branch a lane from another lane, and never let a worker commit onto the\n   branch the user had checked out. Sequential means one lane at a time in the\n   shared tree; it never means committing onto the user's working branch.\n   Branch from the **remote** base after a fetch (`origin/<base>`), not from the\n   local branch of the same name. A local base that sits ahead of its remote\n   carries the user's unrelated committed work into every lane, and delivery\n   then merges that work under a PR title that never mentions it. If local and\n   remote have diverged, say so before the first lane starts; whose commits\n   those are is the user's call, not a detail to resolve silently.\n\n   For a worktree lane, create it with\n   `scripts/linchpin.sh worktree <main-repo> <lane-slug> <base>`, always from\n   the repository's **main** worktree and never from inside another lane. It\n   fetches, resolves `origin/<base>`, refuses a nested or already-claimed lane,\n   and prints `WORKTREE-READY` or a `WORKTREE-FAIL <reason>` you pass straight\n   to `schedule auto`. Do not substitute a worktree helper from the user's\n   machine: one of those pulled the base branch inside the user's dirty source\n   tree on the way to creating the worktree and left an unresolved merge across\n   twenty uncommitted files. Lane isolation is Linchpin's to perform, and the\n   source tree the user is sitting in is never modified to create a lane.\n2. **Make the worktree able to run the gates before the worker starts.** A fresh\n   worktree has source but no build state: no installed dependencies, and none\n   of the repository's local tooling. Every lane that discovers this alone\n   discovers it again in parallel, and reports a gate it could not run as if\n   that were a verification result. Once per run, resolve the bootstrap for this\n   repository — its lockfile install, its pinned runtime version, and whether\n   dependencies can be shared across lanes rather than installed per lane — then\n   apply it to each worktree and state in the ledger which gate commands are\n   actually runnable there. Check the repository's own test configuration for\n   path exclusions that would silently match your worktree directory and match\n   zero tests; if one does, resolve the override once and put it in every brief\n   rather than letting each lane rediscover it. The same gap breaks commits: a\n   repository whose commit hooks run out of `node_modules` rejects every commit\n   in a fresh worktree until dependencies are installed, so bootstrap before the\n   first commit rather than after it. If what you are committing is your own\n   manager housekeeping — a ledger, a plan file — recording it with hooks\n   skipped is acceptable and worth saying out loud; a lane commit is never\n   delivered on skipped hooks.\n3. Launch workers using only the Worker row in `references/runtime.md`. Pin the\n   required effort and working directory in the subprocess invocation, and pass\n   the generated brief file as the prompt. Do not inherit session defaults, do\n   not retype the brief into a prompt of your own, and do not route code edits\n   through another runtime.\n4. Require a worker commit, exact test output, caller census, revert check, and\n   gate evidence before manager verification. The commit is evidenced by the\n   commit itself, never by a worker's summary claiming one. A lane recorded as\n   committed whose sha the worker never created is a false ledger row.\n5. Keep a partial lane and its worktree. A timeout or worker summary is not a\n   delivery result; inspect the actual diff and resume from the recorded state.\n6. A lane that ends `PARTIAL` or `BLOCKED` releases its group's queue. The next\n   queued lane starts; the batch does not stall behind a lane that is done\n   failing.\n\n### Awaiting a lane\n\nA lane takes minutes, and its progress prose is not evidence you will act on.\nLaunch each worker **detached**, with its output redirected to a log and its\nprocess id written to `.linchpin/<lane>.pid`, so that no lane holds an\ninteractive session open for you to babysit:\n\n```sh\ncodex exec ... > .linchpin/<lane>.log 2>&1 &\necho $! > .linchpin/<lane>.pid\n```\n\nThen wait on the whole group at once:\n\n```sh\nscripts/linchpin.sh await .linchpin/<lane-a>.pid .linchpin/<lane-b>.pid --interval 60\n```\n\nIt blocks until every lane in the group has exited and prints one\n`AWAIT-DONE` row per lane. Waiting for a group in one call costs turns in\nproportion to the number of groups; polling each live subprocess on a short\ntimer costs turns in proportion to lane duration, and runs that did it spent\nhundreds of turns restating that a lane was still running. Process exit and the\nreal diff are the only two signals worth a turn; announce a lane's status when\nit changes, not on a timer.\n\n### Ending the run\n\nThe run is over when the workspace looks the way it did before it started. For\nevery lane, after its delivery state is terminal and recorded: remove the\nworktree, prune the worktree list, and delete the lane branch that was merged.\nKeep the worktree and branch of any lane that ended `PARTIAL` or `BLOCKED` —\nthose are resumable state — and name in the final report exactly what was kept\nand the command that resumes or removes it. Leave `.linchpin/` in place as the\nrun record; `workspace` has already kept it out of `git status`. Check the\ntarget repository's status at the end and account for anything Linchpin added\nthat is still there. Cleanup is part of delivery, not an optional courtesy.\n\n## Inherited lane gates\n\nThe PRD's Negative Controls table is an inherited lane gate, not advice. Copy it\ninto the reviewer packet with the ledger and require one Gate Evidence row for\nevery control. The evidence format is:\n\n```markdown\n## Gate Evidence\n| Gate | Result | Observed-red evidence | Exact command/result |\n|---|---|---|---|\n| gate-id | PASS | RED observed: disabled gate | `command: sh tests/example.sh`; result: RED observed: disabled gate; exit: 1 |\n```\n\nThe exact command/result cell repeats the command documented in the PRD's\nNegative Controls table. `gate` rejects missing, duplicate, or extra gate ids,\ngeneric evidence without that exact command, green-only evidence, and zero\nexits.\n\nRun `scripts/linchpin.sh gate <prd> <report>` before delivery. A report with\nonly green assertions, a missing control, or a missing observed-red line is\n`UNVERIFIED` and rejected. Every control must have failed as expected at least\nonce. This rule is identical in parallel and sequential mode.\n\nWhen the PRD declares no Negative Controls, `gate` reports\n`GATES-NOT-DECLARED` and delivery proceeds on the verification the PRD *does*\ndeclare. Do not invent controls the author never wrote, and do not hold a lane\nbecause a section is absent. The inherited-gate rule binds the controls a PRD\ndeclares; it never manufactures new ones.\n\nThe reviewer packet must contain the negative-control table even when all\nfunctional tests are green. The manager records the exact red command and its\nnon-zero result; a verbal claim is not evidence.\n\n## One review and repair rule\n\nTwo preconditions come before the reviewer, in this order. A lane that fails\neither is not ready for review, and launching a reviewer anyway produces a\nrejection that says nothing about the code:\n\n1. **The lane is committed.** An uncommitted working tree is `PARTIAL`. Get the\n   worker's own commit first; a missing commit is a worker-contract failure that\n   no review round can fix.\n2. **You have run the gates yourself.** The reviewer is `--sandbox read-only`:\n   it cannot install dependencies, write a cache, bind a port, or run the\n   repository's suites. Run them in a writable tree and produce the Gate\n   Evidence table before the reviewer starts.\n\nGenerate the review brief with the helper; it refuses to emit without both:\n\n```sh\nscripts/linchpin.sh review-brief <prd> <lane-id> --gates <gate-evidence.md> --commit <sha> --out <review>\n```\n\nThen launch exactly one fresh reviewer per lane through this shape, with all\nrole values resolved from the Reviewer row in `references/runtime.md`:\n\n```text\ncodex exec --model <Reviewer.Model> -c 'model_reasoning_effort=\"<Reviewer.Effort>\"' --sandbox read-only -C <lane> \"$(cat <review-file>)\"\n```\n\nPass the file `review-brief --out` wrote. Do not interpolate the packet's text\ninto the command line: it contains backticks, quoted commands, and table pipes,\nand a manager that hand-escaped one sent `codex` a mangled argument and read its\n`Reading additional input from stdin...` as a review. If the reviewer exits\nbefore the model starts, that is an environment failure, not a verdict — the\nusual cause is a `$CODEX_HOME` the process cannot write, which preflight already\nchecks. Report it as an unresolved external gate and say the lane is unreviewed;\nnever let a reviewer that could not start be recorded as a lane that passed.\n\nRecord `review_used: true` before launch. The reviewer cannot edit. The manager\ncloses findings after Luna repair; no second reviewer is started after repair.\n\nEvery finding is labelled `DEFECT` or `EVIDENCE-GAP`. Only a `DEFECT` blocks\ndelivery. An `EVIDENCE-GAP` is recorded in the ledger and delivered past — a\nreviewer reporting what it was structurally unable to run is describing its own\nsandbox, not a fault in the lane.\n\nState facts in the brief without classifying them. A brief that says \"treat the\nmissing commit as a finding\" has already written the verdict, and the review\nthat comes back is an echo. `APPROVE` with zero findings is a valid review.\n\nWhat this review is for is the class of defect only a reader reaches: a negative\ncontrol that stays green when the feature is deleted, a field the code accepts\nand never maps, a document asserting behavior the code contradicts. Narrow the\nquestion to that; never trade away the rigor.\n\nWhen a worker or reviewer exposes a failure, treat it first as specification\nevidence. Before re-delegating, write a corrected or narrowed handoff naming the\nexact file, line, expected behavior, failing command, and newly required test.\nThe handoff must differ from the failed prompt. Never repeat an unchanged\nprompt, and never change the model tier or effort to escape a failed gate.\nUse the recorded `codex exec resume <session-id>` only when the corrected\ncontinuation is explicit.\n\nA repair round is for a `DEFECT`. Spawning a fresh worker whose entire scope is\n\"commit the diff that already exists\" is not repair — it is manager integration\nwork, and it costs a full model run to reach a `git commit` you could have made\ndirectly. If a lane arrives uncommitted, fix it as integration and record the\nworker-contract failure; do not dress it up as a repair round. A lane whose PRD\nrequires that nothing be committed is already correct and never gets one.\n\nRepair, integration, and conflict work face the same inherited gates. Ordinary\noverlap and merge conflicts are manager-directed integration work; preserve the\naccepted intent of both PRDs and add a regression test when resolution combines\nbehavior. A semantic conflict that would require violating a PRD is a named\n`BLOCKED` decision, not a silent rewrite.\n\n## Delivery and terminal states\n\nResolve delivery from `.linchpin.toml`: `pr` by default, `branch` when selected,\nand `branch` after an announced missing-remote or missing-client fallback. A\ndelivery fallback does not remove review, gate evidence, or verification.\n\nProbe the PR path once, at preflight, rather than discovering it lane by lane at\nthe moment of delivery. Confirm which client actually works against this remote,\nand which merge methods the repository permits, before the first merge — a\nrepository that forbids merge commits rejects the merge after the PR is already\nopen. Record the working client and the permitted method in the ledger and use\nthem for every lane.\n\n**Merging to a shared base branch is the one stop-and-confirm point.** Opening\nPRs, pushing lane branches, and reporting are all Linchpin's to do. Merging\nanother lane's work into a branch other people build on is the user's decision,\nand an autonomous run is exactly the situation where nobody is watching. Ask\nonce, before the first merge, and carry the answer across the remaining lanes.\nIf the run was told not to stop, deliver every lane as an open PR and say that\nthe merges are waiting — an unmerged PR is recoverable, a merge is not.\n\nUse only these terminal forms:\n\n- `DELIVERED(pr)` or `DELIVERED(branch)` after the full evidence packet passes;\n- `BLOCKED <named external reason> <resumable command>` with preserved state;\n- `PARTIAL` while implementation or evidence is incomplete.\n\nNever label a lane `MERGED` as its product state. Never call a lane delivered\nbecause a process exited, a summary said done, or a green-only test suite ran.\n\n## Final controller verification\n\nBefore handing off, inspect the real branch or shared-tree diff and run the\ngates the **target repository** names — its own test, lint, typecheck, and build\ncommands, discovered from that repository. Linchpin's own repository scripts\n(`scripts/verify.sh`, its shellcheck and jq checks) are for developing this\nplugin; never run them inside a user's repository.\n\nConfirm the diff contains only the files the PRD's scope covers. An unrelated\ndeletion, an unrelated dependency bump, or an unrelated doc edit that arrived\ninside a lane commit is a finding, not a bonus: name it, and get the worker's\nown commit narrowed before delivery.\n\nRead the ledger back rather than recalling it:\n\n```sh\nscripts/linchpin.sh status .linchpin/run-<timestamp>.md\n```\n\nIt prints one line per lane and exits `0` only when every lane is\n`DELIVERED(...)`, `1` while any lane is still open, and `2` when the only\nunfinished lanes are `BLOCKED`. Summarizing eight lanes from memory at the end\nof a long batch is where a run starts reporting work it did not do; the command\nis the answer, and its exit code is the honest one.\n\nThe final report maps every PRD criterion and every ledger row to a command,\nfile:line, or captured result. It names observed-red failures, unresolved\nexternal gates, and a resumable command. It never claims the external install\nswap or live post-swap resolution without owner evidence.\n"
}

SHA-256 of public snapshot: 62b1e39b41c4b3927cce6bfcc18d3052035a0999d89e06a20430e317ec74a353