Skip to content

fix(vibe): ship combined 1.0.74 lessons release - #334

Merged
shafty023 merged 21 commits into
mainfrom
fix/vibe-lessons-20261021e
Oct 22, 2026
Merged

shafty023 merged 21 commits into
mainfrom
fix/vibe-lessons-20261021e

Conversation

@shafty023

@shafty023 shafty023 commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

Purpose

Ship Daniel's 2026-10-21/22 vibe lessons as one pull request and one vibe 1.0.74 release. This branch preserves the commits from #331, #332, #333, and #335, including the Storybook guard corrections at 87c61fc, and merges current main rather than rebasing.

Folded pull requests

Release metadata

  • One changelog entry: vibe v1.0.74
  • One version bump: vibe 1.0.73 → 1.0.74 in both manifests
  • The version-specific lesson contracts are consolidated into the 1.0.74 contract.
  • The deadline-only decision to skip pre-merge E2E is deliberately excluded; it is not a plugin rule.

Prevention closeouts

Supervisor restart and throttle

Prevention

  • Class: used launchctl kickstart -k when restarting a supervised watcher, causing the caller to hang and the supervisor to remain absent for the full throttle interval.
  • Instances: fixed plugins/vibe/skills/codex-fleet-monitor/SKILL.md, scripts/watch.sh, and templates/codex-fleet-supervisor.plist.
  • Search: rg -n 'kickstart|ThrottleInterval|bootstrap|bootout' plugins/vibe
  • Rung: 3 via scripts/templates.test.mjs, with the restart recipe and 30-second throttle in the owned template.
  • Proof: the template test recreates the forbidden restart/throttle text and fails unless bootout/bootstrap and the bounded interval remain.
  • Why not higher: launchd restart choice is shell/config behavior, not a representable type.
  • Follow-up: none.

Live-product precedent

Prevention

  • Class: researched public help pages when asked what Asana does, causing a live, observable behavior to be reported as undocumented.
  • Instances: fixed agents/vibe-requirements-worker.md, skills/vibe/references/quality-loop.md, skills/vibe/scripts/precedent-check.mjs, README, and precedent eval twins.
  • Search: rg -n --glob '!**/history.jsonl' 'public help|help center|another app|--no-browser' plugins/vibe
  • Rung: 2 via precedent-check.mjs, which has no web-search tools or public fallback and rejects public-only reports.
  • Proof: a recreated help-center report exited 1 with the answer is from public material; focused Node tests pass after restoration.
  • Why not higher: whether browser evidence answers the question is runtime evidence, not a type state.
  • Follow-up: none.

Stopped helpers left app stacks

Prevention

  • Class: stopped QA/review workers without terminating their owned child processes, causing dev stacks to consume machine resources for 13–16 hours.
  • Instances: fixed fleet helpers.mjs, its helper ledger, orphan reporting, and worker instructions.
  • Search: rg -n 'pids|endProcesses|ORPHAN|stopped' plugins/vibe/skills/fleet-orchestrator
  • Rung: 1 via an owned process ledger whose stopped transition cannot complete while a recorded owned process is alive.
  • Proof: helpers.test.mjs recreates live recorded children and requires termination before the stopped state.
  • Why not higher: this is the architecture rung; ownership and lifecycle are represented together.
  • Follow-up: none.

Containerized E2E collision

Prevention

  • Class: ran a fixed-name E2E compose project concurrently, causing one session's teardown to remove another session's stack.
  • Instances: fixed skills/vibe/scripts/e2e-lock.mjs, environment/handoff instructions, and compose-project tests.
  • Search: rg -n 'COMPOSE_PROJECT_NAME|foreign-compose|e2e-lock|compose project' plugins/vibe
  • Rung: 1 via a lease plus a unique per-run compose project recorded by the launcher.
  • Proof: e2e-lock.test.mjs recreates a foreign live project and concurrent lease and requires refusal/isolation.
  • Why not higher: this is the architecture rung; teardown is bound to the project the run created.
  • Follow-up: none.

QA checkpoint delivery

Prevention

  • Class: told the operator that a checkpoint was ready without notifying the guide session, causing the guide to remain blocked on stale state.
  • Instances: fixed fleet board.mjs, board.md, and the worker/QA guide delivery workflow.
  • Search: rg -n 'checkpoint|UNTOLD|told|guide' plugins/vibe/skills/fleet-orchestrator
  • Rung: 1 via durable delivery records that remain open per recipient until explicitly acknowledged.
  • Proof: board.test.mjs recreates a ready checkpoint with an untold guide and the status command exits 1.
  • Why not higher: this is the architecture rung; delivery state is explicit rather than inferred from chat.
  • Follow-up: none.

Watcher lapse

Prevention

  • Class: failed to re-arm the fleet watcher after interruption, causing pushed heads to sit unnoticed for roughly two hours.
  • Instances: fixed monitor watch.sh, watcher.mjs, watcher state, and the orchestrator turn-end rule.
  • Search: rg -n 'watcher.json|watcher MISSING|lastTickAt|re-arm' plugins/vibe/skills/codex-fleet-monitor plugins/vibe/skills/fleet-orchestrator
  • Rung: 2 via watcher.mjs, which rejects missing, exited, dead, or stale watcher state.
  • Proof: watcher.test.mjs recreates each lapsed state and requires MISSING with exit 1.
  • Why not higher: a watcher is an external process whose death cannot be made impossible by types.
  • Follow-up: none.

UX ruling reached only one surface

Prevention

  • Class: delivered a settled UX ruling only to the writer who asked when several surfaces rendered the behavior, causing sibling hosts and QA plans to drift.
  • Instances: fixed fleet board.mjs, the shared reference delivery workflow, QA-plan requirements, and cross-writer prompt templates.
  • Search: rg -n 'kind ruling|reference|UNTOLD|QA plan|shared component' plugins/vibe/skills/fleet-orchestrator
  • Rung: 1 via one saved reference plus an explicit recipient set and per-recipient delivery state.
  • Proof: board.test.mjs recreates a three-recipient ruling and blocks until every writer and guide is told.
  • Why not higher: this is the architecture rung; the ruling and its distribution are one durable object.
  • Follow-up: none.

Writers lacked fleet context

Prevention

  • Class: launched writers without shared ownership/dependency state or direct messaging, causing conflicting work and hidden dependencies.
  • Instances: fixed fleet board.mjs, references/templates.md, and writer launch/status steps.
  • Search: rg -n 'Fleet board|board.mjs|dependencies|app-server-orchestrator.*send|SendMessage' plugins/vibe/skills/fleet-orchestrator
  • Rung: 1 via the durable fleet board supplied to every writer.
  • Proof: board.test.mjs recreates stale writer heads and untold dependencies and requires a failing status.
  • Why not higher: this is the architecture rung; shared coordination state is explicit.
  • Follow-up: none.

Critical-path checkpoint stayed local

Prevention

  • Class: kept a critical-path checkpoint unpushed during repeated review loops, causing QA to wait five hours and later findings to enlarge one risky batch.
  • Instances: fixed skills/vibe/scripts/push-cadence.mjs, commit receipts, fleet rules, and worker prompts.
  • Search: rg -n 'pushDue|90 minutes|unpushed|checkpoint' plugins/vibe
  • Rung: 2 via the push-cadence source gate and commit receipt.
  • Proof: push-cadence.test.mjs recreates an old unpushed diff and requires pushDue: true.
  • Why not higher: elapsed time and Git state are runtime facts.
  • Follow-up: none.

Unsafe process-group signal

Prevention

  • Class: group-signaled PID 1 after treating EPERM as ownership, causing every process owned by the operator to receive termination signals.
  • Instances: fixed fleet helpers.mjs, bounded runners, worker ledgers/dist, and every signal-test twin.
  • Search: rg -n 'process\.kill\(-|kill -- -|endProcesses|process\.pid|ppid' plugins/vibe tools/vibe-workers
  • Rung: 1 plus 2 via owned PID identity records, injected test signals, and test_vibe_signal_safety_contract.py static scanning.
  • Proof: helper tests recreate PID 0/1, EPERM, reused PIDs and foreign process groups; the static contract rejects an unguarded negative signal.
  • Why not higher: the owned identity model is the highest rung; the scan covers remaining raw signal call sites.
  • Follow-up: none.

Prototype catalog gate omission

Prevention

  • Class: changed prototype imports without running repository file-scanning gates, causing a PR to pass selected tests but fail the catalog gate on main.
  • Instances: fixed handoff path-gates.mjs, diff-rules.mjs, verify-worker instructions, and path-gate tests.
  • Search: rg -n 'path-gates|check-catalog-imports|file-scanning gates' plugins/vibe
  • Rung: 2 via .vibe/path-gates.json path matching and required evidence on the published head.
  • Proof: path-gates.test.mjs recreates a matching changed path with no declared gate result and rejects it.
  • Why not higher: repositories own arbitrary scanning commands, so a typed closed set would prevent extension.
  • Follow-up: none.

Stale RUNNING app-server state

Prevention

  • Class: trusted cached RUNNING state when the authoritative thread was idle, causing both turn-start and steer to refuse progress.
  • Instances: fixed skills/cl-sweep/scripts/native-app-server-orchestrator.mjs and its tests.
  • Search: rg -n 'reconcileSession|activeTurnId|RUNNING|threadStatus' plugins/vibe/skills/cl-sweep
  • Rung: 1 via reconciliation with authoritative thread state before the transition.
  • Proof: native-app-server-orchestrator.test.mjs recreates RUNNING plus idle/no active turn and requires turn-start to proceed.
  • Why not higher: this is the architecture rung; the transition derives from the authoritative state.
  • Follow-up: none.

Independent criteria audit ran after merge

Prevention

  • Class: scoped review to the writer's own plan and ran the independent criteria audit only after merge, causing eight acceptance misses to ship.
  • Instances: fixed handoff criteria-audit.mjs, handoff ordering, and criteria audit tests.
  • Search: rg -n 'criteria-audit|MET|PARTIAL|MISSED|fresh-context' plugins/vibe
  • Rung: 2 via a final-head CLI gate over every acceptance criterion.
  • Proof: criteria-audit.test.mjs recreates missing, PARTIAL, MISSED and stale-head rows and rejects each.
  • Why not higher: audit verdicts depend on review evidence, not compile-time structure.
  • Follow-up: none.

Criteria coverage matrix had empty cells

Prevention

  • Class: omitted criterion/surface/input/flag combinations from review and QA, causing pointer, host, and flag-state gaps to survive.
  • Instances: fixed criteria-audit.mjs matrix validation and handoff evidence rules.
  • Search: rg -n 'matrixProblems|surface x input x flag|no test or QA evidence' plugins/vibe
  • Rung: 2 via exhaustive Cartesian-cell validation.
  • Proof: criteria-audit.test.mjs removes one desktop-pointer cell and the check rejects it.
  • Why not higher: the dimensions come from each ticket and cannot be a repository-wide type.
  • Follow-up: none.

Flag-off behavior drifted from base

Prevention

  • Class: changed flag-off behavior without comparing it to the base, causing three parity regressions.
  • Instances: fixed criteria-audit.mjs, PR facts, verify-worker evidence, and host parity test selection.
  • Search: rg -n 'flag-off|no behavior change:|flagStates|parity' plugins/vibe/skills/handoff plugins/vibe/agents/vibe-verify-worker.md
  • Rung: 2 via required flag-off matrix cells and base-diff or sourced-ruling evidence.
  • Proof: criteria-audit.test.mjs recreates an unsupported looks the same flag-off claim and rejects it.
  • Why not higher: flags and affected surfaces are repository-defined runtime configuration.
  • Follow-up: none.

Diff-level audit misses

Prevention

  • Class: accepted removed host props, non-total comparators, agent-authored accessibility text and unused exports when reviewing a large diff, causing silent or dead behavior to merge.
  • Instances: fixed handoff diff-rules.mjs, review-gap-rules.mjs, parity-test selection, and source-provenance checks.
  • Search: rg -n 'comparator-tie|unused-export|copy-provenance|gridParityTests|capability-removal' plugins/vibe/skills/handoff/scripts
  • Rung: 2 for comparator, copy and export shapes; 3 for host/capability parity through enumerated tests.
  • Proof: diff-rules.test.mjs recreates missing tie fixtures, unused exports, uncited ARIA/copy and removed capabilities and rejects them.
  • Why not higher: a generic plugin cannot type product-specific host objects; repository TypeScript and parity tests own those semantics.
  • Follow-up: propose an AST-backed satisfies host-object rule if a repository exposes a stable host registry; no new parser/toolchain was added here.

Client/server capability parity

Prevention

  • Class: exposed a mutation to client row types the server rejects, causing offered actions to fail by entity type.
  • Instances: fixed criteria matrices, shared/host parity test selection, and verify-worker flag/host evidence.
  • Search: rg -n 'surface-capability-parity|host-capability-parity|gridParityTests|surface x input x flag' plugins/vibe
  • Rung: 3 via repository capability-parity tests required whenever the shared grid/adapter/mount changes.
  • Proof: handoff-inventory.test.mjs recreates a GridTableV2 change and requires all registered parity tests even when graph mapping omits them.
  • Why not higher: accepted entity types live in the target repository's client/server domain model, outside this plugin's type system.
  • Follow-up: target repositories should use one shared capability predicate where their architecture permits it.

Mid-work rulings missed ticket criteria

Prevention

  • Class: left operator rulings only in chat and QA records, causing later audits against ticket criteria to report deliberate decisions as misses.
  • Instances: fixed handoff rulings-check.mjs, ticket template, fleet ruling flow, and tests.
  • Search: rg -n 'rulings-check|Ruling <date>|amends:' plugins/vibe
  • Rung: 2 via the ticket/record reconciliation CLI.
  • Proof: rulings-check.test.mjs recreates a QA ruling absent from the ticket and rejects it.
  • Why not higher: the external ticket and transcripts are runtime documents.
  • Follow-up: none.

Remote writer received finding without evidence

Prevention

  • Class: sent a remote writer a prose-only QA finding while its story and screenshots stayed on another host, causing the writer to stall.
  • Instances: fixed fleet finding-brief.mjs, fleet.sh evidence transport, and tests.
  • Search: rg -n 'finding-brief|screenshots|evidenceDir|prompt.evidence' plugins/vibe/skills/fleet-orchestrator
  • Rung: 2 via input validation plus evidence copying before send.
  • Proof: finding-brief.test.mjs recreates missing route/viewport/evidence and refuses the prompt; the remote test proves the copied path exists.
  • Why not higher: evidence files and remote reachability are runtime resources.
  • Follow-up: none.

Precedent missed the disputed sub-question

Prevention

  • Class: answered a precedent headline without exercising the disputed interaction, causing the actual product conflict to remain unresolved.
  • Instances: fixed precedent-check.mjs behavior checklist, saved checklist artifact, quality loop, and tests.
  • Search: rg -n 'behavior|checklist.json|does not settle B' plugins/vibe/skills/vibe
  • Rung: 2 via required per-behavior evidence at report check time.
  • Proof: precedent-check.test.mjs recreates a headline-only and screenshot-less result and rejects both.
  • Why not higher: disputed interactions are supplied per question at runtime.
  • Follow-up: none.

Storybook completion falsely reported success

Prevention

  • Class: trusted storyFinished success when a play function threw, causing false-green Storybook verdicts.
  • Instances: fixed story-play-verdict.mjs, PR facts, verify-worker instructions, and tests.
  • Search: rg -n 'storyFinished|playVerdictProblems|exception|completion' plugins/vibe
  • Rung: 1 via a verdict derived from the complete event set rather than one ambiguous event.
  • Proof: story-play-verdict.test.mjs recreates a throwing play followed by storyFinished: success and requires FAIL.
  • Why not higher: this is the architecture rung; callers receive only the derived verdict.
  • Follow-up: none.

Shared-component fix regressed sibling hosts

Prevention

  • Class: applied a host-specific fix inside a shared component without testing every consumer, causing another host and existing stories to regress.
  • Instances: fixed handoff shared-consumers.mjs, diff rules, PR facts, verify-worker evidence, and tests.
  • Search: rg -n 'sharedComponentTests|every host|flagStates|shared-path' plugins/vibe
  • Rung: 2 via import/consumer enumeration and required per-host, per-flag test evidence.
  • Proof: diff-rules.test.mjs recreates a shared service/component change without every consumer suite and rejects it.
  • Why not higher: consumer ownership and flag modes are discovered from each target repository.
  • Follow-up: prefer a shared lower-level primitive while keeping genuinely host-specific policy in adapters.

Ticket statuses drifted from delivery evidence

Prevention

  • Class: left tickets in statuses that contradicted merged PRs, open PRs, and writer assignments, causing delivered or unowned work to be misrepresented.
  • Instances: fixed fleet status-audit.mjs, writer-assignment/merge steps, and tests.
  • Search: rg -n 'status-audit|UNOWNED|IN_REVIEW|merged PR' plugins/vibe/skills/fleet-orchestrator
  • Rung: 2 via evidence-to-status reconciliation at every assignment and merge.
  • Proof: status-audit.test.mjs recreates merged-not-DONE, assigned-backlog, and unfinished-unowned rows and rejects them.
  • Why not higher: ClosedLoop and GitHub status are external mutable systems.
  • Follow-up: none.

Lessons were split into stacked PRs

Prevention

  • Class: opened one stacked PR per lesson batch while a lessons PR was already open, causing conflicts, repeated CI and operator restacking work.
  • Instances: fixed fleet-orchestrator's lessons loop and the combined fix(vibe): ship combined 1.0.74 lessons release #334 release/body.
  • Search: rg -n 'one open PR per repo|one PR per lesson|lessons PR' plugins/vibe/skills/fleet-orchestrator
  • Rung: 4 via the owning lessons-loop rule, pinned by the 1.0.74 contract.
  • Proof: advisory rung; no proof possible without making the plugin mutate/query live PR topology during documentation work.
  • Why not higher: deciding whether two lessons are the same release concern requires scope judgment and live PR context.
  • Follow-up: none.

Long foreground work hid rulings

Prevention

  • Class: ran long commands in a worker's foreground when rulings were arriving, causing three orchestrator messages to remain unseen.
  • Instances: fixed fleet worker preamble and the second-unanswered-message escalation rule.
  • Search: rg -n 'more than a few minutes|inbox between steps|second unanswered' plugins/vibe/skills/fleet-orchestrator
  • Rung: 3 via test_vibe_1074_lessons_contract.py over every emitted worker preamble.
  • Proof: removing the background/inbox sentence made test_long_commands_do_not_hide_orchestrator_messages fail; restoring it passes.
  • Why not higher: command duration and message-boundary behavior belong to the external worker runtime.
  • Follow-up: none.

Storybook rule violations reached main

Prevention

  • Class: changed Storybook stories without enforcing the repository's release, placement, handler, component, controls and state-order rules, causing eight violation classes to merge green.
  • Instances: fixed storybook-rules.mjs, .vibe/storybook-rules.json example contract, diff rules, verify worker, and fix(vibe): run a repo's Storybook rules as handoff diff rules #335 corrections.
  • Search: rg -n 'storybook-rules|frozenRoots|noOpHandler|handRolledCells|literalOptions|storySupportPaths' plugins/vibe
  • Rung: 2 via repository-declared static diff rules and required Storybook checks.
  • Proof: storybook-rules.test.mjs recreates all eight violation classes and rejects each; fix(vibe): run a repo's Storybook rules as handoff diff rules #335 narrows list controls without weakening frozen-file rules.
  • Why not higher: Storybook taxonomy and release policy are repository configuration, not plugin types.
  • Follow-up: none.

Product questions skipped code feasibility

Prevention

  • Class: asked product whether impossible mutations should exist before checking schema and sync code, causing avoidable operator questions.
  • Instances: fixed session-questions.mjs, precedent-check.mjs, vibe quality loop/SKILL, requirements worker, README, and eval twins.
  • Search: rg -n 'code-evidence|Current code and data model|product question' plugins/vibe
  • Rung: 2 via session-questions.mjs ask --product --code-evidence <file:line> and the same evidence requirement at precedent launch.
  • Proof: a recreated product question without code evidence exited 1; session-questions.test.mjs pins the rejection.
  • Why not higher: the answer is evidence in an arbitrary target codebase, not a type available to the plugin.
  • Follow-up: none.

Idle writers' requests were not read

Prevention

  • Class: re-armed the watcher after writers became idle without reading their final messages, causing three actionable requests to wait about an hour.
  • Instances: fixed monitor liveness.mjs, classify.sh, monitor instructions, and operator-away reporting.
  • Search: rg -n 'NEEDS-REPLY|assistantTail|IDLE|attention.md' plugins/vibe/skills/codex-fleet-monitor plugins/vibe/skills/fleet-orchestrator
  • Rung: 3 via a watcher-output guard test that includes the final assistant lines and classifies trailing questions/permission requests.
  • Proof: replacing NEEDS-REPLY with ordinary LAST made the focused liveness test fail; restoring it passes.
  • Why not higher: whether prose asks for action requires message classification at runtime.
  • Follow-up: none.

In-scope VQA findings were deferred to an owner

Prevention

  • Class: labeled confirmed VQA findings on touched surfaces as the component owner's call, causing known defects in the delivered scope to remain unfixed.
  • Instances: fixed fleet QA rules, handoff VQA step, finding-brief.mjs closeout mode, and tests.
  • Search: rg -n 'touchedSurface|require-disposition|owner.s decision|already on main' plugins/vibe
  • Rung: 2 via required explicit scope classification and a handoff gate demanding fixed: <sha> or ticket: <id> for touched findings.
  • Proof: a recreated touched finding with no disposition exited 1; omission of touchedSurface also fails.
  • Why not higher: whether a visual finding touches the requested surface is a review judgment, but its disposition is mechanically enforceable.
  • Follow-up: none.

Program rulings were mixed into resume status

Prevention

  • Class: stored program rulings only among resume-log status entries, causing writers and auditors to lack one durable program specification.
  • Instances: fixed references/state.md, worker/QA templates, fleet.sh, and the rulings.md layout.
  • Search: rg -n 'rulings.md|Program rulings|resume-log' plugins/vibe/skills/fleet-orchestrator
  • Rung: 1 via a dedicated sourced rulings.md artifact automatically mirrored with every remote prompt.
  • Proof: finding-brief.test.mjs sends a remote prompt and requires the mirrored rulings.md to exist beside it.
  • Why not higher: this is the architecture rung; program rulings have one owned durable location.
  • Follow-up: none; per-ticket rulings remain owned by fix(vibe): criteria audit, rulings, evidence and e2e lane checks #332's rulings-check.mjs path.

Program rulings were not reconciled before audit

Prevention

  • Class: audited acceptance criteria without reconciling rulings from transcripts and QA records, causing deliberate decisions to look like misses.
  • Instances: fixed fleet audit step, state reference, and handoff rulings-check.mjs --program.
  • Search: rg -n 'rulings-check.mjs --program|operator message|AskUserQuestion|Before an audit' plugins/vibe
  • Rung: 2 via sourced program-entry syntax and record-to-index reconciliation.
  • Proof: a recreated unsourced program ruling and missing record ruling exited 1; focused tests pass with the sourced restored form.
  • Why not higher: transcript and ticket sources are external documents.
  • Follow-up: none.

Operator-away attention was not maintained

Prevention

  • Class: let actionable decisions and idle-writer requests remain scattered while the operator was away, causing blocked work and a poor return briefing.
  • Instances: fixed references/state.md, fleet reporting rules, and monitor idle-message output.
  • Search: rg -n 'attention.md|operator steps away|NEEDS-REPLY|lead with' plugins/vibe/skills/fleet-orchestrator plugins/vibe/skills/codex-fleet-monitor
  • Rung: 3 for surfacing actionable idle messages; 4 for the recommendation/blocking judgment in attention.md.
  • Proof: the watcher mutation proof fails when NEEDS-REPLY is removed; the attention format is advisory and cannot prove recommendation quality.
  • Why not higher: deciding what needs the operator and what it blocks requires orchestration judgment.
  • Follow-up: none.

High Claude usage was handled only after limit

Prevention

  • Class: waited for Claude workers to hit a hard limit before reducing their work, causing scarce budget to be spent on idle polling and noncritical continuations.
  • Instances: fixed fleet budget policy beside MOVE_AT_PERCENT and the 1.0.74 contract.
  • Search: rg -n 'high Claude usage|polling Claude|MOVE_AT_PERCENT|push a checkpoint' plugins/vibe/skills/fleet-orchestrator
  • Rung: 4 via the owning budget rule.
  • Proof: advisory rung; no proof possible because usage is reported by the operator and the correct migration depends on current work state.
  • Why not higher: the monitor has no authoritative Claude-usage API and budget triage requires judgment.
  • Follow-up: add a machine-readable Claude budget signal if the runtime exposes one.

Finding IDs collided across audits

Prevention

  • Class: reused short finding IDs such as F1 across audit reports, causing the operator to confuse decisions and fixes.
  • Instances: fixed references/templates.md, references/state.md, review-page-check.mjs, and tests.
  • Search: rg -n 'D###|X###|N###|S###|R###|review-page-check' plugins/vibe/skills/fleet-orchestrator
  • Rung: 2 via a review-page check for typed, unique IDs whose status matches the encoded kind.
  • Proof: a recreated F1/reused-ID review page exited 1; the test also rejects a typed ID with the wrong status.
  • Why not higher: Markdown review pages are runtime artifacts, not typed program values.
  • Follow-up: none.

Product-question research order was incomplete

Prevention

  • Class: used inconsistent research sequences across vibe, requirements, and fleet orchestration, causing code feasibility, product direction, prototype precedent, or live Asana to be skipped.
  • Instances: fixed skills/vibe/references/quality-loop.md, agents/vibe-requirements-worker.md, skills/vibe/SKILL.md, fleet principle 1, precedent CLI, README, and eval twins.
  • Search: rg -n 'Current code and data model|product owner.s recorded direction|approved prototype|Live Asana|code-evidence' plugins/vibe
  • Rung: 2 at question/precedent CLI boundaries, plus a single shared ordered-list source guarded by contract tests.
  • Proof: the CLI negative proofs reject missing code evidence and public-only precedent; the product-order Python contracts pass after sibling docs/evals are aligned.
  • Why not higher: sources are external evidence gathered in sequence, not values a static type can construct.
  • Follow-up: none.

Recovery owners pinned generator package versions

Prevention

  • Class: main-sync compared target-repository generator packages to plugin-pinned versions when the repository upgraded through its pnpm catalog, causing every affected publish to return NEEDS_CHANGE.
  • Instances: fixed Next, Prisma, Fumadocs, Geist and Husky owner declarations in main-sync-input-catalog.ts, the Next fixture, and rebuilt dist/main-sync.mjs.
  • Search: rg -n 'package: \\{[^}]*version|16\\.3\\.6|7\\.10\\.0|14\\.3\\.1' tools/vibe-workers/src/main-sync-input-catalog.ts plugins/vibe/skills/vibe/scripts/dist/main-sync.mjs
  • Rung: 1 via an owner architecture whose type cannot carry a plugin-pinned version; catalog-backed declarations resolve from the target pnpm-workspace.yaml, and other owners bind the target checkout's installed package.
  • Proof: with the old bundle, the new Next 16.4.1 catalog fixture failed with Installed producer contract changed: next-api; after rebuilding from the shared resolver it passes and records 16.4.1.
  • Why not higher: architecture/types are the highest prevention rung.
  • Follow-up: none.

Validation

  • Focused prevention suites: passed (33 Node tests and 30 Python contracts).
  • Negative proofs: product question without code evidence, public-only precedent, unresolved touched-surface VQA, unsourced program ruling, and invalid/reused review IDs all exited 1.
  • Mutation proofs: removing idle NEEDS-REPLY classification and removing the long-command background/inbox instruction each made its owning guard test fail; both were restored and pass.
  • Main-sync version proof: the old bundle rejected a target Next 16.4.1 catalog with Installed producer contract changed: next-api; the rebuilt bundle passes both catalog and installed-package 16.4.1 fixtures, and the complete input-boundary file passes 63/63.
  • Full repository suites: ruff and pyright pass; pytest passes 2,435 with 3 skipped; plugin Node passes 661/661; plugin-manifests 6/6, design-inventory 393/393, code-review-cost 43/43 and guided-manual-qa 50/50 pass with reproducible builds. The process-heavy vibe-workers monolith completed 737/751 under laptop load with 14 timeouts confined to three files; those complete files pass alone through the heavy slot (63/63, 24/24 and 7/7), typecheck passes and the rebuilt dist is clean.
  • Automatic GitHub CI: all 10 checks pass on 6c8f1b719191177898579ad25d3e6a9b5ad635a4.

- A helpers.test.mjs run recorded pid 1 and stopped it; endProcesses
  counted EPERM as alive and sent kill(-1), which signals every process
  the user owns. It ended every app on the operator's machine twice.
- helpers.mjs refuses to record a pid of 1 or lower. endProcesses never
  probes or signals one, nor its own or its parent's pid. It signals a
  whole group only for a pid recorded with --group whose pgid still
  equals the pid, and never signals a pid that EPERM says is not ours.
  It takes an injected kill, so its tests send no real signal.
- Every other group signal (run-bounded, precedent-check, the
  vibe-workers ledger and Claude worker, two tests) checks the pid
  above 1 first; dist rebuilt.
- test_vibe_signal_safety_contract.py fails when a plugin test signals
  0, 1, a negative literal or its own pid, writes one into a pids
  ledger, or calls endProcesses without a fake kill, and when any
  source signals a group without checking the pid above 1.
- The cli-worker fake Codex ends with process.abort() instead of
  signalling its own pid.

Testing: node --test, pytest, ruff, pyright and the vibe-workers
vitest and build on a second machine; each safety check shown failing
with its fix removed.
Risks: a helper started without --group now has only its own pid
signalled, so children it spawned in another group need their own
recorded pids.
- fleet-orchestrator: board.mjs keeps the fleet board, flags rows
  behind the pushed head, and tracks rulings and ready QA checkpoints
  until every writer and QA guide is told directly. qa-plan-check.mjs
  defaults to zero human checkpoints. helpers.mjs records and ends a
  helper's processes, lists orphans, and keeps a handed stack from QA
  reruns.
- codex-fleet-monitor: watch.sh writes watcher.json and watcher.mjs
  reports a lapsed watcher; the supervisor template restarts with
  bootout then bootstrap and throttles 30 seconds.
- vibe: push-cadence.mjs and pushDue on every commit, shepherd.mjs for
  the final stage, main-sync-push refuses out-of-order migrations,
  e2e-lock.mjs gives each run its own compose project, and
  precedent-check.mjs check refuses an answer no live look settled.
- handoff: repo-declared path gates (.vibe/path-gates.json) become
  required runs on the published commit.
- Skill prose points at each check; vibe 1.0.74 and its changelog.

Testing: node --test, pytest, ruff, pyright and the vibe-workers
vitest and build on a second machine.
Risks: None identified; every new check is additive and a repo
without .vibe/path-gates.json requires no gate.
- The fleet skill's generic test reads QA-001 as a ticket id; the
  check accepts any checkpoint id, so the fixtures use C1 to C8.

Testing: qa-plan-check, board and generic tests on a second machine.
Risks: None identified.
- A recorded pid can be handed to one of the user's own apps after
  the helper exits; probe() saw it as alive, and a launchd app leads
  its own group, so stopped would have killed it.
- pid records each process's start time and command and refuses one
  it cannot read; endProcesses re-reads them before every signal and
  treats a mismatch, an unreadable value or an older record without
  identity as not ours. The ps reader is injected like groupOf.
- run-bounded's group test waits, bounded, for the killed grandchild
  to be reaped before asserting it is gone.

Testing: helpers and run-bounded tests on a second machine; making the
identity check always pass fails all four identity tests.
Risks: a process that execs into another command after it is recorded
is no longer signalled by stopped; record the final process instead.
- turn-start on a RUNNING record whose thread is idle reconciles
  against the live thread before starting, instead of refusing.
- handoff: criteria-audit.mjs (fresh-context MET audit on the final
  head, criteria x surface x input x flag matrix, flag-off parity) and
  rulings-check.mjs (every ruling on the ticket with what it amends);
  qa-merge-order.mjs --evidence needs each changed e2e spec passing at
  the head in its lane; diff rules for comparators without a tie test
  and new exports nothing uses.
- precedent-check.mjs --behavior makes each disputed behavior a
  required checklist item.
- fleet-orchestrator: finding-brief.mjs refuses findings without
  evidence and fleet.sh ships the screenshots with the prompt.
- vibe 1.0.75 and its changelog.

Testing: node --test and pytest over the plugins on a second machine.
Risks: the unused-export rule blocks a handoff that adds an export
nothing names until it is removed or recorded with Export:.
- The operator ruled that skipping pre-merge e2e was a deliberate
  trade for a deadline, not a standing plugin rule, so the check,
  its prose and its changelog line come out.

Testing: qa-merge-order tests and the vibe contract tests on a second
machine.
Risks: None identified.
- story-play-verdict.mjs passes a play only when its completion was
  observed and no exception or error event fired; storyFinished's
  status reported success for a play that threw. The evidence gate
  needs playVerdicts, all PASS, on the storybook-plays run.
- A changed UI component two or more hosts import requires every test
  and story covering it or a host, in both flag states when the
  change reads a flag, and blocks until the change log records the
  host the behavior is keyed on.
- vibe 1.0.76 and its changelog.

Testing: node --test (651 of 651) and pytest (2554) over the plugins
on a second machine.
Risks: a shared component change now needs every host's suites run
before a pull request opens.
- status-audit.mjs reads a snapshot of each in-scope PRD's children:
  a merged pull request means DONE, an open one or an assigned writer
  means IN_PROGRESS or IN_REVIEW, and neither means UNOWNED. It fails
  until each mismatch is fixed or ruled out of scope with a reason.
- The fleet skill runs it at every writer assignment and every merge.
- vibe 1.0.77 and its changelog.

Testing: node --test (654 of 654) and pytest (2555) over the plugins
on a second machine.
Risks: None identified; the audit reads a snapshot and changes nothing.
- storybook-rules.mjs reads .vibe/storybook-rules.json and blocks a
  story change with a missing or too-low Storybook release, a reused
  release version, new stories under a frozen root, an edit handler
  wired to a no-op, a hand-rolled table row or cell, a touched story
  with no controls decision, a lifecycle tag outside its roots, a
  computed options list, and a story-local copy of a deleted
  component. Every repo fact lives in the declaration.
- The declaration's checks become required tests whenever a story
  changes, so the evidence gate needs a passing run of each.
- An example declaration (symphony-alpha's), vibe 1.0.78 and its
  changelog.

Testing: each rule flags the real diffs of symphony-alpha #8953,
#8959, #8960, #8962, #8963 and #8980; removing any rule fails its
unit test.
Risks: a repo that adds the declaration blocks story changes that
skip a release until it is cut or a ruling is recorded.
…iles

- story-computed-options counts an options value only in an argTypes
  entry with a select, radio or check control. A prop named options
  ({ control: false }) and an options value under args no longer
  match (symphony-alpha #9102).
- story-no-op-handler skips files under the frozen roots: a v1.0 file
  restored to its earlier bytes keeps its handlers.

Testing: #9102's diff gives only its computed options finding and
#9104's gives none; each new condition fails a fixture when removed.
- Fold all lesson contracts and release notes into one release
- Encode program rulings, attention, budget, VQA, and review IDs
- Remove the deadline-only final-merge E2E exception

Testing: focused vibe 1.0.74 and signal-safety contracts pass

Risks: New orchestration guidance may surface more required fixes
@shafty023 shafty023 changed the title fix(fleet-orchestrator): audit ticket statuses against their evidence fix(vibe): ship combined 1.0.74 lessons release Oct 22, 2026
@shafty023
shafty023 changed the base branch from fix/vibe-lessons-20261021d to main October 22, 2026 01:18
- Preserve the single vibe 1.0.74 release entry
- Include the judges removal and code 2.0.1 changes from main

Testing: Full repository validation follows on the merged head

Risks: Main removes the deprecated judges plugin as already shipped
- Keep confirmed findings on the same writer
- Extend the rule to pre-existing findings on touched surfaces

Testing: 17 focused handoff and combined-release contracts pass

Risks: None identified
- State that confirmed findings on touched surfaces are fixed
- Keep the change within the single vibe 1.0.74 entry

Testing: 17 focused handoff and combined-release contracts pass

Risks: None identified
- Check feasibility and sourced decisions before precedent
- Use live Asana through the actor with the signed-in browser
- Return unresolved browser work to the fleet orchestrator

Testing: 29 product-question and combined-release contracts pass

Risks: Product questions may wait when no signed-in browser is available
- Gate product questions, live precedent, VQA dispositions, rulings, and review IDs
- Surface idle-worker questions and mirror program rulings to remote writers
- Align docs and eval twins with the enforced contracts

Testing: focused Node and Python contract suites; negative and mutation proofs

Risks: workflow inputs now require explicit evidence and dispositions
- Avoid ticket-shaped values in fleet-orchestrator test fixtures
- Preserve VQA disposition and remote rulings coverage

Testing: generic guard and app-server recovery black-box tests

Risks: None identified
- Keep the combined 1.0.74 entry aligned with its guard coverage

Testing: generic guard and app-server recovery black-box tests

Risks: None identified
Restore the settled-decision and narrow-layout instructions while keeping live Asana as the only precedent source.

Testing: 54 focused Python contract tests

Risks: None identified
Read catalog-backed generator versions from the target workspace and bind other owners to the installed package instead of plugin pins.

Testing: 63 main-sync input-boundary tests; negative proof against old bundle; vibe-workers typecheck

Risks: catalog changes now participate in producer input identity
@shafty023
shafty023 merged commit 098915f into main Oct 22, 2026
10 checks passed
@shafty023
shafty023 deleted the fix/vibe-lessons-20261021e branch October 22, 2026 03:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant