docs(plans): refactor-to-next merge plan and lead decision 66 (sage)

Jason's 2026-10-08 rulings via Mos (thread 1eba59e5). R10: next stays
the trunk; the plan pins refactor b8db39cf and next 2101c9b4, finds a
clean merge-tree, and names the CI gate, approval identity, frozen
next-lane publishing, root .mosaic/repo.json, 13 stale v1 PRs and the
hardcoded ledger branch as the work. Nothing merged.

R8: Path A on the new estate Vikunja meets slice 1 and replaces
decision 61's Path B. The runbook's Path A text names the estate
instance and the share-only isolation rule.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-08 16:53:57 -05:00
co-authored by Claude Opus 5.5
parent b8db39cf1e
commit ba51c8d867
4 changed files with 212 additions and 0 deletions
+11
View File
@@ -510,3 +510,14 @@ are never rewritten or removed; corrections are new entries.
- 2026-10-05 | rocko | row 37 review opening, lead decisions 62/63 | Opened review at rev 126; expected credential-free post failure recorded at rev 127; README documents cooperative proof escape and S6 isolation obligation; no commit. - 2026-10-05 | rocko | row 37 review opening, lead decisions 62/63 | Opened review at rev 126; expected credential-free post failure recorded at rev 127; README documents cooperative proof escape and S6 isolation obligation; no commit.
2026-10-05T21:49:40Z | Dewey (T3 Claude Code, thread 84fb346c) | row 40 S5 #1522, lead decision 63 | recorded LD63 routing of the gap list; verify against the S2 round 2 candidate files (manifest 61519059, broker aa5efbbf): 15 checks 0 failed, check 16 equal on 203 rows; check 16 pin waits for Sage's commit; nothing committed 2026-10-05T21:49:40Z | Dewey (T3 Claude Code, thread 84fb346c) | row 40 S5 #1522, lead decision 63 | recorded LD63 routing of the gap list; verify against the S2 round 2 candidate files (manifest 61519059, broker aa5efbbf): 15 checks 0 failed, check 16 equal on 203 rows; check 16 pin waits for Sage's commit; nothing committed
2026-10-05T22:16:03Z | Sage (T3 Claude Code, thread 1ef1e4f8) | S1 and S2 integration | S1 at 2d64c71e (row 36 done) and S2 at 38828a2c (row 37 done) after integration gates in git worktrees, all suites green with live cases; row 43 S2b brief and #1525 2026-10-05T22:16:03Z | Sage (T3 Claude Code, thread 1ef1e4f8) | S1 and S2 integration | S1 at 2d64c71e (row 36 done) and S2 at 38828a2c (row 37 done) after integration gates in git worktrees, all suites green with live cases; row 43 S2b brief and #1525
- 2026-10-05 | rocko | S2b row43 / #1525 candidate | 48/48 Node24+26; two mutants killed; eight script suites green, task 26/2 under Docker-disabled live-case boundary; review opened rev136, expected token-free post failure rev137; no commit.
2026-10-05T22:23:19Z | Dewey (T3 Claude Code, thread 84fb346c) | row 40 S5 #1522, check 16 pin | check 16 reads packages/bus from commit 38828a2c via git archive (broker aa5efbbf, store e69cb395, schema 179ffe35); verify 15 checks 0 failed 2 N/V, 203 rows equal; 6 stand-in mutants killed; nothing committed
- 2026-10-05 | rocko | row43 S2b R2, lead decision64 | Shared consumption for all three paths; class-drift refusal; 55/55 Node24+26, six mutants; review opened rev142/request failed expected rev143; no commit.
2026-10-05T22:56:12Z | Dewey (T3 Claude Code, thread 84fb346c) | row 40 S5 #1522, S2b repin | check 16 repinned to 4afab552 (broker 44c161c2), verify 15/0 failed/2 N/V, 203 rows equal; finding: S2b refuses an agent message citing its decision (decision-mismatch), reproduced on both commits; SLICE1-VIEWS section 10; reported to Sage; nothing committed
2026-10-05T22:58:30Z | Dewey (T3 Claude Code, thread 84fb346c) | row 40 S5 #1522, lead decision 65 | recorded LD65 (decision citation on within-role message.send, S2c row 44); fixture 101/102 kept; waiting for S2c to repin check 16 and update section 10; nothing committed
- 2026-10-05 | rocko | row44 S2c / #1526 | Within-role citations preserved without consumption; README evidence wording fixed; 58/58 Node24+26, three mutants; eight suites pass, task26/2 Docker-disabled; review opened rev151, expected token-free post failure rev152; no commit.
2026-10-05T23:18:04Z | Dewey (T3 Claude Code, thread 84fb346c) | row 40 S5 #1522, S2c repin | check 16 repinned to d27042fa (broker 51e03b33), verify 15/0 failed/2 N/V, 203 rows equal; probe confirms LD65 on d27042fa (citation stored, not consumed); fixture adds message.send action.allowed for 101/102; SLICE1-VIEWS.md section 10 says S2c restores them; no commit.
2026-10-08T21:53:57Z | Sage (T3 Claude Code, thread 1ef1e4f8) | Mos 1eba59e5, Jason R1/R5/R8/R10/R17 | merge plan docs/plans/2026-10-08_refactor-to-next-merge-plan.md (pinned b8db39cf/2101c9b4, merge-tree clean); lead decision 66 (next trunk, estate Vikunja Path A replaces LD61 Path B, R1 defaults); runbook Path A text; nothing merged
+10
View File
@@ -106,11 +106,21 @@ that is yours.
### Path A, an existing instance ### Path A, an existing instance
Mosaic Stack uses this path on the estate instance (lead decision 66).
Set `VK` to its HTTPS base URL. Don't use tasks.setspark.io.
Check that `curl -s "$VK/api/v1/info"` reports `v2.7.0` or later. Use your Check that `curl -s "$VK/api/v1/info"` reports `v2.7.0` or later. Use your
existing account as the owner. existing account as the owner.
The estate instance also holds Launchpad, personal and system projects.
A bot sees only the projects shared with it, so section 3 shares the
`mosaic-stack` project and nothing else. Never share another project
with a `bot-mosaic-stack-*` user.
### Path B, the bundled instance ### Path B, the bundled instance
Other installs can use this path. Mosaic Stack's own install doesn't.
Row S3 ships `packages/tasks/deploy/vikunja/` for this. Until it lands, Row S3 ships `packages/tasks/deploy/vikunja/` for this. Until it lands,
these commands start the same pinned image the probes used, bound to these commands start the same pinned image the probes used, bound to
127.0.0.1: 127.0.0.1:
+37
View File
@@ -1140,3 +1140,40 @@ which stay with him. Each item names who decided it and what happened.
the policy can express. Role authority has no per-target entries, the policy can express. Role authority has no per-target entries,
so the broker classifies `message.send` by the sender's role so the broker classifies `message.send` by the sender's role
alone. S2c does that, and that's the rule. alone. S2c does that, and that's the rule.
66. **Jason's 2026-10-08 rulings for the stack: `next` stays the trunk,
Mosaic Stack uses the estate Vikunja, and non-gated defaults apply
at their deadline (2026-10-08).** Source: Mos, thread 1eba59e5,
relaying Jason's rulings R1, R5, R8, R10 and R17. Mos's lane state
file holds the full list.
- R10: the trunk stays `next`, and `refactor` merges into it. The
plan is `docs/plans/2026-10-08_refactor-to-next-merge-plan.md`.
Nothing is merged. `next`'s `.mosaic/repo.json` already names
`next` as the integration trunk, so no record contradicts the
ruling. `refactor` has no root `.mosaic/`; the plan adds one.
- R8: one new estate Vikunja 2.7.x instance serves Mosaic Stack,
Launchpad, personal and system projects. SetSpark stays on
tasks.setspark.io. Path A on that instance meets slice 1, so row
35 uses Path A there, and this replaces decision 61's Path B
bullet. Decision 61 chose Path B to keep slice 1 off SetSpark's
instance, and R8 keeps that separation.
- Isolation comes from shares. A bot sees only projects shared
with it, and the runbook shares only `mosaic-stack`. The bot
names, `bot-mosaic-stack-<role>`, already avoid collisions with
a second business on the same instance.
- S3's probes still run on a scratch container, never the estate
instance. Its first probe, which labels `GET /labels` shows a
bot, has to show nothing from an unshared project before the PM
bot runs on the estate instance.
- S3's one live run writes into the `mosaic-stack` project only.
- The bundled path stays in S3 as the REQ-TASK-3 option for other
installs.
- R1 and R5: when a non-gated item's deadline passes, its
recommended default applies and is logged. Gated items wait for
Jason: money, credentials and legal; prod infra and prod data;
anything sent to people outside the fleet. Product and UX
direction isn't gated.
- R17: Jason runs `docs/guides/slice-1-identities.md` on 2026-10-09
at about 10:30 Central. If the estate instance isn't serving by
then, he runs section 1 (Gitea) and leaves sections 2 to 4 for
when it is. Don't start Path B as a stopgap, because that makes
two Vikunjas and mints bot tokens twice.
@@ -0,0 +1,154 @@
# Merge plan: `refactor` into `next`
Jason's ruling R10 (2026-10-08, relayed by Mos in thread 1eba59e5): the
stack trunk stays `next`, and `refactor` merges into it. Sage writes the
plan. Nothing in this file has been executed. No merge has happened.
## Pinned measurement (2026-10-08)
| Ref | SHA |
|---|---|
| `origin/refactor` | `b8db39cf1ec9ffc8958d7966b63f04710e70cb75` |
| `origin/next` | `2101c9b4468b22f57b2f02bb2c9da12067225819` |
| merge base | `5d2770002612a09ae0cadc129b4ea30619133e8a` |
| `origin/main` (not part of this plan) | `7102ccb93e007d98faab3994ea552d03f522ad2c` |
The merge base is the old v1 head. The 2026-09-07 conversion merged it in
as the second parent and moved its tree under `v1/`
(`docs/plans/2026-09-07_repository-consolidation-completed.md`).
- `refactor` is 371 commits ahead of the base. `next` is 1 commit ahead:
`2101c9b4`, fred, 2026-09-11, `fix(git-tools): issue-comment.sh resolves
API base without monolith GITEA_URL (#1502)`. It changes two files under
`packages/mosaic/framework/tools/git/`.
- `git diff -M origin/next origin/refactor`: 5,520 paths. 3,491 are v1
files renamed into `v1/`, 16 are added under `v1/`, 1,997 are added at
the root, 7 root files are renamed and 9 are modified.
- `git merge-tree --write-tree origin/next origin/refactor` exits 0 with no
conflicts. Result tree `095ce6f8949149f664ab6915cf631fb294871a0c`
differs from `refactor`'s tree in exactly the two #1502 files, now at
`v1/packages/mosaic/framework/tools/git/`. Rename detection carries the
fix into the archive where it belongs.
The text merge is trivial. The work is everything around it.
## Conflict areas
1. **The merge gate can't pass as things stand.** `next` is protected: no
direct push, one approval, and the required status
`ci/woodpecker/pr/ci`. Woodpecker reads `.woodpecker/` from the PR's
head tree. `refactor` has no root `.woodpecker/`, so a PR from it never
posts that status. The PR would sit unmergeable unless an admin
overrides the check.
2. **Approval identity.** Every seat writes to Gitea as `jarvis`. Gitea
doesn't count an approval from the PR's author, so if `jarvis` opens
the PR, a seat review can't satisfy the one-approval rule. Jason's
approval can, and later the slice 1 Gitea reviewer bot can.
3. **`next`'s pipelines go quiet.** After the merge `next`'s root has
no `.woodpecker/`. Pushes to `next` stop publishing
`@mosaicstack/mosaic@next` and the next-lane gateway, web and
appservice sha images. Nothing fails. The dist-tag and images freeze
at the last v1 build. Anything that auto-deploys next-lane images
stops updating. That's prod infra, so Jason confirms nothing live
depends on it before the merge.
4. **`.mosaic/repo.json` moves.** On `next` it sits at the root and says
`integration_trunk: next`, `release_branch: main`,
`flow: trunk-release`. `refactor` has it only at `v1/.mosaic/`. Nothing
in it contradicts R10, so there's nothing to correct. But R14's
enforcers read `<repo>/.mosaic/repo.json`, and after the merge `next`
has none at the root. The landing order adds one.
5. **Thirteen open PRs go stale.** Twelve target `next` and one targets
`main`. All are on the v1 tree, the newest from 2026-09-11. After the
merge their paths no longer exist at the root.
| PR | Author | Title (short) |
|---|---|---|
| #1491 | orch-01 | PRD rev1 ratification |
| #1469 | code-be-01 | config minimal-subset |
| #1431 | fred | gateway bootstrap advisory lock |
| #1370 | code-infra-01 | credentials Gitea seat slots |
| #1367 | fred | mint-seat-credential.sh |
| #1315 | fargo | RI-050 release evidence |
| #1291 | fargo | identity-first principal resolution |
| #1281 | Ghost | vetted user store (W-F4) |
| #1268 | Ghost | unattended identity first start |
| #1259 | Ghost | enumeration guard scope |
| #1213 | Ghost | HARNESS-HOMES fleet MVP |
| #1192 | Ghost | fail closed on invalid launch inputs |
| #1054 | Ghost | installer state machine (base `main`) |
6. **Hardcoded `refactor`.** `packages/ledger/src/ledger.mjs:37` reads
`git log refactor`. Prose in `AGENTS.md`, `docs/plans/CONDUCTOR.md`,
`docs/plans/CURRENT.md` and the queue's genesis log names `refactor`
as the working branch. The genesis log is append-only history and
stays as written. The rest changes in the cutover commit.
## Landing order
Each step is a separate act. Steps 1 to 3 happen on `refactor` under my
existing push authority. Steps 4 and 5 are Jason's.
1. **Add PR CI to `refactor`.** A `.woodpecker/ci.yml` triggered on
`pull_request` and `manual`, so its status context is
`ci/woodpecker/pr/ci`. It uses a digest-pinned `node:26` image, runs
`npm ci`, every `node --test packages/*/tests/*.test.mjs` and the
`scripts/test-*.sh` suites that need no Docker or provider login. The
two live-provider assertions in `test-task.sh` skip under an explicit
flag that CI sets and the suite reports as a skip. New queue row,
Darkwing reviews.
2. **Add root `.mosaic/repo.json`.** Same content as `next`'s, with the
notes updated to cite R10. Hold this step until the T235 enforcer
lands and its handling of a repo with this file is checked. An
enforcer that reads `integration_trunk: next` while `refactor` is
still the working branch must not block step 3.
3. **Back-merge `origin/next` into `refactor`.** One merge commit,
proven clean above. Re-run `merge-tree` against the then-current
`origin/next` first, since `next` can still move. Full integration
gate, then push. After this, `refactor` contains all of `next`.
4. **PR `refactor` into `next`, fast-forward only.** `refactor` already
contains `next`, so the fast-forward style applies. `next`'s head
becomes a SHA that passed our gate, with no new commit. Every SHA
cited in run records, review records and queue rounds keeps
resolving. Squash and rebase are ruled out because they would break
those citations. Jason approves and merges (R2).
5. **Dispose of the thirteen v1 PRs.** Recommended default: close each
with a comment pointing to `v1/` and this plan. Closing them changes
nothing outside the fleet, so under R1 the default applies at its
deadline unless Jason rules otherwise.
6. **Cutover commit, first PR on the new trunk.** Point the ledger at
the trunk named in `.mosaic/repo.json`, not a hardcoded branch.
Update `AGENTS.md`, `CONDUCTOR.md` and `CURRENT.md`. Freeze
`refactor`: keep the ref, push nothing more to it.
## How slice 1 rows retarget
- Open rows: 35 (SR, waiting on Jason), 38 (S3), 39 (S4), 40 (S5), 41
(S6), 42 (S7). Also row 13 (ledger queue section, in review).
- Before step 4: rows land on `refactor` exactly as they do today. A row
in review when step 3 starts finishes on `refactor` first, so nothing
straddles the cutover.
- After step 4: each row's candidate lands on a branch `slice1/<row>-<slug>`
cut from `next`, opened as a PR into `next`. The seat review stays on
the row's issue as now. The PR adds CI and Jason's approval and merge.
Briefs, issues and queue rows don't change. Packet base SHAs stay valid
because `next` contains `refactor`'s history.
- S7 needs this anyway. Its coder bot opens pull requests against the
integration trunk, and `.mosaic/repo.json` names `next`. Step 4 has to
land before S7 starts.
- Cost: every row after the cutover needs a Jason merge. That's five
merges for S3 to S7, plus fix rounds. Decision 62 already gates each
S7 coder-bot merge, so S7 adds no new kind of ask.
## What Jason decides
- When to merge (step 4), and the approval and merge themselves.
- Whether anything live consumes next-lane images or the `@next`
dist-tag (conflict 3). Prod infra, gated under R5.
- Push authority for `slice1/*` feature branches as `jarvis`. Today I
may push only to `refactor`.
- If he'd rather not wait for step 1, an admin override of the missing
status check instead. I don't recommend it. It merges 371 commits with
no CI run on the protected branch.
`main` is out of scope. It stays the v1 release branch until a separate
release ruling.