Skip to content

fix(vibe): ship 1.0.78, one fleet home and the open 10-22 lessons - #340

Merged
shafty023 merged 7 commits into
mainfrom
fix/vibe-lessons-1078
Oct 22, 2026
Merged

shafty023 merged 7 commits into
mainfrom
fix/vibe-lessons-1078

Conversation

@shafty023

@shafty023 shafty023 commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Purpose

Ships vibe 1.0.78: the fleet runs from one fleet home, so a new orchestrator chat finds everything it should reuse in one place and a new program sees nothing of an earlier one's state, plus every open 2026-10-22 lesson that was not yet fixed. Each lesson gets the highest rung that can catch it, shown failing on the old code. The branch already held the 1.0.77 word-count fix and instruction-words.mjs.

Release metadata

  • One changelog entry: vibe v1.0.78 (already bumped on this branch in both manifests).
  • Contract coverage: plugins/vibe/tools/python/test_vibe_1078_lessons_contract.py.
  • Net instruction length since 1.0.77 (fix(vibe): ship the 1.0.77 lessons release and prose trim #339): Markdown under plugins/vibe is about 7 words shorter (2,451 added, 2,458 removed), measured at the head with instruction-words.mjs --base 8f562ab --changelog CHANGELOG.md --version 1.0.78. Prose the new scripts enforce was trimmed; every phrase the contract tests pin is kept.

Fleet home design

  • <fleetHome> (FLEET_HOME, default ~/fleet-orchestrator): reusable files at the top (config.env, standing-rulings.md, lessons.md, handover.md, current), each program under programs/<slug>/ (resume log, program rulings, attention, prs.txt, sessions/, prompts/, findings/, board, monitor state, evidence).
  • The seam is codex-fleet-monitor/scripts/work-dir.mjs, not a new argument on every script: each script that takes <orchDir>/<workDir> (fleet.sh, board, helpers, finding-brief, watch.sh, snapshot.sh, supervise, watcher, claude-usage) resolves a home to its active program and derives LOCAL_STATE_DIR, REQUESTS_DIR and, with REMOTE_FLEET_HOME, the remote dirs per program. A flat dir still works, so the change is backward compatible; shells eval one generated snippet so there is one implementation.
  • fleet-orchestrator/scripts/fleet-home.mjs: start (refuses while another program is current), close, resume (reading order, RELAUNCH <writer> <prompt> for Claude writers, WATCHER-LIVE <pid> for the lock handoff), check, migrate (in place, repoints symlinks beside and inside the dir, refuses while a watcher holds the lock).

Prevention closeouts

A new orchestrator chat inherited only part of the program

Prevention

  • Class: orchestration state was written wherever a tool defaulted (resume log and ledger beside the work dir, Codex state from app-server-orchestrator in other dirs), so a new chat could not find it and nothing kept programs apart.
  • Instances: fixed fleet.sh, board.mjs, helpers.mjs, finding-brief.mjs, watch.sh, snapshot.sh, supervise.sh/.mjs, watcher.mjs, claude-usage.mjs; state, setup and monitor docs.
  • Search: rg -n "config.env|<orchDir>|<workDir>" plugins/vibe/skills/{fleet-orchestrator,codex-fleet-monitor}/scripts
  • Rung: 3. board.mjs status (run with every monitor event) fails with FLAT, OUTSIDE, CONFIG, SHARED-REMOTE, UNMANAGED (a sessions.txt session fleet.sh did not start; remote turns leave <name>.remote.json) and UNMANAGED-STATE; a contract test fails when any script taking a work dir does not resolve it through work-dir.mjs.
  • Proof: the new board test fails on the old board.mjs; the fleet.sh home test fails on the old fleet.sh; the contract test fails on the old watch.sh.
  • Why not higher: sessions started by another skill cannot be prevented from this plugin; the check reports them.
  • Follow-up: none. Event recorded: vibe lessons ledger.

#9116 merged with Desktop E2E reds its pre-PR lanes skipped

Prevention

  • Class: pre-pr-lanes.mjs skipped e2e lanes by default and could not read a lane line starting with the step's variables (DESKTOP_E2E_SPECS='...' pnpm ...), so the lane the report named was never required.
  • Instances: fixed vibe/scripts/pre-pr-lanes.mjs; --skip now needs --skip-ruling (deadline mode).
  • Rung: 3 via pre-pr-lanes.test.mjs with an env-prefixed desktop e2e line.
  • Proof: both lane tests fail on the old script.
  • Why not higher / Follow-up: the web e2e lane and a visual-baseline check for grid column changes are not in symphony-alpha's pnpm test:lanes report; that report is the repo's own (it already names desktop-e2e), so naming the web e2e lane there is a symphony-alpha follow-up, after which this check requires it with no plugin change.

Another author's PR was enqueued under the operator's account

Prevention

  • Class: auto-merge was armed on a PR a worker misattributed to the fleet.
  • Instances: fixed by a new PreToolUse hook hooks/merge-guard.mjs (shared command parsing moved to hooks/command-segments.mjs, also used by kill-guard).
  • Rung: 2 (hook refuses gh pr merge when the PR author is not the signed-in account, unless MERGE_AUTHOR_OK=<author>).
  • Proof: removing the author comparison fails both merge-guard tests.
  • Why not higher: Codex has no plugin hook.

Watcher discovery picked up a PR another chat owned (#9058)

Prevention

  • Class: PR auto-discovery added every open PR by the gh account, including ones another chat shepherds.
  • Instances: fixed codex-fleet-monitor/scripts/snapshot.sh: a PR in prs-ignore.txt or in another program's prs.txt in the same fleet home is never added or reported, so never STALE-PR, even when listed by hand.
  • Rung: 3 via snapshot.test.mjs. Proof: the new test fails on the old snapshot.sh and on this PR's earlier add-only version.

R-SINGLE-REVIEW retired once core work is done

Prevention

  • Class: the single review round was written as permanent, so after a program's delivery phase valid later-round findings would still be deferred to follow-up tickets.
  • Instances: fixed vibe/scripts/shepherd.mjs (--round-one-fixed-at needs --single-review-ruling), vibe/scripts/review-followup.mjs (plan needs it), handoff/scripts/review-threads.mjs (a later result needs singleReviewRuling); fleet, vibe and handoff SKILL text.
  • Rung: 3 via the three suites. Proof: each fails on its previous script.

Review bots treated as human reviewers; green-watch model split; e2e before merge; intended change filed as a regression

Prevention

  • Class: rulings that need judgment (R-REVIEW-BOTS, green-watch Sonnet watcher plus Opus fixer, R-E2E-BEFORE-MERGE, R-INTENDED-CHANGE: read the causing PR's ticket, PRD and design rulings before filing another author's red).
  • Rung: 4, fleet-orchestrator SKILL.md (review-round bullet, green-watch bullet), pinned by the contract test. Advisory rung, no proof possible.
  • Why not higher: who wrote a review comment cannot be told from its login (bots post as teammates), and choosing a model or running e2e on main early are orchestration choices; the e2e fix PR gate is partly mechanical through the e2e lanes pre-pr-lanes.mjs now requires.

Green-watch fixes skipped the gates a vibe writer passes

Prevention

  • Class: the green-watch fixer opened PRs outside vibe, so none of vibe's PR gates ran: a 73-character title failed the metadata gate (#9188), a "pixel-identical" baseline was about 3,900 pixels off (#9186), a changed literal stayed in another spec, a locator was widened to a non-unique match, an author was misattributed, and "23/23 passed" was reported for a commit never tested.
  • Instances: new vibe/scripts/pr-preflight.mjs (title with (#n) at most 72; an identical/matches claim needs its measured count), run by the environment worker before a PR opens; new vibe/scripts/tested-head.mjs, used by pre-pr-lanes.mjs run|record --head and e2e-lock.mjs run --head (refuse another HEAD or a modified tracked file, fail when HEAD moves mid-run); fleet green watch: the fixer is a vibe writer and attributes from gh pr view --json author,headRefName; guardrails reviewer: a changed literal whose old value remains, and a widened non-unique locator.
  • Rung: 3 for the preflight and tested-head checks; 2 for the act of merging another author's PR (merge-guard above); 4 for the literal sweep, locator scope and attribution wording.
  • Proof: removing either preflight check fails all 3 pr-preflight.test.mjs cases; the new pre-pr-lanes and e2e-lock head tests fail on the previous scripts.
  • Why not higher: an old value that the change itself replaced is judged by the reviewer, since a literal sweep cannot tell a semantic leftover (e.g. two initials vs one) from an unrelated string. Follow-up: the operator's machine-local e2e-slot.sh wrapper should call e2e-lock.mjs run --head or tested-head.mjs; it is not in this repo.

A preservation phrase enabled and protected an unsourced control

Prevention

  • Class: a valid control prop was newly enabled on a surface from a broad preservation phrase, then baseline regeneration blessed the unsupported element without a human source naming that control on that surface.
  • Instances: fixed the vibe change writer, handoff diff rules, guardrails reviewer, verify worker, environment worker PR preflight, handoff visual QA, and fleet green watch.
  • Search: verified PR #8962 added onSelectAll and showSelectAll to Branches, PR #9116 moved the star column, and PR #9188 accepted the checkbox into the baseline; checked live ISS-12683, ISS-9324, ISS-9461, ISS-12918, and ISS-13007.
  • Rung: 3. diff-rules.mjs requires a surface-specific Control: citation for newly enabled control props or mounts. visual-baseline-ledger.mjs and pr-preflight.mjs require a counted, sourced Baseline element: ledger for every changed visual baseline.
  • Proof: with the new calls removed, the #8962-shaped control test and both #9188-shaped baseline tests fail; the restored implementation passes all 32 focused Node tests.
  • Why not higher: rung 1 accepted the valid typed props and rung 2 accepted valid syntax; #8962 passed both. Product authority is external to the type system, so rung 3 is the highest mechanical gate, backed by guardrails review and rendered-control QA.
  • Follow-up: none. Event recorded: vibe v1.0.78 changelog.

Migration for an existing flat work dir

Stop the watcher for that dir first (the command refuses while it holds watch.lock), then:

node <plugin>/skills/fleet-orchestrator/scripts/fleet-home.mjs migrate --from <flat dir> --program <slug> --dry-run
node <plugin>/skills/fleet-orchestrator/scripts/fleet-home.mjs migrate --from <flat dir> --program <slug>

Then copy the rulings that bind every program into standing-rulings.md (SPLIT-RULINGS), set FLEET_HOME, and run fleet-home.mjs check.

Commands run

  • Node suite: 748 passed in the broad run; 2 unrelated App Server concurrency tests hit EPIPE and registry-lock races, then both files passed in isolation (3 tests). The 32 touched-script tests pass.
  • uv run pytest plugins/: 2475 passed, 3 skipped. uv run ruff check . and uv run pyright: clean.
  • instruction-words.mjs --base 8f562ab --changelog CHANGELOG.md --version 1.0.78: net -7, passes.
  • Migration rehearsed on a scratch copy of a live work dir (dry run and real run, then check and resume).

Risks

  • e2e-lock.mjs run and pre-pr-lanes.mjs record now need --head and a clean tracked tree.
  • gh pr merge on another author's PR needs MERGE_AUTHOR_OK=<author> in every Claude session with the plugin.
  • A flat work dir that watches sessions or PRs now fails board.mjs status with FLAT-LAYOUT until migrated.

- The 1.0.77 changelog said about 930 words shorter; the merged change
  is about 830 shorter. The count was taken before the last commits.
- instruction-words.mjs measures net Markdown words between two refs
  and, with --changelog, fails an entry whose stated number does not
  match; the lessons loop runs it at the final head.
- vibe 1.0.78.

Testing: instruction-words.test.mjs; the old 1.0.77 entry fails the
check against the merged release; vibe contracts.
Risks: None identified.
- One fleet home holds what every orchestrator chat reuses (config,
  standing rulings, lessons ledger, handover, current program) and each
  program's state under programs/<slug>/. fleet-home.mjs starts, closes,
  resumes, checks and migrates; work-dir.mjs resolves the home for every
  fleet and monitor script and derives the state dirs per program.
- board.mjs status fails on state written outside the home, including a
  session fleet.sh did not start. A new chat once inherited only part of
  a program.
- hooks/merge-guard.mjs refuses gh pr merge on another author's pull
  request until the operator approves it.
- pre-pr-lanes.mjs requires e2e lanes the report names and reads lane
  lines with leading variables; --skip needs --skip-ruling.
- fleet-orchestrator: review bots post under teammates' accounts; green
  watch splits a Sonnet watcher from an Opus fixer; full e2e on main
  before batches find the reds. Prose trimmed to stay under 1.0.77.

Testing: fleet-home, board, fleet, merge-guard and pre-pr-lanes suites,
each failing on the old code or with its check removed; all vibe node
suites; vibe contracts; migration rehearsed on a copy of a live dir.
Risks: gh pr merge on another author's PR now needs MERGE_AUTHOR_OK; a
flat work dir that watches PRs fails board.mjs status until migrated.
- snapshot.sh discovery never adds a PR listed in prs-ignore.txt or in
  another program's prs.txt in the same fleet home. Discovery once put
  a PR another chat was shepherding in this fleet's watch set.
- Green watch files another author's red only after that PR's ticket,
  PRD and design rulings show the change was not asked for.
- Changelog word count at the head: about 5 words shorter than 1.0.77.

Testing: snapshot.test.mjs, failing on the old snapshot.sh; all node
suites; vibe contracts; instruction-words --changelog.
Risks: None identified.
- The single review round holds only in a program's delivery phase.
  Once core work is done it is retired and every valid finding is
  fixed in its pull request, every round: shepherd.mjs
  --round-one-fixed-at, review-followup.mjs plan and a later result in
  review-threads.mjs need the single-review ruling in force.
- snapshot.sh never reports a PR in prs-ignore.txt or another program's
  prs.txt, so another chat's PR is never STALE-PR here.
- Green watch cites a requested change instead of filing it.
- Prose trimmed; Markdown about 2 words shorter than 1.0.77.

Testing: shepherd, review-followup, review-threads and snapshot suites,
each failing on the previous scripts; all node suites; vibe contracts;
instruction-words --changelog.
Risks: deferring a later review round now needs the ruling named.
- tested-head.mjs: a run starts only at the intended HEAD with no
  modified tracked file. pre-pr-lanes.mjs run records a lane under the
  SHA it tested, record needs --head, and e2e-lock.mjs run needs --head;
  both fail when HEAD moves mid-run. A container once tested an old
  commit for an hour and passes were reported for an untested PR.
- pr-preflight.mjs: the title with " (#n)" fits 72 characters and an
  identical or matching claim carries its measured count; the
  environment worker runs it before opening a PR.
- The green-watch fixer is a vibe writer, attributing reds from gh; the
  guardrails reviewer blocks a changed literal left elsewhere in the
  repo and a widened, non-unique test locator.
- Prose trimmed; Markdown about 7 words shorter than 1.0.77.

Testing: pre-pr-lanes, e2e-lock and pr-preflight suites, each failing
on the old scripts or with the check removed; all node suites; vibe
contracts; instruction-words --changelog.
Risks: e2e-lock run and pre-pr-lanes record now need --head and a
clean tracked tree.
- The busy test's holder shared the run's worktree, so on Linux, where
  the temp dir is not a symlink, the run read as a duplicate (76), not
  busy (75). The test root is now resolved like the worktree, and the
  holder names its own worktree.

Testing: e2e-lock.test.mjs, reproducing the CI failure locally first.
Risks: None identified.
- Gate newly enabled controls and visual baseline elements on surface-specific requirement citations
- Inventory rendered controls during guardrails review, handoff, verification, and green watch
- Add regression coverage for the 8962 and 9188 failure shapes

Testing: Node tests, pytest, Ruff, and Pyright

Risks: Citation matching intentionally fails closed
@shafty023
shafty023 merged commit 2ec2904 into main Oct 22, 2026
10 checks passed
@shafty023
shafty023 deleted the fix/vibe-lessons-1078 branch October 22, 2026 23:54
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