sage: re-pin window 490e2771d to 4429a104f (row 192) record, STATE.md (sha256 a4d0a7b12f431f15), W.txt (ca9ad4a09059d3b7), S1/S2, matrices, W10 browser check and diagnosis (screenshots not committed), Mos's P3 rehearsal and flags check, W11 reads. Plan corrections after the window: NEW is 103 commits past OLD (not 106), the P3 flags note (mos-1107), and W10's line g and corrected browser checks (mos-1135, mos-1137). PRD 1.8 raise record, decision 3a6c8fb9 (mos-1140) (#1690; P19 386, 412)
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"seq": 22,
|
||||
"id": "3a6c8fb9-a5ab-42f8-9755-902a88375ca2",
|
||||
"at": "2026-10-20T22:41:14.444Z",
|
||||
"business": "mosaic-stack",
|
||||
"project": null,
|
||||
"raised_by_role": "pm",
|
||||
"raised_by_run": "rc9e993da24cf",
|
||||
"class": "gated",
|
||||
"action": "prd.approve",
|
||||
"route_to": "human",
|
||||
"question": "Approve PRD 1.8 exactly as drafted?\n\nFile: agents/honker/work/queue-194/PRD-1.8-DRAFT.md on mosaicstack/stack at commit 762a6711ff7ed049aa73dfde98b75ebf326bdd99 (revision 5), 319 lines, sha256 8eee52470b1d7df139164e3ba5cc128dc469457b2b52f298c12685c3483011a8. Duckworth reviewed it (duckworth-0061, confirmed duckworth-0062) and Mos checked it (mos-1140). The tip of branch honker/row194-b2 holds a later r6 (aba3cbdeb), which is not used here. This approval covers only the r5 commit and sha256 above. The PM copied these values from the request and did not compute or check the sha256.\n\nNotes the approval carries:\n1. Mos's reading: \"the main agent or chief of staff\" in Q10 is one role under two names, the chief of staff. Only the chief raises a grant request; the assistant passes the user's request to the chief. To change it, say so at approval and REQ-GRANT-1 changes first.\n2. Mos's reading: revoke by \"you, Mos or the tester\" means the user, the assistant (\"Mos\", Jason's assistant) for grants in its own organization, and the tester only on a dev instance.\n3. N5: host.sudo keeps the arbiter route version 1.7 set for git.push.remote. A raise for it that cites the spec and isn't within-role goes to the arbiter for its domain, not to the user. In manual mode it comes to the user.\n4. B7 residual: only an Approve creates a grant, but an agent running as the stack's OS user can still write the stack's own store (Q182 on dragon-lin, #423 on .53 and .54). This version doesn't close it.\n5. N6: the broker enforces only that the chief of staff raised a grant request. The rest of the chain of command is the messaging lists and role contracts, not a broker check.\n\nSource: a tester request relayed by the chief (message 6990efb4, tester message d54a190e). It is a test request, not Jason's instruction. It takes the same route as PRD 1.7 (decision d52febb5): non-blocking, no task, uncited, so it goes to the human's Inbox. I recommend yes because two reviewers have passed r5 and the open points are written down above, not hidden.",
|
||||
"options": [
|
||||
{
|
||||
"key": "yes",
|
||||
"text": "Approve PRD 1.8 exactly as drafted: the r5 file at commit 762a6711ff7ed049aa73dfde98b75ebf326bdd99 with the sha256 below, and only that."
|
||||
},
|
||||
{
|
||||
"key": "no",
|
||||
"text": "Don't approve. Say what changes, and a new revision comes back for review."
|
||||
}
|
||||
],
|
||||
"recommendation": "yes",
|
||||
"task_ref": null,
|
||||
"requirement_ref": null,
|
||||
"blocking": false,
|
||||
"supersedes": null,
|
||||
"spec_path": null,
|
||||
"spec_commit": null,
|
||||
"authorization": {
|
||||
"action": "prd.approve",
|
||||
"target": null,
|
||||
"approvalChoice": "yes"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
[
|
||||
{
|
||||
"seq": 22,
|
||||
"id": "3a6c8fb9-a5ab-42f8-9755-902a88375ca2",
|
||||
"at": "2026-10-20T22:41:14.444Z",
|
||||
"business": "mosaic-stack",
|
||||
"project": null,
|
||||
"raised_by_role": "pm",
|
||||
"raised_by_run": "rc9e993da24cf",
|
||||
"class": "gated",
|
||||
"action": "prd.approve",
|
||||
"route_to": "human",
|
||||
"question": "Approve PRD 1.8 exactly as drafted?\n\nFile: agents/honker/work/queue-194/PRD-1.8-DRAFT.md on mosaicstack/stack at commit 762a6711ff7ed049aa73dfde98b75ebf326bdd99 (revision 5), 319 lines, sha256 8eee52470b1d7df139164e3ba5cc128dc469457b2b52f298c12685c3483011a8. Duckworth reviewed it (duckworth-0061, confirmed duckworth-0062) and Mos checked it (mos-1140). The tip of branch honker/row194-b2 holds a later r6 (aba3cbdeb), which is not used here. This approval covers only the r5 commit and sha256 above. The PM copied these values from the request and did not compute or check the sha256.\n\nNotes the approval carries:\n1. Mos's reading: \"the main agent or chief of staff\" in Q10 is one role under two names, the chief of staff. Only the chief raises a grant request; the assistant passes the user's request to the chief. To change it, say so at approval and REQ-GRANT-1 changes first.\n2. Mos's reading: revoke by \"you, Mos or the tester\" means the user, the assistant (\"Mos\", Jason's assistant) for grants in its own organization, and the tester only on a dev instance.\n3. N5: host.sudo keeps the arbiter route version 1.7 set for git.push.remote. A raise for it that cites the spec and isn't within-role goes to the arbiter for its domain, not to the user. In manual mode it comes to the user.\n4. B7 residual: only an Approve creates a grant, but an agent running as the stack's OS user can still write the stack's own store (Q182 on dragon-lin, #423 on .53 and .54). This version doesn't close it.\n5. N6: the broker enforces only that the chief of staff raised a grant request. The rest of the chain of command is the messaging lists and role contracts, not a broker check.\n\nSource: a tester request relayed by the chief (message 6990efb4, tester message d54a190e). It is a test request, not Jason's instruction. It takes the same route as PRD 1.7 (decision d52febb5): non-blocking, no task, uncited, so it goes to the human's Inbox. I recommend yes because two reviewers have passed r5 and the open points are written down above, not hidden.",
|
||||
"options": [
|
||||
{
|
||||
"key": "yes",
|
||||
"text": "Approve PRD 1.8 exactly as drafted: the r5 file at commit 762a6711ff7ed049aa73dfde98b75ebf326bdd99 with the sha256 below, and only that."
|
||||
},
|
||||
{
|
||||
"key": "no",
|
||||
"text": "Don't approve. Say what changes, and a new revision comes back for review."
|
||||
}
|
||||
],
|
||||
"recommendation": "yes",
|
||||
"task_ref": null,
|
||||
"requirement_ref": null,
|
||||
"blocking": false,
|
||||
"supersedes": null,
|
||||
"spec_path": null,
|
||||
"spec_commit": null,
|
||||
"authorization": {
|
||||
"action": "prd.approve",
|
||||
"target": null,
|
||||
"approvalChoice": "yes"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,13 @@
|
||||
[mos test] Please have the PM raise a prd.approve decision for PRD 1.8, the same route as PRD 1.7 (decision d52febb5): blocking false, no task_ref, recommendation yes, gated to the human. The PM must not compute or change the sha256; it copies the values below.
|
||||
|
||||
Question: "Approve PRD 1.8 exactly as drafted?"
|
||||
File: agents/honker/work/queue-194/PRD-1.8-DRAFT.md on mosaicstack/stack at commit 762a6711ff7ed049aa73dfde98b75ebf326bdd99 (revision 5), 319 lines, sha256 8eee52470b1d7df139164e3ba5cc128dc469457b2b52f298c12685c3483011a8. Reviewed by Duckworth (duckworth-0061, confirmed duckworth-0062) and checked by Mos (mos-1140). The branch tip of honker/row194-b2 holds a later r6 (aba3cbdeb) that is not used; the approval covers only the r5 commit and sha256 above.
|
||||
|
||||
The decision notes must carry these five items:
|
||||
1. Mos's reading: "the main agent or chief of staff" in Q10 is one role under two names, the chief of staff. Only the chief raises a grant request; the assistant passes the user's request to the chief. To change it, say so at approval and REQ-GRANT-1 changes first.
|
||||
2. Mos's reading: revoke by "you, Mos or the tester" means the user, the assistant ("Mos", Jason's assistant) for grants in its own organization, and the tester only on a dev instance.
|
||||
3. N5: host.sudo keeps the arbiter route version 1.7 set for git.push.remote. A raise for it that cites the spec and isn't within-role goes to the arbiter for its domain, not to the user. In manual mode it comes to the user.
|
||||
4. B7 residual: only an Approve creates a grant, but an agent running as the stack's OS user can still write the stack's own store (Q182 on dragon-lin, #423 on .53 and .54). This version doesn't close it.
|
||||
5. N6: the broker enforces only that the chief of staff raised a grant request. The rest of the chain of command is the messaging lists and role contracts, not a broker check.
|
||||
|
||||
Reply with the decision id once raised. Do not resolve it.
|
||||
@@ -0,0 +1,8 @@
|
||||
sent d54a190e to chief
|
||||
chief (RESULT, re d54a190e) cc46a7b4:
|
||||
I passed your request to the pm without changing any of it, and launched the pm so it can act on it. No decision id yet, because the pm hasn't raised the decision.
|
||||
|
||||
- **Message to pm:** 6990efb4-8321-4d0e-9b8a-771f65625b83. It says the request comes from a tester and authorizes nothing, and it carries your PRD 1.8 values and the five notes as you wrote them.
|
||||
- **pm launch:** run rc9e993da24cf.
|
||||
|
||||
When the pm answers with the decision id, I'll send it to you.
|
||||
@@ -0,0 +1,5 @@
|
||||
trail 3a6c8fb9-a5ab-42f8-9755-902a88375ca2: 4 row(s)
|
||||
2026-10-20T22:40:47.949Z events#1550 session.launched pm
|
||||
2026-10-20T22:40:47.969Z role_claims#102 claim pm by rc9e993da24cf
|
||||
2026-10-20T22:41:14.444Z decisions#22 gated prd.approve → human: Approve PRD 1.8 exactly as drafted? File: agents/honker/work/queue-194/PRD-1.8-DRAFT.md on mosaicstack/stack at commit …
|
||||
2026-10-20T22:41:14.445Z events#1553 action.allowed pm decision.raise decision 3a6c8fb9
|
||||
@@ -26,7 +26,8 @@ the rollback compare are reused unchanged.
|
||||
- OLD, live: `490e2771d3d057ab76991e2c7859cd251857e64c`, activation `20261020T192956Z-490e2771d3d0`, pointer
|
||||
`pm: true`, schema 3i, Console `--port 7332 --public-host mosaic.woltje.com --auth-header X-authentik-username
|
||||
--allow-user jason.woltje --tester-port 7333` (no `--send`, read from `stack-release.sh status` between 21:36Z and 21:39Z).
|
||||
- NEW: `4429a104f6d65ccf165f6c83b5d1dce3147dfde0`, row 192's landing, 106 commits past OLD counting records.
|
||||
- NEW: `4429a104f6d65ccf165f6c83b5d1dce3147dfde0`, row 192's landing, 103 commits past OLD (`git rev-list --count 490e2771d..4429a104f`).
|
||||
The 106 that `status` showed is OLD to HEAD 305857c8f, so it also counts the three record commits below.
|
||||
The commits after it (5b8def2f1 plans, 176a6bf4b sessions, 305857c8f queue) are records and don't move NEW. If
|
||||
another code row lands before W0 (row 190 is the likely one), NEW stays here unless Mos rules otherwise.
|
||||
- REPO: the canonical checkout. `activate` runs REPO's `webui-service.sh`, so the four service scripts are held
|
||||
@@ -79,7 +80,7 @@ writes no copy if it fails (:56). W0 checks the result: `node_modules/oauth4weba
|
||||
| P1 | Sage | The business file, read only, the same values as the 177-185 plan P1. I report its sha256 now rather than assume the 06:15Z value. `business-check.mjs` for OLD now and for NEW after W0: LOAD_OK both. |
|
||||
| W0 | Sage | `cd $REPO && scripts/stack-copy.sh copy $NEW`, in a gap between gate-lane runs, since npm ci is heavy. Then the two npm checks above, and `diff <(git -C $REPO show $NEW:package-lock.json) $COPIES/$NEW/package-lock.json` empty. W0 writes only under `copies/` and changes nothing live, so it moves before P2 and P3, which need the copy. |
|
||||
| P2 | Sage | `console-check.sh $NEW` against a stub Console of NEW on a scratch port, once without and once with `--tester-port` on a second scratch port. CONSOLE_PASS both. |
|
||||
| P3 | Mos | `scripts/stack-release.sh rehearse $NEW mosaic-stack --backup 20261020T192956Z-490e2771d3d0 --port <scratch>`. It must pass every gate check but the PM's, with the pointer's Console flags. It stops no unit and writes no pointer. Transcript in `$WIN/p3/`. |
|
||||
| P3 | Mos | `scripts/stack-release.sh rehearse $NEW mosaic-stack --backup 20261020T192956Z-490e2771d3d0 --port <scratch>`. It must pass every gate check but the PM's. It stops no unit and writes no pointer. Transcript in `$WIN/p3/`. Correction (mos-1107): `rehearse` starts NEW's Console with only `--port` and `--business`, not the pointer's flags. So Mos also starts NEW's Console by hand with the pointer's flags on two scratch ports and reads healthz and `/api/config` on both, then stops it (`$WIN/p3/flags-check.txt`, `flags-console.log`). |
|
||||
| P4 | Sage | The tunnel read, as in the 177-185 plan P4. |
|
||||
| P5 | Sage | `git -C $REPO diff --quiet $NEW HEAD -- scripts/stack-release.sh scripts/webui-service.sh scripts/bus-service.sh scripts/stack-copy.sh` and an empty `git status --porcelain` on the same four. Row 190 round 3 touches `webui-service.sh`; if it lands before W5, P5 fails and the window waits for Mos's ruling. |
|
||||
| P6 | Sage | The 7332 matrix (a)-(g) on OLD, as in the 177-185 plan, saved as `$WIN/matrix-old.txt`. |
|
||||
@@ -95,7 +96,7 @@ writes no copy if it fails (:56). W0 checks the result: `node_modules/oauth4weba
|
||||
| W4 | Sage | The unit reads, as in the 177-185 plan W4. |
|
||||
| W5 | Sage, on Mos's go | `stack-release.sh activate $NEW mosaic-stack --pm`. Exit 0, `result ok`, every gate check including `pm_launched`. Record the activation id, the backup path and STAMP, and the backup SHA256SUMS sha256. Then `status`. |
|
||||
| W9 | Sage, after Mos verifies W5 | The 177-185 plan's W9 list unchanged, the chief turn and the one `assistant` thread turn included (mos-0929 Q3), plus two lines: the webui journal since the W5 stamp (with `UTC`) has one `Proxy: proxy proof off` and no `Sign-in:` line, and `ls -l /proc/<Console pid>/cwd` names the NEW copy. |
|
||||
| W10 | Sage | The browser check on 127.0.0.1:7333 and the matrix again as `$WIN/matrix-new.txt`, identical to `matrix-old.txt`. Then P4 again. |
|
||||
| W10 | Sage | The browser check on 127.0.0.1:7333 and the matrix again as `$WIN/matrix-new.txt`, identical to `matrix-old.txt`. Then P4 again. Corrections after the window (mos-1135, mos-1137): the matrix line for a file the pin changes isn't "identical". Line (g) serves `index.html`, which row 192 grows by 121 bytes (6470 to 6591), so (g) is 200 non-json at 6575 bytes, not 6454. The two browser checks come from the 177-185 window, before row 192 and before a second thread project. "Only tester forms" now allows `#sign-out` while it is `hidden` and `/api/config` has no `sso: true`. "Chat lists the W9 thread" now reads every `.chat-projects section.panel` list (chat.js:93 renders one per project), not the first. |
|
||||
| W11 | Sage | STATE report in `$WIN/STATE.md`, posted on P19 386 and P19 412 and on Gitea #1690. |
|
||||
|
||||
## Stop conditions and rollback
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
chief rbb708846b605 claude-code since 2026-10-20T19:29:59.053Z
|
||||
pm rc36b17ef3788 claude-code since 2026-10-20T20:20:56.278Z
|
||||
# exit 0
|
||||
@@ -0,0 +1,256 @@
|
||||
{
|
||||
"settings loaded": {
|
||||
"pass": true
|
||||
},
|
||||
"settings": {
|
||||
"banner": "Tester Console. Changes are recorded as tester, never as the human.",
|
||||
"h1": "Settings",
|
||||
"forms": [
|
||||
"sign-out",
|
||||
"conv-form",
|
||||
"routes-form",
|
||||
"instance-add-form",
|
||||
"instance-change-form",
|
||||
"tester-name-form",
|
||||
"tester-name-form",
|
||||
"tester-name-form",
|
||||
"tester-name-form",
|
||||
"tester-name-form",
|
||||
"tester-name-form"
|
||||
],
|
||||
"convFormHidden": true,
|
||||
"panels": [
|
||||
"Routing",
|
||||
"Role instances",
|
||||
"Seat names"
|
||||
],
|
||||
"instancesTable": true,
|
||||
"nameForms": 6,
|
||||
"routesForm": true,
|
||||
"routesSubmitEnabled": true,
|
||||
"forbidden": [],
|
||||
"tokenLimitsPanel": false
|
||||
},
|
||||
"tester banner": {
|
||||
"pass": true,
|
||||
"detail": "Tester Console. Changes are recorded as tester, never as the human."
|
||||
},
|
||||
"instance, routes and name editors present": {
|
||||
"pass": true
|
||||
},
|
||||
"only tester forms (conv-form is index.html:21, global and hidden)": {
|
||||
"pass": false,
|
||||
"detail": [
|
||||
"sign-out",
|
||||
"conv-form",
|
||||
"routes-form",
|
||||
"instance-add-form",
|
||||
"instance-change-form",
|
||||
"tester-name-form",
|
||||
"tester-name-form",
|
||||
"tester-name-form",
|
||||
"tester-name-form",
|
||||
"tester-name-form",
|
||||
"tester-name-form"
|
||||
]
|
||||
},
|
||||
"no launch settings, assistant, limit reset or send": {
|
||||
"pass": true,
|
||||
"detail": []
|
||||
},
|
||||
"no Token limits panel (plan W10 item 2, amended)": {
|
||||
"pass": true
|
||||
},
|
||||
"board": {
|
||||
"busViewHidden": true,
|
||||
"banner": true,
|
||||
"headings": [
|
||||
"Waiting on you –",
|
||||
"All sessions –"
|
||||
],
|
||||
"unavailable": false,
|
||||
"length": 179,
|
||||
"forms": [
|
||||
"sign-out",
|
||||
"conv-form"
|
||||
]
|
||||
},
|
||||
"board reads": {
|
||||
"pass": true,
|
||||
"detail": {
|
||||
"busViewHidden": true,
|
||||
"banner": true,
|
||||
"headings": [
|
||||
"Waiting on you –",
|
||||
"All sessions –"
|
||||
],
|
||||
"unavailable": false,
|
||||
"length": 179,
|
||||
"forms": [
|
||||
"sign-out",
|
||||
"conv-form"
|
||||
]
|
||||
}
|
||||
},
|
||||
"chat": {
|
||||
"hash": "#/chat",
|
||||
"banner": true,
|
||||
"threads": [
|
||||
{
|
||||
"href": "#/chat/threads/d0ba7a66-aa3f-4918-9518-94132bce6b28",
|
||||
"name": "w9",
|
||||
"instance": "assistant"
|
||||
}
|
||||
],
|
||||
"conversationOpen": false,
|
||||
"forms": [
|
||||
"sign-out",
|
||||
"conv-form",
|
||||
"chat-project-form"
|
||||
]
|
||||
},
|
||||
"chat lists the W9 thread": {
|
||||
"pass": false,
|
||||
"detail": [
|
||||
{
|
||||
"href": "#/chat/threads/d0ba7a66-aa3f-4918-9518-94132bce6b28",
|
||||
"name": "w9",
|
||||
"instance": "assistant"
|
||||
}
|
||||
]
|
||||
},
|
||||
"W9 thread page not opened": {
|
||||
"pass": true,
|
||||
"detail": "#/chat"
|
||||
},
|
||||
"tester banner on chat": {
|
||||
"pass": true
|
||||
},
|
||||
"requests": [
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/config",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/config",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/messages",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus-status",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/messages",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/settings",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/usage",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/settings",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/usage",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/names",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/names",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/instances",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/instances",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/routes",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/routes",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/limits",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/limits",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/inbox",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/agents",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/messages",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/chat/projects",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/chat/threads",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/business",
|
||||
"refused": false
|
||||
}
|
||||
],
|
||||
"no write through the listener": {
|
||||
"pass": true,
|
||||
"detail": []
|
||||
},
|
||||
"no request to the W9 thread messages or open": {
|
||||
"pass": true,
|
||||
"detail": []
|
||||
}
|
||||
}
|
||||
W10 browser: FAIL
|
||||
# exit 1
|
||||
@@ -0,0 +1,200 @@
|
||||
{
|
||||
"config": {
|
||||
"sso": null
|
||||
},
|
||||
"forms": [
|
||||
{
|
||||
"id": "sign-out",
|
||||
"hidden": true,
|
||||
"action": "/auth/logout",
|
||||
"method": "post"
|
||||
},
|
||||
{
|
||||
"id": "conv-form",
|
||||
"hidden": true,
|
||||
"action": null,
|
||||
"method": null
|
||||
},
|
||||
{
|
||||
"id": "routes-form",
|
||||
"hidden": false,
|
||||
"action": null,
|
||||
"method": null
|
||||
},
|
||||
{
|
||||
"id": "instance-add-form",
|
||||
"hidden": false,
|
||||
"action": null,
|
||||
"method": null
|
||||
},
|
||||
{
|
||||
"id": "instance-change-form",
|
||||
"hidden": false,
|
||||
"action": null,
|
||||
"method": null
|
||||
},
|
||||
{
|
||||
"id": "tester-name-form",
|
||||
"hidden": false,
|
||||
"action": null,
|
||||
"method": null
|
||||
},
|
||||
{
|
||||
"id": "tester-name-form",
|
||||
"hidden": false,
|
||||
"action": null,
|
||||
"method": null
|
||||
},
|
||||
{
|
||||
"id": "tester-name-form",
|
||||
"hidden": false,
|
||||
"action": null,
|
||||
"method": null
|
||||
},
|
||||
{
|
||||
"id": "tester-name-form",
|
||||
"hidden": false,
|
||||
"action": null,
|
||||
"method": null
|
||||
},
|
||||
{
|
||||
"id": "tester-name-form",
|
||||
"hidden": false,
|
||||
"action": null,
|
||||
"method": null
|
||||
},
|
||||
{
|
||||
"id": "tester-name-form",
|
||||
"hidden": false,
|
||||
"action": null,
|
||||
"method": null
|
||||
}
|
||||
],
|
||||
"chat": {
|
||||
"hash": "#/chat",
|
||||
"open": false,
|
||||
"projects": [
|
||||
{
|
||||
"project": "window-20261020-0801",
|
||||
"threads": [
|
||||
"#/chat/threads/d0ba7a66-aa3f-4918-9518-94132bce6b28"
|
||||
]
|
||||
},
|
||||
{
|
||||
"project": "window-20261020-2205",
|
||||
"threads": [
|
||||
"#/chat/threads/446201de-e8b5-4df3-9356-d0d5422cc899"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"requests": [
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/config",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/config",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/messages",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus-status",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/messages",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/settings",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/usage",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/settings",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/usage",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/names",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/names",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/instances",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/instances",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/routes",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/routes",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/limits",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/bus/limits",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/config",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/chat/projects",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/chat/threads",
|
||||
"refused": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"url": "/api/business",
|
||||
"refused": false
|
||||
}
|
||||
]
|
||||
}
|
||||
sign-out hidden true, sso null; W9 thread listed true; thread page open false; writes 0
|
||||
# exit 0
|
||||
@@ -0,0 +1,8 @@
|
||||
a 200 ok=true
|
||||
b 401 error="sign-in required"
|
||||
c 401 error="sign-in required"
|
||||
d 403 error="proxy Host refused"
|
||||
e 403 error="tester listener required"
|
||||
f 403 error="proxy header refused"
|
||||
g 200 non-json 6575 bytes
|
||||
# exit 0
|
||||
@@ -0,0 +1,7 @@
|
||||
# P4 2026-10-20T22:31:29Z
|
||||
DropInPaths=
|
||||
ExecStart={ path=/home/jwoltje/.local/bin/chisel ; argv[]=/home/jwoltje/.local/bin/chisel client --fingerprint ce+ISFvMAhuoCRDuc7riIf+hYz87TLHk/C9C/H8QsUg= --keepalive 25s --max-retry-interval 10s http://10.1.1.227:8080 R:0.0.0.0:7332:127.0.0.1:7332 ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }
|
||||
# exit 0
|
||||
# R: specs (1): R:0.0.0.0:7332:127.0.0.1:7332
|
||||
P4 PASS: one R: spec R:0.0.0.0:7332:127.0.0.1:7332, DropInPaths empty
|
||||
# exit 0
|
||||
@@ -0,0 +1,6 @@
|
||||
ActiveState=active
|
||||
DropInPaths=
|
||||
MainPID=2950923
|
||||
ExecStart={ path=/home/jwoltje/.local/share/mosaic-stack/copies/4429a104f6d65ccf165f6c83b5d1dce3147dfde0/scripts/mosaic ; argv[]=/home/jwoltje/.local/share/mosaic-stack/copies/4429a104f6d65ccf165f6c83b5d1dce3147dfde0/scripts/mosaic bus start mosaic-stack --pm ; ignore_errors=no ; start_time=[Tue 2026-10-20 17:02:08 CDT] ; stop_time=[n/a] ; pid=2950923 ; code=(null) ; status=0/0 }
|
||||
WorkingDirectory=/home/jwoltje/.local/share/mosaic-stack/copies/4429a104f6d65ccf165f6c83b5d1dce3147dfde0
|
||||
# exit 0
|
||||
@@ -0,0 +1,12 @@
|
||||
● jarvis-curation-gate.service loaded failed failed Jarvis curation-gate liveness check (wake the agent if staged pulls sit uncurated)
|
||||
● jarvis-retro-check.service loaded failed failed Jarvis weekly retrospective ARTIFACT check (did Sunday's tick produce a retro?)
|
||||
● jarvis-retro.service loaded failed failed Jarvis weekly retrospective tick
|
||||
● mosaic-install-drift.service loaded failed failed Assert the installed Mosaic binaries still match the committed source (drift, not failure)
|
||||
● mosaic-standup-pm.service loaded failed failed Coordinator standup trigger (evening)
|
||||
● [email protected] loaded failed failed Escalate failed Mosaic unit jarvis-curation-gate.service to the local agent seat
|
||||
● [email protected] loaded failed failed Escalate failed Mosaic unit jarvis-retro-check.service to the local agent seat
|
||||
● [email protected] loaded failed failed Escalate failed Mosaic unit jarvis-retro.service to the local agent seat
|
||||
● [email protected] loaded failed failed Escalate failed Mosaic unit mosaic-install-drift.service to the local agent seat
|
||||
● [email protected] loaded failed failed Escalate failed Mosaic unit mosaic-reconcile.service to the local agent seat
|
||||
● setspark-tmp-guard.service loaded failed failed SetSpark: /tmp and scratch guard
|
||||
# exit 0
|
||||
@@ -0,0 +1,5 @@
|
||||
ActiveState=active
|
||||
SubState=running
|
||||
ActiveEnterTimestamp=Tue 2026-10-13 08:40:19 CDT
|
||||
MainPID=1317
|
||||
# exit 0
|
||||
@@ -0,0 +1,6 @@
|
||||
ActiveState=active
|
||||
DropInPaths=
|
||||
MainPID=2950925
|
||||
ExecStart={ path=/usr/bin/node ; argv[]=/usr/bin/node /home/jwoltje/.local/share/mosaic-stack/copies/4429a104f6d65ccf165f6c83b5d1dce3147dfde0/packages/webui/src/cli.mjs serve --checkout /mnt/storage/src/mosaic-stack --port 7332 --public-host mosaic.woltje.com --auth-header X-authentik-username --allow-user jason.woltje --tester-port 7333 ; ignore_errors=no ; start_time=[Tue 2026-10-20 17:02:08 CDT] ; stop_time=[n/a] ; pid=2950925 ; code=(null) ; status=0/0 }
|
||||
WorkingDirectory=/home/jwoltje/.local/share/mosaic-stack/copies/4429a104f6d65ccf165f6c83b5d1dce3147dfde0
|
||||
# exit 0
|
||||
@@ -0,0 +1,2 @@
|
||||
chief r097436c91816 claude-code since 2026-10-20T22:02:08.951Z
|
||||
# exit 0
|
||||
@@ -0,0 +1,7 @@
|
||||
PASS markdown-preview.js is served and equals the copy's
|
||||
PASS /api/config on loopback: send=false edit=false
|
||||
PASS project.files through the Console: head=ae0b17c9586e51da7bc1b7e548c6acf913a55665 files=2 spec=true error=none
|
||||
PASS project.file spec/north-star.md through the Console: commit=ae0b17c9586e51da7bc1b7e548c6acf913a55665 length=99 error=none
|
||||
PASS loopback save refused: HTTP 403 error=read-only sent=false
|
||||
CONSOLE_PASS
|
||||
# exit 0
|
||||
@@ -0,0 +1,19 @@
|
||||
[
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"instance": "chief",
|
||||
"run": "r097436c91816",
|
||||
"launchedBy": "jason",
|
||||
"harness": "claude-code",
|
||||
"model": "claude-opus-5-5",
|
||||
"provider": "anthropic",
|
||||
"modelKey": "opus",
|
||||
"pid": 2951160,
|
||||
"startTime": "63491912",
|
||||
"runnerPid": 2951161,
|
||||
"runnerStartTime": "63491912",
|
||||
"runDir": "/home/jwoltje/.mosaic-dev/launches/mosaic-stack/r097436c91816",
|
||||
"startedAt": "2026-10-20T22:02:08.941Z",
|
||||
"live": true
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,2 @@
|
||||
r097436c91816 mosaic-stack/chief claude-code claude-opus-5-5 by jason since 2026-10-20T22:02:08.941Z running
|
||||
# exit 0
|
||||
@@ -0,0 +1,2 @@
|
||||
[]
|
||||
# exit 0
|
||||
@@ -0,0 +1,2 @@
|
||||
created project window-20261020-2205 id 77e7b45f-8c34-49a3-b2fa-9cf565177c30
|
||||
# exit 0
|
||||
@@ -0,0 +1 @@
|
||||
1792533965
|
||||
@@ -0,0 +1,21 @@
|
||||
pointer: /home/jwoltje/.mosaic-dev/state/stack-active.json
|
||||
{"copy":"4429a104f6d65ccf165f6c83b5d1dce3147dfde0","business":"mosaic-stack","pm":true,"claude":"/home/jwoltje/.local/bin/claude","console":["--port","7332","--public-host","mosaic.woltje.com","--auth-header","X-authentik-username","--allow-user","jason.woltje","--tester-port","7333"],"schema":"3i","activation":"20261020T220206Z-4429a104f6d6","at":"2026-10-20T22:02:09Z"}
|
||||
log (last five lines):
|
||||
{"at":"2026-10-20T07:58:02Z","op":"activate","from":"89af38a83afa22a8a4f0d368a0a4030ad15a0efa","to":"490e2771d3d057ab76991e2c7859cd251857e64c","backup":"20261020T075800Z-490e2771d3d0","activation":"20261020T075800Z-490e2771d3d0","result":"ok"}
|
||||
{"at":"2026-10-20T19:29:56Z","op":"activate","from":"490e2771d3d057ab76991e2c7859cd251857e64c","to":"490e2771d3d057ab76991e2c7859cd251857e64c","backup":null,"activation":"20261020T192956Z-490e2771d3d0","result":"started"}
|
||||
{"at":"2026-10-20T19:30:00Z","op":"activate","from":"490e2771d3d057ab76991e2c7859cd251857e64c","to":"490e2771d3d057ab76991e2c7859cd251857e64c","backup":"20261020T192956Z-490e2771d3d0","activation":"20261020T192956Z-490e2771d3d0","result":"ok"}
|
||||
{"at":"2026-10-20T22:02:06Z","op":"activate","from":"490e2771d3d057ab76991e2c7859cd251857e64c","to":"4429a104f6d65ccf165f6c83b5d1dce3147dfde0","backup":null,"activation":"20261020T220206Z-4429a104f6d6","result":"started"}
|
||||
{"at":"2026-10-20T22:02:09Z","op":"activate","from":"490e2771d3d057ab76991e2c7859cd251857e64c","to":"4429a104f6d65ccf165f6c83b5d1dce3147dfde0","backup":"20261020T220206Z-4429a104f6d6","activation":"20261020T220206Z-4429a104f6d6","result":"ok"}
|
||||
check:
|
||||
bus: /home/jwoltje/.local/share/mosaic-stack/copies/4429a104f6d65ccf165f6c83b5d1dce3147dfde0
|
||||
Console: /home/jwoltje/.local/share/mosaic-stack/copies/4429a104f6d65ccf165f6c83b5d1dce3147dfde0
|
||||
CLI: /home/jwoltje/.local/share/mosaic-stack/copies/4429a104f6d65ccf165f6c83b5d1dce3147dfde0
|
||||
result: pass
|
||||
bus status:
|
||||
host: mosaic-stack, pid 2950923, running, since 2026-10-20T22:02:08.133Z, notifier off
|
||||
socket: present
|
||||
writer.lock: pid 2950981
|
||||
boot: organization file loaded at 2026-10-20T22:02:08.125Z
|
||||
unit flags: match the pointer
|
||||
drift: 6 commit(s) on refactor since the pointer's copy
|
||||
# exit 0
|
||||
@@ -0,0 +1,4 @@
|
||||
sent c5b43f04 to chief
|
||||
chief (RESULT, re c5b43f04) c3e236d7:
|
||||
Got the re-pin of 4429a104f6d65ccf165f6c83b5d1dce3147dfde0 from the tester; I took no action because a tester message authorizes nothing, and I launched and changed nothing.
|
||||
# exit 0
|
||||
@@ -0,0 +1,4 @@
|
||||
sent b4b66ced to window-20261020-2205/w9
|
||||
assistant (RESULT, re b4b66ced) cfa7ea99:
|
||||
Assistant (run r497f1c817d4d) got the [mos test] message and is replying in one line as asked, without treating it as Jason's instruction or acting on it.
|
||||
# exit 0
|
||||
@@ -0,0 +1,32 @@
|
||||
[
|
||||
{
|
||||
"seq": 570,
|
||||
"id": "b4b66ced-d088-4b9c-a944-306f164028f9",
|
||||
"at": "2026-10-20T22:05:58.283Z",
|
||||
"business": "mosaic-stack",
|
||||
"from_role": "tester",
|
||||
"from_run": "tester-cli",
|
||||
"to_role": "assistant",
|
||||
"class": "REQUEST",
|
||||
"in_reply_to": null,
|
||||
"decision": null,
|
||||
"corrects": null,
|
||||
"body": "[mos test] reply with one line, then stop",
|
||||
"to_name": null
|
||||
},
|
||||
{
|
||||
"seq": 571,
|
||||
"id": "cfa7ea99-7ccb-4225-80a6-9a903540e337",
|
||||
"at": "2026-10-20T22:06:04.247Z",
|
||||
"business": "mosaic-stack",
|
||||
"from_role": "assistant",
|
||||
"from_run": "r497f1c817d4d",
|
||||
"to_role": "tester",
|
||||
"class": "RESULT",
|
||||
"in_reply_to": "b4b66ced-d088-4b9c-a944-306f164028f9",
|
||||
"decision": null,
|
||||
"corrects": null,
|
||||
"body": "Assistant (run r497f1c817d4d) got the [mos test] message and is replying in one line as asked, without treating it as Jason's instruction or acting on it.",
|
||||
"to_name": null
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,2 @@
|
||||
created window-20261020-2205/w9 id 446201de-e8b5-4df3-9356-d0d5422cc899 instance assistant
|
||||
# exit 0
|
||||
@@ -0,0 +1,3 @@
|
||||
window-20261020-0801/w9 assistant d0ba7a66
|
||||
window-20261020-2205/w9 assistant 446201de
|
||||
# exit 0
|
||||
@@ -0,0 +1 @@
|
||||
446201de-e8b5-4df3-9356-d0d5422cc899
|
||||
@@ -0,0 +1,165 @@
|
||||
{
|
||||
"total": {
|
||||
"input": 62,
|
||||
"output": 9623,
|
||||
"cacheWrite": 186650,
|
||||
"cacheRead": 404132,
|
||||
"unknownTurns": 1
|
||||
},
|
||||
"byRun": [
|
||||
{
|
||||
"run": "r8fba7e598156",
|
||||
"input": 0,
|
||||
"output": 0,
|
||||
"cacheWrite": 0,
|
||||
"cacheRead": 0,
|
||||
"unknownTurns": 1
|
||||
},
|
||||
{
|
||||
"run": "r4a96e2142e4d",
|
||||
"input": 2,
|
||||
"output": 52,
|
||||
"cacheWrite": 11750,
|
||||
"cacheRead": 0,
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"run": "rc78c9700c8e9",
|
||||
"input": 14,
|
||||
"output": 1519,
|
||||
"cacheWrite": 18187,
|
||||
"cacheRead": 89559,
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"run": "r293f33bcbc63",
|
||||
"input": 2,
|
||||
"output": 44,
|
||||
"cacheWrite": 18595,
|
||||
"cacheRead": 0,
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"run": "r34520a581318",
|
||||
"input": 6,
|
||||
"output": 323,
|
||||
"cacheWrite": 26349,
|
||||
"cacheRead": 14307,
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"run": "r7e99838f9f93",
|
||||
"input": 2,
|
||||
"output": 44,
|
||||
"cacheWrite": 9858,
|
||||
"cacheRead": 0,
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"run": "rc964611b2092",
|
||||
"input": 4,
|
||||
"output": 120,
|
||||
"cacheWrite": 26138,
|
||||
"cacheRead": 23870,
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"run": "rbb708846b605",
|
||||
"input": 12,
|
||||
"output": 2089,
|
||||
"cacheWrite": 17285,
|
||||
"cacheRead": 73823,
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"run": "rc36b17ef3788",
|
||||
"input": 16,
|
||||
"output": 5221,
|
||||
"cacheWrite": 36717,
|
||||
"cacheRead": 202573,
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"run": "r097436c91816",
|
||||
"input": 2,
|
||||
"output": 131,
|
||||
"cacheWrite": 11915,
|
||||
"cacheRead": 0,
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"run": "r497f1c817d4d",
|
||||
"input": 2,
|
||||
"output": 80,
|
||||
"cacheWrite": 9856,
|
||||
"cacheRead": 0,
|
||||
"unknownTurns": 0
|
||||
}
|
||||
],
|
||||
"byInstance": [
|
||||
{
|
||||
"instance": "chief",
|
||||
"input": 36,
|
||||
"output": 4114,
|
||||
"cacheWrite": 85486,
|
||||
"cacheRead": 177689,
|
||||
"unknownTurns": 1
|
||||
},
|
||||
{
|
||||
"instance": "coder",
|
||||
"input": 2,
|
||||
"output": 44,
|
||||
"cacheWrite": 18595,
|
||||
"cacheRead": 0,
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"instance": "assistant",
|
||||
"input": 4,
|
||||
"output": 124,
|
||||
"cacheWrite": 19714,
|
||||
"cacheRead": 0,
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"instance": "pm",
|
||||
"input": 20,
|
||||
"output": 5341,
|
||||
"cacheWrite": 62855,
|
||||
"cacheRead": 226443,
|
||||
"unknownTurns": 0
|
||||
}
|
||||
],
|
||||
"byProvider": [
|
||||
{
|
||||
"provider": "anthropic",
|
||||
"input": 62,
|
||||
"output": 9623,
|
||||
"cacheWrite": 186650,
|
||||
"cacheRead": 404132,
|
||||
"unknownTurns": 1
|
||||
}
|
||||
],
|
||||
"byModel": [
|
||||
{
|
||||
"provider": "anthropic",
|
||||
"model": "claude-opus-5-5",
|
||||
"input": 62,
|
||||
"output": 9623,
|
||||
"cacheWrite": 186650,
|
||||
"cacheRead": 404132,
|
||||
"unknownTurns": 1
|
||||
}
|
||||
],
|
||||
"byAccount": [
|
||||
{
|
||||
"account": null,
|
||||
"input": 62,
|
||||
"output": 9623,
|
||||
"cacheWrite": 186650,
|
||||
"cacheRead": 404132,
|
||||
"unknownTurns": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
# exit 0
|
||||
@@ -0,0 +1,2 @@
|
||||
r097436c91816 mosaic-stack/chief claude-code claude-opus-5-5 by jason since 2026-10-20T22:02:08.941Z running
|
||||
# exit 0
|
||||
@@ -0,0 +1,19 @@
|
||||
[
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"instance": "chief",
|
||||
"run": "r097436c91816",
|
||||
"launchedBy": "jason",
|
||||
"harness": "claude-code",
|
||||
"model": "claude-opus-5-5",
|
||||
"provider": "anthropic",
|
||||
"modelKey": "opus",
|
||||
"pid": 2951160,
|
||||
"startTime": "63491912",
|
||||
"runnerPid": 2951161,
|
||||
"runnerStartTime": "63491912",
|
||||
"runDir": "/home/jwoltje/.mosaic-dev/launches/mosaic-stack/r097436c91816",
|
||||
"startedAt": "2026-10-20T22:02:08.941Z",
|
||||
"live": true
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,153 @@
|
||||
{
|
||||
"schema": "3i",
|
||||
"tables": {
|
||||
"decision_events": {
|
||||
"rows": 21,
|
||||
"maxSeq": 21,
|
||||
"sha256": "28dd95056663dd5eb7442a3d815b73a4a3cd311a0e854fd82dc54f7dc3e6ef26"
|
||||
},
|
||||
"decisions": {
|
||||
"rows": 21,
|
||||
"maxSeq": 21,
|
||||
"sha256": "fef1058660b0d128ef21089dda5e0fba7f71763d8325148fe521de0d3f57e4ad"
|
||||
},
|
||||
"deliveries": {
|
||||
"rows": 1726,
|
||||
"maxSeq": 1726,
|
||||
"sha256": "8667571f4a05ce3621b04cf2dc5eb0311bac3d3aff1858584c78445c5c4c2fb4"
|
||||
},
|
||||
"events": {
|
||||
"rows": 1525,
|
||||
"maxSeq": 1525,
|
||||
"sha256": "e51827e31f2fa5a9a50993e5a10f37f1dee383b7d673f793006bd2ba1e9a5573"
|
||||
},
|
||||
"instance_names": {
|
||||
"rows": 0,
|
||||
"maxSeq": null,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"message_threads": {
|
||||
"rows": 2,
|
||||
"maxSeq": null
|
||||
},
|
||||
"messages": {
|
||||
"rows": 567,
|
||||
"maxSeq": 567
|
||||
},
|
||||
"meta": {
|
||||
"rows": 3,
|
||||
"maxSeq": null,
|
||||
"sha256": "89fec56e7293d19e0b2f6cd8c0ef745ebf99e4115abeaea7fbdbc98a261332d9"
|
||||
},
|
||||
"projects": {
|
||||
"rows": 1,
|
||||
"maxSeq": 1,
|
||||
"sha256": "a3945f7462895e0e302029c542d384a6d33e559da900e6461d78bbcd7cc28b16"
|
||||
},
|
||||
"role_claims": {
|
||||
"rows": 98,
|
||||
"maxSeq": 98,
|
||||
"sha256": "ac6694fd0b365469f7486ae1f31486cd52b31be7bc0399938b7361f22454362e"
|
||||
},
|
||||
"task_comment_cursors": {
|
||||
"rows": 215,
|
||||
"maxSeq": 215,
|
||||
"sha256": "7f80df8efb90b502a9530a7ed5068d59be59b2eb318aa4e64ce6bf481762a5e9"
|
||||
},
|
||||
"task_snapshots": {
|
||||
"rows": 401,
|
||||
"maxSeq": 401,
|
||||
"sha256": "cced8c7f90ecaa60eee3010d987013d8c0301563cb888860fd91b8c5a02f0a00"
|
||||
},
|
||||
"thread_claims": {
|
||||
"rows": 2,
|
||||
"maxSeq": 2,
|
||||
"sha256": "6046c7088779aa2f6e9b3fd2c7520404b1678a4fcae71c2b9157a008bba22a5f"
|
||||
},
|
||||
"thread_opens": {
|
||||
"rows": 0,
|
||||
"maxSeq": null,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"threads": {
|
||||
"rows": 1,
|
||||
"maxSeq": 1,
|
||||
"sha256": "3043721efd386f23dfdaad4acf41e0d553ff6182f0068c2133a615141bcf772a"
|
||||
},
|
||||
"usage_records": {
|
||||
"rows": 30,
|
||||
"maxSeq": 30,
|
||||
"sha256": "7ecbc0606273043b017d778bb23880377bfe367f788d234289b7c132caa588f2",
|
||||
"byRun": [
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "r8fba7e598156",
|
||||
"input": "0",
|
||||
"output": "0",
|
||||
"unknownTurns": 1
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "r4a96e2142e4d",
|
||||
"input": "2",
|
||||
"output": "52",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "rc78c9700c8e9",
|
||||
"input": "14",
|
||||
"output": "1519",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "r293f33bcbc63",
|
||||
"input": "2",
|
||||
"output": "44",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "r34520a581318",
|
||||
"input": "6",
|
||||
"output": "323",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "r7e99838f9f93",
|
||||
"input": "2",
|
||||
"output": "44",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "rc964611b2092",
|
||||
"input": "4",
|
||||
"output": "120",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "rbb708846b605",
|
||||
"input": "12",
|
||||
"output": "2089",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "rc36b17ef3788",
|
||||
"input": "16",
|
||||
"output": "5221",
|
||||
"unknownTurns": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"untimed": [
|
||||
"message_threads",
|
||||
"meta",
|
||||
"task_comment_cursors"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
{
|
||||
"schema": "3i",
|
||||
"tables": {
|
||||
"decision_events": {
|
||||
"rows": 21,
|
||||
"maxSeq": 21,
|
||||
"sha256": "28dd95056663dd5eb7442a3d815b73a4a3cd311a0e854fd82dc54f7dc3e6ef26"
|
||||
},
|
||||
"decisions": {
|
||||
"rows": 21,
|
||||
"maxSeq": 21,
|
||||
"sha256": "fef1058660b0d128ef21089dda5e0fba7f71763d8325148fe521de0d3f57e4ad"
|
||||
},
|
||||
"deliveries": {
|
||||
"rows": 1740,
|
||||
"maxSeq": 1740,
|
||||
"sha256": "554ce5b377ffacc72bfde11c99c920cd5d30337c8bfa217275d0073b587e2169"
|
||||
},
|
||||
"events": {
|
||||
"rows": 1543,
|
||||
"maxSeq": 1543,
|
||||
"sha256": "0151673193d0286ce8f3b234d7d21fa2b0f43f2ceec55644cccaa5cbd77603dd"
|
||||
},
|
||||
"instance_names": {
|
||||
"rows": 0,
|
||||
"maxSeq": null,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"message_threads": {
|
||||
"rows": 4,
|
||||
"maxSeq": null
|
||||
},
|
||||
"messages": {
|
||||
"rows": 571,
|
||||
"maxSeq": 571
|
||||
},
|
||||
"meta": {
|
||||
"rows": 3,
|
||||
"maxSeq": null,
|
||||
"sha256": "89fec56e7293d19e0b2f6cd8c0ef745ebf99e4115abeaea7fbdbc98a261332d9"
|
||||
},
|
||||
"projects": {
|
||||
"rows": 2,
|
||||
"maxSeq": 2,
|
||||
"sha256": "3435f574ab94bc2fcc65fb8605251f30d4e9e63baf38e6fdf3c39c126531aa63"
|
||||
},
|
||||
"role_claims": {
|
||||
"rows": 101,
|
||||
"maxSeq": 101,
|
||||
"sha256": "fb47114defbb8a57dd148a06fbaf61b30f791a81f14b1510b8c32690506b4308"
|
||||
},
|
||||
"task_comment_cursors": {
|
||||
"rows": 220,
|
||||
"maxSeq": 220,
|
||||
"sha256": "df03c84094999299499de01107ddd08636df6156f5c9ccd2ff6e8c43e459f7e4"
|
||||
},
|
||||
"task_snapshots": {
|
||||
"rows": 408,
|
||||
"maxSeq": 408,
|
||||
"sha256": "e2243a89388afba07e8d096b4961deeb2d17c656cdcace54b46eac7001393814"
|
||||
},
|
||||
"thread_claims": {
|
||||
"rows": 4,
|
||||
"maxSeq": 4,
|
||||
"sha256": "088b8236570d8afe03364b85803fdc5034cce2cef6ed7b16f8b99bf6366524ad"
|
||||
},
|
||||
"thread_opens": {
|
||||
"rows": 0,
|
||||
"maxSeq": null,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"threads": {
|
||||
"rows": 2,
|
||||
"maxSeq": 2,
|
||||
"sha256": "819fd24c64e279d0debad5ab5dbbe533d8e6f26de58277c69510b9cbbaadbc3a"
|
||||
},
|
||||
"usage_records": {
|
||||
"rows": 34,
|
||||
"maxSeq": 34,
|
||||
"sha256": "de614f3d62c9b3819757c5659bee40085cb86cc873b7bfe381b13e254ddb7cad",
|
||||
"byRun": [
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "r8fba7e598156",
|
||||
"input": "0",
|
||||
"output": "0",
|
||||
"unknownTurns": 1
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "r4a96e2142e4d",
|
||||
"input": "2",
|
||||
"output": "52",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "rc78c9700c8e9",
|
||||
"input": "14",
|
||||
"output": "1519",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "r293f33bcbc63",
|
||||
"input": "2",
|
||||
"output": "44",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "r34520a581318",
|
||||
"input": "6",
|
||||
"output": "323",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "r7e99838f9f93",
|
||||
"input": "2",
|
||||
"output": "44",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "rc964611b2092",
|
||||
"input": "4",
|
||||
"output": "120",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "rbb708846b605",
|
||||
"input": "12",
|
||||
"output": "2089",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "rc36b17ef3788",
|
||||
"input": "16",
|
||||
"output": "5221",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "r097436c91816",
|
||||
"input": "2",
|
||||
"output": "131",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "r497f1c817d4d",
|
||||
"input": "2",
|
||||
"output": "80",
|
||||
"unknownTurns": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"untimed": [
|
||||
"message_threads",
|
||||
"meta",
|
||||
"task_comment_cursors"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
# Re-pin window 490e2771d to 4429a104f (row 192, Q175 phase 1), STATE report (W11)
|
||||
|
||||
Operator and tester: Sage. Plan: `agents/sage/work/window-plan/repin-4429a104f.md` at f41729178, sha256
|
||||
e1272d1a391e00fb1291d47da9973c0ba342d65fcd42f583ea007e883c1f32b9 (checked before W0b, W9). The plan file in
|
||||
this commit carries three corrections made after the window. They are listed at the end, so its sha256 differs
|
||||
now. Tool blob 3b068b1546d4 (`scripts/stack-release.sh`). OLD 490e2771d3d057ab76991e2c7859cd251857e64c, NEW
|
||||
4429a104f6d65ccf165f6c83b5d1dce3147dfde0. Every stamp below comes from `date -u` or from the transcript `W.txt`
|
||||
in this directory. Mos's gos: mos-1113 (W5), mos-1114 (W9 to W11), mos-1128 (W9b accepted), mos-1135 (W10
|
||||
browser part), mos-1137 (line g, post W11).
|
||||
|
||||
## Outcome
|
||||
|
||||
NEW is live for mosaic-stack with its PM, and the store stays on 3i. Row 192's sign-in code is in the copy but
|
||||
dormant, because the Console runs without `--sso`. W0 to W10 passed, and nothing was rolled back. W10 stopped
|
||||
once on two failed browser checks. I diagnosed both read-only as checks written before row 192, not faults in
|
||||
NEW, and Mos passed them (mos-1135). Matrix line (g) isn't byte-identical, for a known cause, and Mos passed it
|
||||
(mos-1137). Nobody acted as Jason. There was no `--by jason`, no pi, no Save and no `mosaic name`, and
|
||||
`bus.tester` was not touched.
|
||||
|
||||
## Stamps and activation
|
||||
|
||||
| Step | Start (UTC) | Result |
|
||||
| --- | --- | --- |
|
||||
| P1 values, business-check OLD | file written 21:43:13Z | values as planned, LOAD_OK (`p1.txt`) |
|
||||
| W0 copy NEW with npm ci, business-check NEW | 21:45:57Z | copied, lockfile diff empty, LOAD_OK (`w0.txt`) |
|
||||
| P2 console-check on a stub of NEW | 21:46:09Z | CONSOLE_PASS without and with `--tester-port` (`p2.txt`) |
|
||||
| P3 rehearsal (Mos) | 21:52:31Z to 21:52:34Z | REHEARSAL_PASS, rc 0 (`p3/`) |
|
||||
| P3 flags check (Mos) | 21:53:52Z to 21:53:56Z | NEW Console with the pointer flags on 7341/7342: healthz 200 both, then gone, 0 listeners |
|
||||
| P4, P5, P6 | 22:00:17Z | P4 PASS, P5 PASS (HEAD 4385b9ec1), `matrix-old.txt` |
|
||||
| W0b business file copy | 22:00:49Z | sha256 1e49bdf0 |
|
||||
| W1 idle check, S1 | 22:00:49.758Z | chief idle; S1 a7649760 |
|
||||
| W2 status | 22:00:49.819Z | pointer OLD, pm true, 3i, unit flags match |
|
||||
| W3 plan | 22:00:50.068Z | exit 0 (`W3-plan.txt` 45de68d4) |
|
||||
| W4 unit read | 22:00:50.238Z | OLD units, no drop-ins, bus `--pm`, no quote or backslash |
|
||||
| W5 activate (mos-1113) | 22:02:06.776Z, end 22:02:09.556Z | exit 0, gate passed, activate ok |
|
||||
| W5 status | 22:02:13.885Z | pointer NEW, pm true, 3i, unit flags match |
|
||||
| W9 checks and turns (mos-1114) | 22:05:51Z to 22:06:06Z | pass |
|
||||
| W9b run end and S2 | 22:21:05.171Z, S2 22:21:07Z | ended by the launcher (thread-idle); S2 1a444f5a |
|
||||
| W10 browser (stop), diagnosis | 22:29:14Z, 22:30:02Z | 10 of 12, then both failures traced to the checks |
|
||||
| W10 matrix, P4 (mos-1135) | 22:31:29Z | a-f identical, g +121 bytes; P4 PASS |
|
||||
| W11 reads | 22:44:33Z to 22:44:34Z | units, tunnel, business file, failed units |
|
||||
|
||||
Activation id 20261020T220206Z-4429a104f6d6. Pointer `at` 2026-10-20T22:02:09Z.
|
||||
|
||||
## Backups and hashes
|
||||
|
||||
- Store backup: `~/.mosaic-dev/backups/stack/20261020T220206Z-4429a104f6d6`, SHA256SUMS sha256
|
||||
b61d64843c9e2a153842606353450838da9cb778c8f3b9c27cc9366dd72ec0c9.
|
||||
- Rollback set: `~/.mosaic-dev/state/stack-rollback/20261020T220206Z-4429a104f6d6`. Rollback goes to 490e2771d.
|
||||
- Business file: 1e49bdf05e62607972958f5b7298cfd600c7825812370e26d7c2a842f2af9b93 at P1, at W0b and again at
|
||||
W11. The W0b copy is `~/.config/mosaic-dev/businesses/mosaic-stack.json.pre-window-20261020T220049Z` with the
|
||||
same hash. Nothing in the window wrote it. `backups.txt` holds the W0b and W5 lines.
|
||||
|
||||
## Pointer before and after
|
||||
|
||||
Before (W2): copy 490e2771d3d0, pm true, schema 3i, activation 20261020T192956Z-490e2771d3d0. Console flags
|
||||
`--port 7332 --public-host mosaic.woltje.com --auth-header X-authentik-username --allow-user jason.woltje
|
||||
--tester-port 7333`.
|
||||
|
||||
After (W5, W9 and W11): copy 4429a104f6d6, pm true, schema 3i, activation 20261020T220206Z-4429a104f6d6. The
|
||||
Console flags are the same, with no `--send`, no `--sso` and no proof pair. Bus pid 2950923 and Console pid
|
||||
2950925, both since 22:02:08Z. Status shows drift of 6 commits on refactor since the pointer's copy (records).
|
||||
|
||||
## Unit ExecStart lines (no Environment values)
|
||||
|
||||
W11, after. Both units active, DropInPaths empty, WorkingDirectory the NEW copy:
|
||||
|
||||
```
|
||||
bus: ~/.local/share/mosaic-stack/copies/4429a104f6d65ccf165f6c83b5d1dce3147dfde0/scripts/mosaic bus start mosaic-stack --pm (MainPID 2950923)
|
||||
webui: /usr/bin/node ~/.local/share/mosaic-stack/copies/4429a104f6d65ccf165f6c83b5d1dce3147dfde0/packages/webui/src/cli.mjs serve --checkout /mnt/storage/src/mosaic-stack --port 7332 --public-host mosaic.woltje.com --auth-header X-authentik-username --allow-user jason.woltje --tester-port 7333 (MainPID 2950925)
|
||||
```
|
||||
|
||||
W4 read the same two lines on OLD's copy (W.txt 329-344). The bus Environment has 2 assignments with no quote or
|
||||
backslash. The values are not recorded. The Console's cwd is the NEW copy (W9). The webui journal since W5 has one
|
||||
"Proxy: proxy proof off" line and no "Sign-in:" line.
|
||||
|
||||
Tunnel: `mosaic-preview-tunnel.service` active, running, MainPID 1317, since 2026-10-13 08:40:19 CDT. The window
|
||||
didn't touch it. P4 before and after shows one R: spec, `R:0.0.0.0:7332:127.0.0.1:7332`.
|
||||
|
||||
## S1, S2 and the store
|
||||
|
||||
S1 (`S1.json`, sha256 a7649760c3439705c8b5f3af26d0c21aea1081c1eb295fd02aef3a642064194b) is W1's held read at
|
||||
22:00:49Z. S2 (`agents/sage/work/window-repin-4429a104f/S2.json`, sha256
|
||||
1a444f5ac0049bc78e397b6928e1008cfe8cbc30989bbf2042b4ed27f56a4173) is the held read after the assistant run
|
||||
ended, at 22:21:07Z. Both are 3i. SNAP (`snapshot.mjs`, 639fd28a) was checked before each.
|
||||
|
||||
| Table | S1 rows | S2 rows | S2 vs S1 |
|
||||
| --- | --- | --- | --- |
|
||||
| decisions, decision_events | 21, 21 | 21, 21 | same sha256 |
|
||||
| meta, instance_names, thread_opens | 3, 0, 0 | 3, 0, 0 | same sha256 |
|
||||
| deliveries | 1726 | 1740 | +14 |
|
||||
| events | 1525 | 1543 | +18 |
|
||||
| role_claims | 98 | 101 | +3 |
|
||||
| messages | 567 | 571 | +4 (counts only) |
|
||||
| message_threads | 2 | 4 | +2 (counts only) |
|
||||
| usage_records | 30 | 34 | +4 |
|
||||
| projects, threads, thread_claims | 1, 1, 2 | 2, 2, 4 | +1, +1, +2 |
|
||||
| task_snapshots | 401 | 408 | +7 |
|
||||
| task_comment_cursors | 215 | 220 | +5 |
|
||||
|
||||
For every grown table with a seq, maxSeq grew by exactly the row delta.
|
||||
|
||||
The task_snapshots and task_comment_cursors rows (mos-1128 item 2). The writer is the bus's own Vikunja poll, not
|
||||
an agent. `packages/bus/src/process.mjs:104` loads the tasks adapter. Its timer runs `tick` every `pollSeconds`
|
||||
(`packages/tasks/src/adapter.mjs:192-197`), and `sync.mjs:169` calls `broker.recordTask` with no cap
|
||||
(`packages/bus/src/broker.mjs:1123`). That writes `source 'poll'` with role and run null (`broker.mjs:1159-1174`)
|
||||
and the comment cursors (`:1131-1138`). The adapter logs only on an error (`adapter.mjs:115`), so the bus journal
|
||||
has no line for a good tick. That's why there's no sync line between 22:05Z and 22:22Z. The rows, read
|
||||
read-only after the window:
|
||||
|
||||
- task_snapshots 402-404 at 22:05:08Z: P19 436, 435 and 434, all updated 22:04:55-56Z. 405-406 at 22:12:38Z: 438
|
||||
and 437. 407 at 22:17:08Z: 438 again. 408 at 22:19:08Z: 431. All have `source poll`, `via cursor`, role null
|
||||
and run null. These are tracker edits made by seats during the window, which the poll picked up.
|
||||
- task_comment_cursors 216-220: tasks 424, 432, 438, 431 and 436, last comments 397 to 401. These are the
|
||||
comments seats posted on P19 in the same minutes (398 is Mos's comment on #432).
|
||||
|
||||
Rows after S2 (task_snapshots 409 at 22:33Z, cursors 221-223) are the same poll and are outside the window.
|
||||
|
||||
## W9 output
|
||||
|
||||
- Status, console-check (CONSOLE_PASS), the journal counts, the Console cwd and one running chief from this
|
||||
start (r097436c91816) all passed.
|
||||
- `talk chief --tester` (c5b43f04): the chief replied that a tester message authorizes nothing and it took no
|
||||
action.
|
||||
- Project `window-20261020-2205`, thread 446201de-e8b5-4df3-9356-d0d5422cc899. `talk --thread` (b4b66ced) got one
|
||||
assistant reply from run r497f1c817d4d. `thread read` shows the tester REQUEST and the assistant RESULT.
|
||||
- `threads`, `names` (empty) and `usage` read fine. The human-thread probe was skipped: S1's one thread is the
|
||||
177-185 window's tester thread d0ba7a66, so no human thread exists.
|
||||
- W9b: the launcher logged launch at 22:06:00.766Z, thread-idle at 22:21:05.149Z and end at 22:21:05.171Z
|
||||
(reason stopped, exit 0). Nobody stopped it by hand.
|
||||
|
||||
## W10
|
||||
|
||||
The browser check (`w10-browser.mjs`, dda57ccf) ran against 127.0.0.1:7333 with fetch and XHR limited to GET and
|
||||
HEAD. It made no writes and sent no W9 thread request. 10 of 12 checks passed. The two that failed:
|
||||
|
||||
1. "Only tester forms": `#sign-out` was in the list. It is row 192's form at `packages/webui/src/public/index.html:12`,
|
||||
`hidden`. `app.js:479` shows it only when `/api/config` has `sso: true`. The live config has no `sso`
|
||||
key, and the form stayed hidden.
|
||||
2. "Chat lists the W9 thread": the check read only the first `ul.chat-thread-list`. `chat.js:93` renders one list
|
||||
per project, and W9 made the second project. The diagnosis (`w10-diag.mjs`, 42d0844b) read every panel and
|
||||
found 446201de listed.
|
||||
|
||||
Both checks come from the 177-185 window (Darkwing's `window-rows-177-185/w10-browser.mjs`), written before row
|
||||
192 and before a second thread project existed. Corrected, they now read:
|
||||
|
||||
- Only tester forms, allowing `#sign-out` when it is `hidden` and `/api/config` has no `sso: true`.
|
||||
- The W9 thread is in some `.chat-projects section.panel` thread list, not only the first.
|
||||
|
||||
Both corrections are in the plan's W10 line, for the next window that copies this one.
|
||||
|
||||
The matrix (`matrix-new.txt` against `matrix-old.txt`). Lines a to f are byte-identical. Line g is 200 non-json
|
||||
both times, but 6454 bytes on OLD and 6575 on NEW. `index.html` is 6470 bytes at 490e2771d and 6591 at 4429a104f,
|
||||
+121, and the only hunk is the line 12 form. The served page grew by the same 121. The plan's W10 line now says a
|
||||
line for a file the pin changes isn't "identical", with this case as its example. P4 again at 22:31:29Z: PASS.
|
||||
|
||||
## Failed user units (mos-1128 item 3)
|
||||
|
||||
All three predate the re-pin at 22:02Z and come from the legacy `~/.mosaic` and jarvis-brain setup, not the
|
||||
stack. P19 #393, "dragon-lin: seven legacy user units in failed state", covers all three (filed by Mos on
|
||||
10-20 at about 01:42Z). It has no comments yet. The current failure times are later than the ones #393 lists,
|
||||
so I added a comment with them. Times are from `systemctl --user show` (CDT) with UTC alongside.
|
||||
|
||||
| Unit | Runs | Failed | #393 |
|
||||
| --- | --- | --- | --- |
|
||||
| mosaic-standup-pm.service | `~/.mosaic/tools/coordinator/standup_trigger.py pm` | 2026-10-19 19:00:28 CDT (10-20 00:00:28Z), exit 1 | listed |
|
||||
| mosaic-install-drift.service | `~/src/jarvis-brain/scripts/alerting/mosaic-install-drift` | 2026-10-20 00:12:54 CDT (05:12:54Z), exit 9 | listed, with an older time |
|
||||
| mosaic-unit-failed@mosaic-reconcile.service | `~/.local/bin/mosaic-unit-failed mosaic-reconcile.service` | 2026-10-20 13:16:12 CDT (18:16:12Z), exit 4 | listed, with an older time |
|
||||
|
||||
The marker's journal at 18:16:12Z says the escalation's tmux send to jarvis failed ("tmux target not found",
|
||||
socket mosaic-fleet), so the page wasn't delivered. The record is on disk in
|
||||
`~/.local/state/mosaic-unit-failures/20261020.jsonl`. `mosaic-reconcile.service` failed at that time (exit 7)
|
||||
but last ran OK at 17:16:27 CDT (22:16:27Z). The marker stays failed until something resets it. The journal no
|
||||
longer has lines for the other two units. The window changed none of these units, and touching them is
|
||||
outside it (`~/.mosaic` is off limits, and #393 needs Jason or ops-01's charter to disable any). W11's list also
|
||||
shows `setspark-tmp-guard.service` failed. It belongs to another project, and I've left it.
|
||||
|
||||
## Corrections to the plan, made after the window
|
||||
|
||||
- NEW is 103 commits past OLD (`git rev-list --count 490e2771d..4429a104f`), not 106. The 106 in `status` was OLD
|
||||
to HEAD 305857c8f, so it also counted the three record commits.
|
||||
- P3: `rehearse` starts NEW's Console with only `--port` and `--business`, not the pointer's flags. Mos's
|
||||
separate flags check covers that (`p3/flags-check.txt`, `p3/flags-console.log`). The line was wrong as
|
||||
written (mos-1107).
|
||||
- W10: the matrix line g size change and the two corrected browser checks, as above.
|
||||
|
||||
## Files
|
||||
|
||||
`W.txt` (transcript), `S1.json`, `S2.json`, `matrix-old.txt`, `matrix-new.txt`, `backups.txt`, `W3-plan.txt`,
|
||||
`W5.txt`, `W5-status.txt`, `w0.txt`, `p1.txt`, `p2.txt`, `p3/` (Mos's rehearsal and flags check), `p456.sh`,
|
||||
`w9.sh`, `w9b.sh`, `w9.out`, `w9b.out`, `w10-browser.mjs`, `w10-diag.mjs` with their outputs (the three
|
||||
screenshots stay on disk in this directory, uncommitted, since the push check refuses binaries),
|
||||
and the `.w9*`, `.w10*` and `.w11*` reads. The store snapshot tool is `snapshot.mjs` (639fd28a).
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,116 @@
|
||||
plan: activate for mosaic-stack
|
||||
from: 490e2771d3d057ab76991e2c7859cd251857e64c
|
||||
to: 4429a104f6d65ccf165f6c83b5d1dce3147dfde0
|
||||
store schema: 3i (read from the store the running bus holds)
|
||||
target schema: 3i
|
||||
migration: none; the store is at the target's version
|
||||
backup: the run backs up the stopped store to /home/jwoltje/.mosaic-dev/backups/stack/<activation>/ before any migration
|
||||
commits: the run adds 103 (newest first, at most 200):
|
||||
4429a104f webui: Q175 phase 1, the Console verifies SSO itself under --sso, OIDC RP with oauth4webapi 3.8.8 (row 192, #1690)
|
||||
32b54ac3b plans: Case 2 row briefs from Gosalyn's 51006710a (webby-0034 N1/N2 and webby-0035: row A README :711 one line per variable, C2-13 owns README :713 and says the precheck prints only variable names)
|
||||
6025ddd9c plans: Case 2 row briefs from Gosalyn's a2d94b2c2 (Webby r9 notes, webby-0032: row A README line on claude-session.env and the dist/providers/data/zai.json path, C2-13 XDG_DATA_HOME precheck and last-assignment-wins key file parse)
|
||||
ecbfd6deb plans: Case 2 row briefs from Gosalyn's 29e85196b (design r9 for mos-1090: row A out of scope points at design 10 step 2d, C2-13 precheck checks the hub key file by name and mode, claude marker check only for claude-code harness, EnvironmentFile= fixed in case2-unit.sh)
|
||||
0498c0613 agents: Gosalyn seat dir, README from gosalyn/case2-design, so Case 2 rows can name the seat as owner (#416)
|
||||
49d1f3a23 plans: Case 2 slice row briefs plus rows A and B, from Gosalyn's f325657c7 on gosalyn/case2-design (#416, design r8, C2-13 copy id and profile asks for row 195, C2-20 count-only note, row A ZAI_API_KEY per mos-1086/mos-1089, row B #428 after 10-27)
|
||||
628e2ca5c sessions: Filbert row 190 manifest round 1 CHANGES (base drift on row 189)
|
||||
088087ac9 queue: revs 2248-2361+. Sage: rows 210 (#424 host access, Gizmoduck) and 211 (#426 force-push guard, Rocko) added and briefed; row 195 re-briefed to the Case 1 install on .53; review requests for 200 r1/r2 and 202; plus earlier Sage revs. Other seats' revs: Launchpad 2254, 2283-2284, 2286, 2311-2313, 2328-2329, 2344, 2347-2348 (rows 192/200); Honker 2255; Morgana 2257, 2320, 2326-2327 (row 204); Gander 2262; Herb 2265; Dewey 2268; Bushroot 2273; Megavolt 2276; Webby 2303, 2316, 2339, 2355 (row 192/200 verdicts); Gizmoduck 2304, 2318-2319 and the row 210 claim (rows 201/210); Quackerjack 2317, 2341-2342 (row 202); Duckworth 2323, 2335, 2353 (rows 201/204/202 verdicts); Darkwing 2354, 2357 (row 190 in-review)
|
||||
a0fbefd48 plans: pre-push force-push hook and failing busy check brief (Vikunja #426, mos-1078, mos-1083; owner Rocko, reviewer Dewey)
|
||||
f24f2cd40 plans: row 195 brief becomes the Case 1 install on 10.1.1.53 (Q181 hosts, Q182/Q183 recorded acceptance, Q185 existing account, chained on rows 190 and C2-13; ops-01 root steps under #423 step 1; sage-1439)
|
||||
9ba31b5b3 agents: Honker's PRD 1.7 draft r2 on refactor for the prd.approve raise (11cb0423b, sha256 e896746df595d1b5155130ca163fbf63b0dc38a87a8dd154af77f1a6d1328647, Duckworth approved duckworth-0039, Vikunja #420)
|
||||
9db578ff5 plans: agent host access with sudo through the credential store brief (#1707, Vikunja #424, Q183/Q184, chained on row 199)
|
||||
8eb9ddd12 plans: FED R8 brief to r4.11 (b93f098f0, recorded acceptance, Duckworth N1/N2, #416 date), R5 context source (sage-1419), 193a makes covers level required (duckworth-0033 N1)
|
||||
ae3c36f24 agents: Gizmoduck seat dir and roster row (FED R1 owner, #414)
|
||||
a2af7ab49 plans: FED R1, R5, R2 and R8 briefs (#414, r4.9 a1daa3c07) and row 193a-d build briefs (#1691); Quackerjack seat dir and roster row
|
||||
aa1bd209e gate-lane: row 189 gate timing table for row 197 (Herb)
|
||||
ace27dc5e row 189 (#1687): stack-release.sh activate --no-send drops the Console's --send (Sage; Dewey approve 29485; Sage gate passed)
|
||||
a4a42dbac plans: stack-release --sso brief (#1698, Launchpad, reviewer Webby, row 192 F3; chained on 192)
|
||||
a31f1a0f8 plans: row 198 brief records Mos's call, in-process board reads behind the Console's auth (mos-1019)
|
||||
992650232 plans: agent credentials and git identity brief (MVP T1 item 6, #1697, Megavolt, reviewer Duckworth); Megavolt seat dir
|
||||
a7661ada0 plans: row 195 acceptance script takes Gizmoduck's gate item list; B8 issuer and TLS front end (mos-1011)
|
||||
f871cb309 plans: retire the control board writer on 7331 brief (#1696, Bushroot, reviewer Webby, mos-1008 item 2); Bushroot seat dir
|
||||
0bbd23c61 plans: row 195 brief adds the identity provider check and flags any new model account for Jason (mos-1008)
|
||||
0217b71c8 plans: row 195 brief rewritten as the hub on its own host, host left to Jason (#1693, mos-0998, mos-1005)
|
||||
c6f528a32 plans: second gate lane brief (#1695, Herb, reviewer Webby, mos-0977 item 6); Herb seat dir; gate template and busy check copies for the row
|
||||
96f243faf plans: human boundary row brief (P19 333, #1694, Gander, reviewer Duckworth, mos-0989); Gander seat dir; seat READMEs name the credentials row, not row 195 (now 190b)
|
||||
c86269935 sessions: Filbert row 190 design review r3, approved
|
||||
48ebee0ff plans: row 190 brief scopes isolation to addressing on one uid, points to row 190b (Filbert N7, mos-0986)
|
||||
66bdd84b8 sessions: Filbert row 190 design review r2, changes requested
|
||||
6966164f0 plans: row 190b brief, Melanie's hub under its own Linux user (#1693, Darkwing, reviewer Duckworth), mos-0986
|
||||
53bb59462 sage: common start for MVP T1 builder seats (mos-0974, mos-0977, mos-0981)
|
||||
5e01c3683 agents: seat dirs and roster rows for Launchpad, Morgana, Honker (Sage's T1 builders) and Webby, Duckworth (Mos's reviewers); row 193 brief takes Mos's B1 starting rule (mos-0985)
|
||||
9f56d2098 plans: rows 192 and 194 review by Webby, not Filbert or Dewey (mos-0981)
|
||||
0599b119f plans: MVP T1 briefs, SSO phase 1 (#1690, Launchpad), human users (#1691, Morgana), agent lifecycle (#1692, Honker), mos-0974/0977
|
||||
b416d2ede sage: Q175 SSO design, Mos C1 condition (mos-0977): straggler check before Jason step 4 in the phase 2 window
|
||||
5fc73a729 revs 2237-2247: row 189 added, briefed, started, in-review round 1 (Dewey, comment 29457); rows 190 (Darkwing) and 191 (Rocko) added and briefed for MVP T1 (mos-0974); darkwing-190-start (rev 2245, Darkwing's) and rocko-191-start (rev 2244, made for Rocko)
|
||||
99772421a sage: row 189 candidate manifest for Dewey's review (d6116771f)
|
||||
da230ca48 plans: MVP T1 briefs, several instances per host (#1688, Darkwing) and the kill switch (#1689, Rocko), mos-0974
|
||||
4f2d1be68 sessions: Filbert Q175 SSO design D1/D2 ack
|
||||
d55d86bb0 sage: Q175 SSO design r3 fix, Filbert r3 D1 (loader checks slot shape only) and D2 (slot from config dir, scratch Console dataRoot and unreachable issuer)
|
||||
c56ccf916 sessions: Filbert Q175 SSO design review r3, approve with D1
|
||||
817e8f51b sage: Q175 SSO design r3 for #412, Filbert r2 C1 (shared loader, config.json inside the phase 2 window, rollback order, test 25) and C2 (401 signed-out page, test 24), notes and Q-E
|
||||
5d019d876 sessions: Filbert Q175 SSO design review r2, changes
|
||||
59475fc5a sage: row 163 landing record, P19 comments 372/373 on 337/412, and P19 #413 filed for the --no-send row
|
||||
1a268249e sage: Q175 SSO design r2 for #412, Filbert r1 B1-B6, rulings Q-B/Q-C/Q-D, config in config.json (mos-0973)
|
||||
def2e7932 plans: brief for stack-release activate --no-send (Q175 interim, mos-0972/0973, #1687, P19 413)
|
||||
c30b36fff sessions: Filbert Q175 SSO design review r1, changes
|
||||
9ae8c73ac queue: revs 2235-2236: row 163 Sage landing note (8ecc7a239, patch-id b8d5f8a37c24, gate passed on eaa0f2666) and done
|
||||
8ecc7a239 row 163 (#1660): stack-release.sh rehearse, the D2 rehearsal on a scratch root from a backup, and bus start --no-launch (Sage; Filbert approve 29447; Sage gate passed)
|
||||
7f57419b3 sage: Q175 SSO design for #412, OIDC relying party on oauth4webapi 3.8.8, for Filbert review (mos-0970, mos-0971)
|
||||
4ca8d6e94 sage: row 42 run log, S7 reachability pass (51cebff7 answered by cff1e9ad after a chief launch, mos-0969)
|
||||
22e5e825b sage: row 42 run log, plain mosaic on a pinned host supersedes the 10-12 full-path line (mos-0968)
|
||||
e6dea74b2 sessions: Sage row 163 r2 approval intake; P19 337 comment 368 script and record
|
||||
cd2b377bb queue: rev 2234: row 163 r2 approve from Filbert (op filbert-163-r2, comment 29447, candidate c6f4f4c12596)
|
||||
ceccb0ef2 sessions: Filbert row 163 r2 review, approve
|
||||
10ab8ea62 sessions: Sage row 163 r2 in-review; P19 337 comment 367 script and record
|
||||
c539995cf queue: revs 2231-2233: row 163 r2 in-review from Sage (ops sage-163-r2-start, sage-163-inreview-2, .outcome; request comment 29446, reviewer Filbert, manifest c6f4f4c12596)
|
||||
92cc6011c queue: rev 2230: row 163 r1 changes from Filbert (op filbert-163-r1, comment 29445, candidate 430212299beb)
|
||||
7af166574 sage: row 163 r2 packet (candidate 2c090eefd on code 2a5f3a3a0, base 4f02486d5: diff, manifest c6f4f4c12596, gate passed, mutants K34-K41 killed)
|
||||
2244e8baf sessions: Filbert row 163 r1 review, changes
|
||||
bde0fdec9 sessions: Sage row 163 r1 in-review; P19 337 comment 366 script and record
|
||||
def677bc7 queue: revs 2228-2229: row 163 r1 in-review from Sage (ops sage-163-inreview-1, .outcome; request comment 29444, reviewer Filbert, manifest 430212299beb)
|
||||
51f67f1f8 sage: row 163 packet (candidate 4be3f6aec on 580500699: diff, manifest 430212299beb, gate passed, mutants K1-K33 killed after four survivors got tests)
|
||||
5b298bd00 sessions: Dewey row 66 r1 (changes) and r2 (approve) reviews
|
||||
565bc32c2 queue: revs 2223-2227: row 66 r2 round from Sage (2223-2225, ops sage-r66-r2-start, sage-r66-inreview-2); r2 verdicts from Filbert (2226, op filbert-66-r2, approve) and Dewey (2227, op dewey-66-r2, approve)
|
||||
5140aa9e8 sessions: Filbert row 66 r2 review, approve
|
||||
973cb5a87 queue: revs 2220-2222: row 163 Sage start (2220); row 66 r1 verdicts from Filbert (2221, op filbert-66-r1) and Dewey (2222, op dewey-66-r1)
|
||||
b82ec9353 sage: row 66 r2 packet (candidate 0f4a57956: diff, manifest cee63e06fdea, gate, mutants K1-K4 killed, singles rerun)
|
||||
3560c450a sessions: Filbert row 66 r1 review, changes
|
||||
4f02486d5 sage: row 66 r1 packet (candidate 8ec03b45a: diff, manifest e68c6bce5ec4, gate r2), row 42 run log (trigger (a), mos-0960), SESSIONS line
|
||||
263ea8a9a queue: revs 2215-2219: row 66 Sage start (2215), in-review round 1 on candidate manifest e68c6bce5ec4 (8ec03b45a) and request comment 29437 (2216-2217); row 163 brief re-pinned to b1500d96ad27 (6020bb43a) and briefed (2218-2219)
|
||||
6020bb43a plans: D2 brief owner is sage (row 163, #1660), and D2 lands after the Part B window (mos-0958, mos-0959)
|
||||
5487ed39d sage: row 188 landing record: P19 411 (N1) and comments 361-363 script and record, 409/410 description restore after a partial done update, SESSIONS line
|
||||
31e328958 queue: revs 2209-2214: row 188 Darkwing start, in-review and request 29432 (2209-2211); Filbert approve 29433 (2212); Sage landing note (8fc0ee216, patch-id c9a56b167c07, stack-release.sh blob 2586a2a37cd2, gate passed) and done (2213-2214)
|
||||
8fc0ee216 row 188 (#1686, P19 409, 410): stack-release T54, the proof file checks on a carried pair and a proof file inside the repository (Darkwing; Filbert approve 29433; Sage gate passed)
|
||||
23a609c5c sessions: Filbert row 188 r1 review, approve
|
||||
b9c1c9fe2 sage: Part B draft 2 A2 passed (mos-0958), row 188 launched, Vikunja comments 358-360 script and record, SESSIONS line
|
||||
525990ecb queue: revs 2207-2208: row 188 add and briefed (Sage), #1686, P19 409/410, gates Part B (mos-0956)
|
||||
148a9503d sage: Part B window file draft 2 for mos-0957 (F1: B6 and B-R1 name the stop's endLaunch rows, PB5 counts per step; F2: PB6, PB7 and B-R1 matrices run (a)-(h)); Q2 answered, Q1 to Jason's list
|
||||
240f21650 brief: stack-release tests for a carried proof pair and a proof file inside the repository (P19 409, 410, #1686, mos-0956)
|
||||
742e98976 sage: Part B window file, the read window's end stamp from the clock (10:29Z, not 10:40Z)
|
||||
288ab1b5a sage: Part B window file for Mos's A2 check (live-copy B3 and B-R1, Q1 on J2 order), SESSIONS lines for Darkwing (row 187, 10:25:22Z) and Sage
|
||||
a843ae284 sage: row 187 landing, P19 407-410 filed and P19 385 comment 357, #1685 closed (comment 29425), SESSIONS line
|
||||
652d6f3a8 queue: revs 2201-2206: row 187 Darkwing start, in-review and request comment 29423 (2201-2203); Filbert approve comment 29424 (2204); landing note (9a71e4e80, patch-id 6b57c47bc661, gate passed) and done (Sage 2205-2206)
|
||||
9a71e4e80 row 187 (#1685): activate sets, carries and drops the Console's proof pair
|
||||
d17328a55 sessions: Filbert row 187 r1 review, approve
|
||||
f81ebfbae sage: row 186 follow-ups filed as P19 405 and 406, P19 404 closed (mos-0955)
|
||||
9760d4967 sage: row 186 landing, P19 404 comment 354 and SESSIONS line, with Darkwing's row 186 SESSIONS line (09:13:21Z)
|
||||
16a936c79 queue: revs 2198-2200: row 186 Filbert approve comment 29419 (2198); landing note (269134d8d, patch-id c97b9f6e25cd, gate passed) and done (Sage 2199-2200)
|
||||
269134d8d row 186 (#1684): the activate plan's backup line says what the run will do
|
||||
3c5da3a91 sessions: Filbert row 186 r1 review, approve
|
||||
b367f5730 sage: rows 186-187 Vikunja comments (P19 404 351, P19 385 352-353) and SESSIONS line (mos-0954)
|
||||
5a768d82c queue: row 187 added and briefed (Part B A0, #1685), with Darkwing's row 186 start (rev 2193)
|
||||
6de3c86be plans: brief for row 187, activate carries the row 178 proof pair (mos-0928 Part B A0, #1685)
|
||||
1d7fd75e2 queue: row 186 added and briefed (P19 404, #1684)
|
||||
f5c72a5c3 plans: brief for row 186, the activate plan's backup line (P19 404, #1684)
|
||||
b724b7b0b sessions: Sage Part A window line, with Darkwing's 06:53:53Z and 08:28:01Z lines
|
||||
e24a13ad8 sage: Vikunja scripts and read-back records 2026-10-13 to 10-20 (decision 110, mos-0882)
|
||||
21aa1cab0 darkwing: re-pin window rows 177-185 packet, STATE.md (sha256 b586f11c9b6f1329), W.txt (edd4622c5c45ef3f), S1/S2/S2b/B snapshots, matrices, W10 browser check and P3 rehearsals (#1683; P19 386)
|
||||
9ddd8a92c plans: repin-rows-177-185 draft 4, R1 snapshot after the plain rollback (mos-0943)
|
||||
e7637b99c plans: repin-rows-177-185 draft 3, R1post expects one tester action.refused per refused read (mos-0935, mos-0942)
|
||||
2ea05700b plans: mos-0928 plan draft 2, NEW is the row 185 landing 490e2771d
|
||||
010666074 queue: revs 2185-2190: row 185 start and in-review on bf87dbba with request comment 29403 (Darkwing 2185-2187); Filbert approve comment 29404 (2188); landing note (490e2771d, patch-id 774cd23186d5, gate passed) and done (Sage 2189-2190)
|
||||
bus: scripts/bus-service.sh install --copy 4429a104f6d65ccf165f6c83b5d1dce3147dfde0 --copies /home/jwoltje/.local/share/mosaic-stack/copies --pm --claude /home/jwoltje/.local/bin/claude
|
||||
proof: off
|
||||
send: off
|
||||
Console: scripts/webui-service.sh install --copy 4429a104f6d65ccf165f6c83b5d1dce3147dfde0 --copies /home/jwoltje/.local/share/mosaic-stack/copies --port 7332 --public-host mosaic.woltje.com --auth-header X-authentik-username --allow-user jason.woltje --tester-port 7333
|
||||
CLI: scripts/stack-copy.sh wrapper 4429a104f6d65ccf165f6c83b5d1dce3147dfde0 --copies /home/jwoltje/.local/share/mosaic-stack/copies --bin /home/jwoltje/.npm-global/bin
|
||||
@@ -0,0 +1,21 @@
|
||||
pointer: /home/jwoltje/.mosaic-dev/state/stack-active.json
|
||||
{"copy":"4429a104f6d65ccf165f6c83b5d1dce3147dfde0","business":"mosaic-stack","pm":true,"claude":"/home/jwoltje/.local/bin/claude","console":["--port","7332","--public-host","mosaic.woltje.com","--auth-header","X-authentik-username","--allow-user","jason.woltje","--tester-port","7333"],"schema":"3i","activation":"20261020T220206Z-4429a104f6d6","at":"2026-10-20T22:02:09Z"}
|
||||
log (last five lines):
|
||||
{"at":"2026-10-20T07:58:02Z","op":"activate","from":"89af38a83afa22a8a4f0d368a0a4030ad15a0efa","to":"490e2771d3d057ab76991e2c7859cd251857e64c","backup":"20261020T075800Z-490e2771d3d0","activation":"20261020T075800Z-490e2771d3d0","result":"ok"}
|
||||
{"at":"2026-10-20T19:29:56Z","op":"activate","from":"490e2771d3d057ab76991e2c7859cd251857e64c","to":"490e2771d3d057ab76991e2c7859cd251857e64c","backup":null,"activation":"20261020T192956Z-490e2771d3d0","result":"started"}
|
||||
{"at":"2026-10-20T19:30:00Z","op":"activate","from":"490e2771d3d057ab76991e2c7859cd251857e64c","to":"490e2771d3d057ab76991e2c7859cd251857e64c","backup":"20261020T192956Z-490e2771d3d0","activation":"20261020T192956Z-490e2771d3d0","result":"ok"}
|
||||
{"at":"2026-10-20T22:02:06Z","op":"activate","from":"490e2771d3d057ab76991e2c7859cd251857e64c","to":"4429a104f6d65ccf165f6c83b5d1dce3147dfde0","backup":null,"activation":"20261020T220206Z-4429a104f6d6","result":"started"}
|
||||
{"at":"2026-10-20T22:02:09Z","op":"activate","from":"490e2771d3d057ab76991e2c7859cd251857e64c","to":"4429a104f6d65ccf165f6c83b5d1dce3147dfde0","backup":"20261020T220206Z-4429a104f6d6","activation":"20261020T220206Z-4429a104f6d6","result":"ok"}
|
||||
check:
|
||||
bus: /home/jwoltje/.local/share/mosaic-stack/copies/4429a104f6d65ccf165f6c83b5d1dce3147dfde0
|
||||
Console: /home/jwoltje/.local/share/mosaic-stack/copies/4429a104f6d65ccf165f6c83b5d1dce3147dfde0
|
||||
CLI: /home/jwoltje/.local/share/mosaic-stack/copies/4429a104f6d65ccf165f6c83b5d1dce3147dfde0
|
||||
result: pass
|
||||
bus status:
|
||||
host: mosaic-stack, pid 2950923, running, since 2026-10-20T22:02:08.133Z, notifier off
|
||||
socket: present
|
||||
writer.lock: pid 2950981
|
||||
boot: organization file loaded at 2026-10-20T22:02:08.125Z
|
||||
unit flags: match the pointer
|
||||
drift: 6 commit(s) on refactor since the pointer's copy
|
||||
# exit 0
|
||||
@@ -0,0 +1,8 @@
|
||||
stack-release: captured the rollback set: /home/jwoltje/.mosaic-dev/state/stack-rollback/20261020T220206Z-4429a104f6d6
|
||||
stack-release: stopped both units
|
||||
stack-release: stopped store schema: 3i
|
||||
stack-release: backup: /home/jwoltje/.mosaic-dev/backups/stack/20261020T220206Z-4429a104f6d6
|
||||
stack-release: installed 4429a104f6d65ccf165f6c83b5d1dce3147dfde0
|
||||
stack-release: gate passed on 4429a104f6d65ccf165f6c83b5d1dce3147dfde0
|
||||
stack-release: activate ok: 4429a104f6d65ccf165f6c83b5d1dce3147dfde0 is live for mosaic-stack
|
||||
# exit 0
|
||||
@@ -0,0 +1,2 @@
|
||||
W0b 2026-10-20T22:00:49Z business file copy /home/jwoltje/.config/mosaic-dev/businesses/mosaic-stack.json.pre-window-20261020T220049Z sha256 1e49bdf05e62607972958f5b7298cfd600c7825812370e26d7c2a842f2af9b93 (source /home/jwoltje/.config/mosaic-dev/businesses/mosaic-stack.json sha256 1e49bdf05e62607972958f5b7298cfd600c7825812370e26d7c2a842f2af9b93)
|
||||
W5 2026-10-20T22:02:13Z activation 20261020T220206Z-4429a104f6d6 backup /home/jwoltje/.mosaic-dev/backups/stack/20261020T220206Z-4429a104f6d6 SHA256SUMS sha256 b61d64843c9e2a153842606353450838da9cb778c8f3b9c27cc9366dd72ec0c9
|
||||
@@ -0,0 +1,7 @@
|
||||
a 200 ok=true
|
||||
b 401 error="sign-in required"
|
||||
c 401 error="sign-in required"
|
||||
d 403 error="proxy Host refused"
|
||||
e 403 error="tester listener required"
|
||||
f 403 error="proxy header refused"
|
||||
g 200 non-json 6575 bytes
|
||||
@@ -0,0 +1,8 @@
|
||||
# P6 2026-10-20T22:00:17Z
|
||||
a 200 ok=true
|
||||
b 401 error="sign-in required"
|
||||
c 401 error="sign-in required"
|
||||
d 403 error="proxy Host refused"
|
||||
e 403 error="tester listener required"
|
||||
f 403 error="proxy header refused"
|
||||
g 200 non-json 6454 bytes
|
||||
@@ -0,0 +1,4 @@
|
||||
copy 490e2771d: roles 6, projects 1, arbiters 2
|
||||
HOLDS chief instance.name yes
|
||||
HOLDS pm instance.name no
|
||||
LOAD_OK
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"bus.tester": true,
|
||||
"plugins": {
|
||||
"usage-source": [
|
||||
"transcript"
|
||||
],
|
||||
"channel": [
|
||||
"cli",
|
||||
"webui"
|
||||
],
|
||||
"harness": [
|
||||
"claude-code"
|
||||
]
|
||||
},
|
||||
"launch.by": "chief",
|
||||
"launch.instances has assistant": true,
|
||||
"roles with pi harness": [],
|
||||
"sha256": "1e49bdf05e62607972958f5b7298cfd600c7825812370e26d7c2a842f2af9b93"
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
start 2026-10-20T21:46:09Z
|
||||
business-check.mjs: OK
|
||||
console-check.sh: OK
|
||||
1ba3c7efbc84a1d7eb8ee0068d32b7917f4e75cdc4066703944cea4c20db5b93 /mnt/storage/scratch/sage-pin-de352dfaf/fixture/console-stub.mjs
|
||||
a4500094e7c7a6dc21797eaf2d696f9814f272ece945c2735b79e4593f9c9503 /mnt/storage/scratch/sage-p2-4429/console-stub-tester.mjs
|
||||
== run 1: pinned stub, no tester listener
|
||||
stub pid 2495939 port 39561
|
||||
PASS markdown-preview.js is served and equals the copy's
|
||||
PASS /api/config on loopback: send=false edit=false
|
||||
PASS project.files through the Console: head=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa files=2 spec=true error=none
|
||||
PASS project.file spec/north-star.md through the Console: commit=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa length=4 error=none
|
||||
PASS loopback save refused: HTTP 403 error=read-only sent=false
|
||||
CONSOLE_PASS
|
||||
PORT 39561
|
||||
CALLS []
|
||||
run 1 console-check rc=0
|
||||
== run 2: main listener plus a tester listener on a second port
|
||||
stub pid 2496085 port 35213 tester port 35945
|
||||
PASS markdown-preview.js is served and equals the copy's
|
||||
PASS /api/config on loopback: send=false edit=false
|
||||
PASS project.files through the Console: head=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa files=2 spec=true error=none
|
||||
PASS project.file spec/north-star.md through the Console: commit=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa length=4 error=none
|
||||
PASS loopback save refused: HTTP 403 error=read-only sent=false
|
||||
CONSOLE_PASS
|
||||
PASS main refuses x-mosaic-tester: HTTP 403 "tester listener required"
|
||||
PASS tester /api/config: HTTP 200 "tester":true
|
||||
PASS tester /api/config send and edit off: HTTP 200 "send":false,"edit":false
|
||||
PASS tester refuses the main auth header: HTTP 403 "proxy header refused"
|
||||
PASS tester refuses project-file save: HTTP 403
|
||||
PORT 35213
|
||||
TPORT 35945
|
||||
CALLS []
|
||||
TESTER_PASS
|
||||
run 2 console-check rc=0 tester rc=0
|
||||
end 2026-10-20T21:46:10Z
|
||||
@@ -0,0 +1 @@
|
||||
2026-10-20T21:52:34Z
|
||||
@@ -0,0 +1,10 @@
|
||||
flags-check start 2026-10-20T21:53:52Z
|
||||
pid 2729699 alive: yes
|
||||
127.0.0.1:7341
|
||||
127.0.0.1:7342
|
||||
main /healthz: 200
|
||||
tester /healthz: 200
|
||||
main /api/config: {"board":"http://127.0.0.1:7331","send":false,"edit":false}
|
||||
pid 2729699 after TERM: gone
|
||||
listeners after: 0
|
||||
flags-check end 2026-10-20T21:53:56Z
|
||||
@@ -0,0 +1,7 @@
|
||||
Mosaic Console: http://127.0.0.1:7341/
|
||||
Board: http://127.0.0.1:7331
|
||||
Bus: mosaic-stack
|
||||
Preview: https://mosaic.woltje.com/ through the proxy, signed-in user from x-authentik-username, read-only
|
||||
Proxy: proxy proof off
|
||||
Tester Console: http://127.0.0.1:7342/ (binds the tester)
|
||||
Ctrl-C stops this server.
|
||||
@@ -0,0 +1 @@
|
||||
rc=0
|
||||
@@ -0,0 +1,20 @@
|
||||
PASS copy: 4429a104f6d65ccf165f6c83b5d1dce3147dfde0, schema 3i
|
||||
PASS port: 127.0.0.1:7341 is free
|
||||
PASS backup: /home/jwoltje/.mosaic-dev/backups/stack/20261020T192956Z-490e2771d3d0 matches its SHA256SUMS
|
||||
PASS scratch-root: /home/jwoltje/.mosaic-dev/rehearsals/20261020T215231Z-4429a104f6d6/data from the backup, config and business file under /home/jwoltje/.mosaic-dev/rehearsals/20261020T215231Z-4429a104f6d6/config, business.diff beside them
|
||||
PASS data-root-live: /home/jwoltje/.mosaic-dev/rehearsals/20261020T215231Z-4429a104f6d6/data is not the live data root
|
||||
PASS sessions-live: no running session named in the data root
|
||||
PASS data-root-scratch
|
||||
PASS notify-off: binding null, so no Discord bridge
|
||||
PASS tracker-configured: bootConfig sets no trackers
|
||||
PASS credential-ref-live: 9 reference(s), each a placeholder
|
||||
PASS migration: not needed: the backup is already 3i
|
||||
PASS gate: host-up, bus-status, console-up, healthz and copy-match on 4429a104f6d65ccf165f6c83b5d1dce3147dfde0
|
||||
PASS no-session: no sessions.json and no launches under /home/jwoltje/.mosaic-dev/rehearsals/20261020T215231Z-4429a104f6d6/data
|
||||
PASS console-stopped: pid 2675437
|
||||
PASS host-stopped: pid 2675436
|
||||
PASS host-released-store
|
||||
PASS backup-unchanged
|
||||
PASS live-config-unchanged
|
||||
REHEARSAL_PASS
|
||||
rehearsal directory: /home/jwoltje/.mosaic-dev/rehearsals/20261020T215231Z-4429a104f6d6
|
||||
@@ -0,0 +1 @@
|
||||
2026-10-20T21:52:31Z
|
||||
@@ -0,0 +1,7 @@
|
||||
# P4 2026-10-20T22:00:17Z
|
||||
DropInPaths=
|
||||
ExecStart={ path=/home/jwoltje/.local/bin/chisel ; argv[]=/home/jwoltje/.local/bin/chisel client --fingerprint ce+ISFvMAhuoCRDuc7riIf+hYz87TLHk/C9C/H8QsUg= --keepalive 25s --max-retry-interval 10s http://10.1.1.227:8080 R:0.0.0.0:7332:127.0.0.1:7332 ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }
|
||||
# exit 0
|
||||
# R: specs (1): R:0.0.0.0:7332:127.0.0.1:7332
|
||||
P4 PASS: one R: spec R:0.0.0.0:7332:127.0.0.1:7332, DropInPaths empty
|
||||
rc 0
|
||||
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env bash
|
||||
# P4-P6 of agents/sage/work/window-plan/repin-4429a104f.md (f41729178), adapted from Darkwing's window-rows-177-185/p456.sh, read only.
|
||||
# P4 the tunnel unit, P5 the four REPO scripts against NEW, P6 the 7332 matrix on OLD (matrix-old.txt).
|
||||
# usage: p456.sh p4|p5|p6
|
||||
set -uo pipefail
|
||||
REPO=/mnt/storage/src/mosaic-stack
|
||||
WIN=$REPO/agents/sage/work/window-repin-4429a104f
|
||||
NEW=4429a104f6d65ccf165f6c83b5d1dce3147dfde0
|
||||
FILES=(scripts/stack-release.sh scripts/webui-service.sh scripts/bus-service.sh scripts/stack-copy.sh)
|
||||
# The plan's <32 letters>: a fixed dummy, not a secret. matrix-new.txt uses the same value.
|
||||
PROOF=abcdefghijklmnopqrstuvwxyzabcdef
|
||||
|
||||
p4() {
|
||||
echo "# P4 $(date -u +%FT%TZ)"
|
||||
local out; out="$(systemctl --user show mosaic-preview-tunnel.service -p ExecStart -p DropInPaths)"; local rc=$?
|
||||
printf '%s\n' "$out"; echo "# exit $rc"
|
||||
local specs; specs="$(grep -oE 'R:[^ ;]+' <<<"$out")"
|
||||
local n; n="$(grep -c . <<<"$specs")"
|
||||
echo "# R: specs ($n): $(tr '\n' ' ' <<<"$specs")"
|
||||
local drop; drop="$(sed -n 's/^DropInPaths=//p' <<<"$out")"
|
||||
if [[ $rc -eq 0 && $n -eq 1 && "$specs" == "R:0.0.0.0:7332:127.0.0.1:7332" && -z "$drop" ]]; then
|
||||
echo "P4 PASS: one R: spec R:0.0.0.0:7332:127.0.0.1:7332, DropInPaths empty"
|
||||
else
|
||||
echo "P4 FAIL"; return 3
|
||||
fi
|
||||
}
|
||||
|
||||
p5() {
|
||||
echo "# P5 $(date -u +%FT%TZ); HEAD $(git -C $REPO rev-parse HEAD)"
|
||||
git -C $REPO diff --quiet $NEW HEAD -- "${FILES[@]}"; local d=$?
|
||||
echo "# git diff --quiet $NEW HEAD -- ${FILES[*]}: exit $d"
|
||||
local st; st="$(git -C $REPO status --porcelain -- "${FILES[@]}")"; local s=$?
|
||||
echo "# git status --porcelain (exit $s): [${st}]"
|
||||
for f in "${FILES[@]}"; do echo "# $f HEAD blob $(git -C $REPO rev-parse HEAD:$f) NEW blob $(git -C $REPO rev-parse $NEW:$f)"; done
|
||||
if [[ $d -eq 0 && $s -eq 0 && -z "$st" ]]; then echo "P5 PASS"; else echo "P5 FAIL"; return 3; fi
|
||||
}
|
||||
|
||||
# one matrix line: label, then curl arguments; prints "<label> <code> <error or ok field>"
|
||||
req() {
|
||||
local label="$1"; shift
|
||||
local body; body="$(mktemp -p "${TMPDIR:-/tmp}")"
|
||||
local code; code="$(curl -s -m 10 -o "$body" -w '%{http_code}' "$@")"
|
||||
local field; field="$(node -e '
|
||||
let s = require("fs").readFileSync(process.argv[1], "utf8"), j;
|
||||
try { j = JSON.parse(s); } catch { console.log("non-json " + s.length + " bytes"); process.exit(0); }
|
||||
console.log(j.error !== undefined ? "error=" + JSON.stringify(j.error) : "ok=" + JSON.stringify(j.ok));
|
||||
' "$body")"
|
||||
rm -f "$body"
|
||||
echo "$label $code $field"
|
||||
}
|
||||
|
||||
p6() {
|
||||
req a http://127.0.0.1:7332/healthz
|
||||
req b -H 'Host: mosaic.woltje.com' http://127.0.0.1:7332/
|
||||
req c -H 'Host: mosaic.woltje.com' -H "X-Mosaic-Proof: $PROOF" http://127.0.0.1:7332/
|
||||
req d -H 'X-authentik-username: tester-probe' http://127.0.0.1:7332/
|
||||
req e -H 'x-mosaic-tester: 1' http://127.0.0.1:7332/
|
||||
req f -H 'X-authentik-username: tester-probe' http://127.0.0.1:7333/
|
||||
req g -H "X-Mosaic-Proof: $PROOF" http://127.0.0.1:7333/
|
||||
}
|
||||
|
||||
case "${1:-}" in
|
||||
p4) p4 ;;
|
||||
p5) p5 ;;
|
||||
p6) p6 ;;
|
||||
*) echo "usage: p456.sh p4|p5|p6" >&2; exit 2 ;;
|
||||
esac
|
||||
@@ -0,0 +1,9 @@
|
||||
# P5 2026-10-20T22:00:17Z; HEAD 4385b9ec183a2da4136ccd639d2a6b041eb9c68f
|
||||
# git diff --quiet 4429a104f6d65ccf165f6c83b5d1dce3147dfde0 HEAD -- scripts/stack-release.sh scripts/webui-service.sh scripts/bus-service.sh scripts/stack-copy.sh: exit 0
|
||||
# git status --porcelain (exit 0): []
|
||||
# scripts/stack-release.sh HEAD blob 3b068b1546d4020cffde5d73929d9130afe91911 NEW blob 3b068b1546d4020cffde5d73929d9130afe91911
|
||||
# scripts/webui-service.sh HEAD blob 0a32547c54ac233e75a21f4817ae230855dbc088 NEW blob 0a32547c54ac233e75a21f4817ae230855dbc088
|
||||
# scripts/bus-service.sh HEAD blob f71250204dfeceb51beeea5941ebbf3a33ce4b92 NEW blob f71250204dfeceb51beeea5941ebbf3a33ce4b92
|
||||
# scripts/stack-copy.sh HEAD blob 24bbb02a6aa8d7857da7be3b6815105a9fef629f NEW blob 24bbb02a6aa8d7857da7be3b6815105a9fef629f
|
||||
P5 PASS
|
||||
rc 0
|
||||
@@ -0,0 +1,235 @@
|
||||
// Merged window B+C, S1, S2 and D3 (repin-merged-bc.md "S1 and S2"): a read-only snapshot of every
|
||||
// table in a bus store, so the 3h to 3i migration and a restore can be checked without the bus.
|
||||
// OLD's broker doesn't take --tester on usage, names or threads.
|
||||
//
|
||||
// usage: node snapshot.mjs --store /abs/bus.sqlite (--held | --stopped) [--after STAMP] [--backup /abs/bus.sqlite]
|
||||
// --held the running bus holds the store: a plain readOnly open, which adds no file to a WAL
|
||||
// store that already has -wal and -shm (as stack-release.sh does for a held store).
|
||||
// Refuses store-not-held when either is absent
|
||||
// --stopped the bus is stopped: refuses store-unclean when -wal or -shm is present, else opens
|
||||
// with immutable=1 and readOnly, which creates no file and leaves the store's mtime
|
||||
// and sha256 alone
|
||||
// --after also counts each timed table's rows with `at` after STAMP (mos-0838 D3, before a
|
||||
// --restore). STAMP is a backup's STAMP file, in now_ms form (stack-release.sh:43,
|
||||
// 2026-10-20T00:11:14.123Z). The count is a text compare, as the tool's own heldcount
|
||||
// does, so every `at` in every timed table must have that form: a table with any
|
||||
// other value refuses at-format and names the table (sage-1125)
|
||||
// --backup also compares every table with a stack-release backup's bus.sqlite, which opens as
|
||||
// --stopped opens a store: immutable=1 and readOnly, refusing backup-unclean when -wal
|
||||
// or -shm is present, so nothing writes into the backup set
|
||||
//
|
||||
// It prints one JSON object: the schema version, then for every table in sqlite_master (type
|
||||
// table, less sqlite_*) the row count, the max seq and a sha256 of the rows (in seq order, else in
|
||||
// column order). `untimed` names the tables with no `at` column. For usage_records it adds per-run
|
||||
// input and output sums, counted as `mosaic usage` counts them (usage.mjs turnRecords). messages
|
||||
// and message_threads hold bodies and names, so they print counts only, no sha256 (sage-1125). It
|
||||
// prints counts, hashes and table and meta key names only: no message body, no instance, project
|
||||
// or thread name, no credential and no file content. It reads no config: the store path is always
|
||||
// given.
|
||||
//
|
||||
// With --backup, each table gets `vsBackup` and `stopTables` names every table other than events
|
||||
// whose rows differ from the backup's (sage-1123): a row with `at` after STAMP, a row past the
|
||||
// backup's max seq, a changed row at or below it, a changed untimed table, or a table only one
|
||||
// side has. meta counts only when a key other than schema_version and schema_digest changed (the
|
||||
// 3h to 3i migration sets those two). Events are left to the tool's own --events N.
|
||||
import { DatabaseSync } from 'node:sqlite';
|
||||
import { createHash } from 'node:crypto';
|
||||
import { existsSync, lstatSync } from 'node:fs';
|
||||
import { isAbsolute } from 'node:path';
|
||||
import { pathToFileURL } from 'node:url';
|
||||
|
||||
// usage_records is hashed on these columns in this order, never SELECT * (mos-0888 F1), as
|
||||
// 3h-3i.sql:9 copies it. Every other table is hashed on its own columns in name order, so a
|
||||
// rebuild that reorders columns keeps the hash. usage_records with any other column set refuses.
|
||||
const USAGE_COLUMNS = ['seq', 'at', 'business', 'run', 'instance', 'provider', 'model', 'account', 'turn', 'source',
|
||||
'phase', 'status', 'code', 'cursor', 'input', 'output', 'cache_write', 'cache_read'];
|
||||
const COUNTS_ONLY = new Set(['messages', 'message_threads']);
|
||||
const SCHEMA_KEYS = ['schema_digest', 'schema_version'];
|
||||
const STAMP = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
|
||||
|
||||
function refuse(code, detail) {
|
||||
process.stderr.write(`snapshot: ${code}: ${detail}\n`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function args(argv) {
|
||||
const o = {};
|
||||
for (let i = 0; i < argv.length; i++) {
|
||||
const a = argv[i];
|
||||
if (a === '--store' || a === '--after' || a === '--backup') {
|
||||
if (i + 1 >= argv.length) refuse('usage', `${a} needs a value`);
|
||||
o[a.slice(2)] = argv[++i];
|
||||
} else if (a === '--held' || a === '--stopped') {
|
||||
if (o.mode) refuse('usage', 'give one of --held and --stopped');
|
||||
o.mode = a.slice(2);
|
||||
} else refuse('usage', `unknown argument ${a}`);
|
||||
}
|
||||
if (!o.store || !o.mode) refuse('usage', 'node snapshot.mjs --store /abs/bus.sqlite (--held | --stopped) [--after STAMP] [--backup /abs/bus.sqlite]');
|
||||
if (!isAbsolute(o.store)) refuse('usage', '--store must be an absolute path');
|
||||
if (o.backup !== undefined && !isAbsolute(o.backup)) refuse('usage', '--backup must be an absolute path');
|
||||
if (o.after !== undefined && !(STAMP.test(o.after) && Number.isFinite(Date.parse(o.after))))
|
||||
refuse('usage', '--after must be a STAMP like 2026-10-20T00:11:14.123Z');
|
||||
return o;
|
||||
}
|
||||
|
||||
function file(path, code) {
|
||||
if (!existsSync(path) || !lstatSync(path).isFile()) refuse(code, `${path} is not a file`);
|
||||
}
|
||||
|
||||
function immutable(path, code) {
|
||||
for (const f of [path + '-wal', path + '-shm'])
|
||||
if (existsSync(f)) refuse(code, `${f} is present; an immutable read would skip the WAL`);
|
||||
return new DatabaseSync(pathToFileURL(path).href + '?immutable=1', { readOnly: true });
|
||||
}
|
||||
|
||||
function open({ store, mode }) {
|
||||
file(store, 'store-missing');
|
||||
if (mode === 'stopped') return immutable(store, 'store-unclean');
|
||||
// A plain readOnly open of a WAL store with no -wal and -shm creates them, so a store that
|
||||
// nothing holds refuses here instead of gaining two files.
|
||||
for (const f of [store + '-wal', store + '-shm'])
|
||||
if (!existsSync(f)) refuse('store-not-held', `${f} is absent; use --stopped for a store the bus doesn't hold`);
|
||||
return new DatabaseSync(store, { readOnly: true });
|
||||
}
|
||||
|
||||
const q = (name) => `"${name.replaceAll('"', '""')}"`;
|
||||
const value = (v) => (typeof v === 'bigint' ? String(v) : v instanceof Uint8Array ? { hex: Buffer.from(v).toString('hex') } : v);
|
||||
|
||||
// The same records `mosaic usage` counts: per (run, turn, source) the latest row, an end row
|
||||
// winning; a turn is known only when that row is an end row with status known.
|
||||
function byRun(rows) {
|
||||
const turns = new Map();
|
||||
for (const row of rows) {
|
||||
const key = JSON.stringify([row.business, row.run, row.turn, row.source]);
|
||||
if (row.phase === 'end' || !turns.has(key)) turns.set(key, row);
|
||||
}
|
||||
const runs = new Map();
|
||||
for (const row of turns.values()) {
|
||||
const key = JSON.stringify([row.business, row.run]);
|
||||
if (!runs.has(key)) runs.set(key, { business: row.business, run: row.run, input: 0n, output: 0n, unknown: new Set() });
|
||||
const r = runs.get(key);
|
||||
if (row.phase === 'end' && row.status === 'known') {
|
||||
r.input += BigInt(row.input);
|
||||
r.output += BigInt(row.output);
|
||||
} else r.unknown.add(row.turn);
|
||||
}
|
||||
return [...runs.values()].map(({ unknown, input, output, ...r }) => ({
|
||||
...r, input: String(input), output: String(output), unknownTurns: unknown.size,
|
||||
}));
|
||||
}
|
||||
|
||||
// meta is compared by key: the names of the keys whose value differs, never the values.
|
||||
function metaKeys(db) {
|
||||
return new Map(db.prepare('SELECT key, value FROM meta').all().map((r) => [String(r.key), String(r.value)]));
|
||||
}
|
||||
|
||||
// One table: rows, max seq and sha256; rows after `after`; with `priorMax` (the backup's max
|
||||
// seq) a second hash of the rows at or below it and the count of rows above it. The hashes stay
|
||||
// inside: a COUNTS_ONLY table's `t` gets none.
|
||||
function read(db, table, { after, priorMax } = {}) {
|
||||
const cols = db.prepare('SELECT name FROM pragma_table_info(?)').all(table).map((c) => c.name);
|
||||
if (!cols.length) refuse('table-missing', table);
|
||||
let hashed = [...cols].sort();
|
||||
if (table === 'usage_records') {
|
||||
if (JSON.stringify(hashed) !== JSON.stringify([...USAGE_COLUMNS].sort()))
|
||||
refuse('columns-changed', `usage_records has columns ${hashed.join(',')}`);
|
||||
hashed = USAGE_COLUMNS;
|
||||
}
|
||||
const seq = cols.includes('seq');
|
||||
const at = cols.includes('at');
|
||||
const stmt = db.prepare(`SELECT ${hashed.map(q).join(',')} FROM ${q(table)} ORDER BY ${seq ? 'seq' : hashed.map(q).join(',')}`);
|
||||
stmt.setReadBigInts(true);
|
||||
const full = createHash('sha256');
|
||||
const prior = createHash('sha256');
|
||||
const limit = priorMax === undefined ? undefined : BigInt(priorMax ?? 0);
|
||||
let rows = 0;
|
||||
let rowsAfter = 0;
|
||||
let badAt = 0;
|
||||
let newRows = 0;
|
||||
const kept = [];
|
||||
for (const row of stmt.iterate()) {
|
||||
rows++;
|
||||
const line = JSON.stringify(hashed.map((c) => value(row[c]))) + '\n';
|
||||
full.update(line);
|
||||
if (seq && limit !== undefined) {
|
||||
if (row.seq <= limit) prior.update(line);
|
||||
else newRows++;
|
||||
}
|
||||
if (after !== undefined && at) {
|
||||
if (typeof row.at !== 'string' || !STAMP.test(row.at)) badAt++;
|
||||
else if (row.at > after) rowsAfter++;
|
||||
}
|
||||
if (table === 'usage_records') kept.push(row);
|
||||
}
|
||||
if (badAt) refuse('at-format', `${table} has ${badAt} row(s) whose at is not in the STAMP form, so a text compare with --after would miscount`);
|
||||
const sha256 = full.digest('hex');
|
||||
const t = { rows, maxSeq: seq ? (db.prepare(`SELECT max(seq) AS m FROM ${q(table)}`).get().m ?? null) : null };
|
||||
if (!COUNTS_ONLY.has(table)) t.sha256 = sha256;
|
||||
if (after !== undefined && at) t.rowsAfter = rowsAfter;
|
||||
if (table === 'usage_records') t.byRun = byRun(kept);
|
||||
return { t, sha256, cols: hashed, seq, at, newRows, priorSha: seq && limit !== undefined ? prior.digest('hex') : null };
|
||||
}
|
||||
|
||||
// Tables only: no index, view or trigger, and none of SQLite's own sqlite_* tables.
|
||||
const tablesOf = (db) => db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite\\_%' ESCAPE '\\' ORDER BY name")
|
||||
.all().map((r) => r.name);
|
||||
|
||||
const o = args(process.argv.slice(2));
|
||||
if (o.backup !== undefined) file(o.backup, 'backup-missing');
|
||||
const db = open(o);
|
||||
const bdb = o.backup === undefined ? null : immutable(o.backup, 'backup-unclean');
|
||||
const out = {};
|
||||
try {
|
||||
db.exec('BEGIN');
|
||||
out.schema = db.prepare("SELECT value FROM meta WHERE key='schema_version'").get()?.value ?? null;
|
||||
const names = tablesOf(db);
|
||||
const base = new Map();
|
||||
if (bdb) {
|
||||
out.backupSchema = bdb.prepare("SELECT value FROM meta WHERE key='schema_version'").get()?.value ?? null;
|
||||
for (const name of tablesOf(bdb)) base.set(name, read(bdb, name));
|
||||
}
|
||||
out.tables = {};
|
||||
out.untimed = [];
|
||||
const stop = [];
|
||||
for (const name of names) {
|
||||
const b = base.get(name);
|
||||
const r = read(db, name, { after: o.after, priorMax: b ? b.t.maxSeq : undefined });
|
||||
if (!r.at) out.untimed.push(name);
|
||||
if (bdb) {
|
||||
const v = { backupRows: b ? b.t.rows : null };
|
||||
let changed;
|
||||
if (!b) changed = true;
|
||||
else if (name === 'meta') {
|
||||
const now = metaKeys(db);
|
||||
const then = metaKeys(bdb);
|
||||
v.keysChanged = [...new Set([...now.keys(), ...then.keys()])].filter((k) => now.get(k) !== then.get(k)).sort();
|
||||
changed = v.keysChanged.some((k) => !SCHEMA_KEYS.includes(k));
|
||||
} else if (r.seq) {
|
||||
v.backupMaxSeq = b.t.maxSeq;
|
||||
v.newRows = r.newRows;
|
||||
v.priorSame = JSON.stringify(r.cols) === JSON.stringify(b.cols) && r.priorSha === b.sha256;
|
||||
changed = r.newRows > 0 || !v.priorSame;
|
||||
} else {
|
||||
v.same = JSON.stringify(r.cols) === JSON.stringify(b.cols) && r.sha256 === b.sha256;
|
||||
changed = !v.same;
|
||||
}
|
||||
if ((r.t.rowsAfter ?? 0) > 0) changed = true;
|
||||
r.t.vsBackup = v;
|
||||
if (changed && name !== 'events') stop.push(name);
|
||||
}
|
||||
out.tables[name] = r.t;
|
||||
}
|
||||
if (bdb) {
|
||||
out.onlyInBackup = [...base.keys()].filter((n) => !names.includes(n));
|
||||
out.stopTables = [...stop, ...out.onlyInBackup].sort();
|
||||
}
|
||||
if (o.after !== undefined) {
|
||||
out.after = o.after;
|
||||
out.eventsAfter = out.tables.events?.rowsAfter ?? null;
|
||||
}
|
||||
} finally {
|
||||
try { db.exec('ROLLBACK'); } catch {}
|
||||
db.close();
|
||||
bdb?.close();
|
||||
}
|
||||
process.stdout.write(JSON.stringify(out, null, 2) + '\n');
|
||||
Executable
+16
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
# Re-pin 4429a104f window step wrapper (copied from Darkwing's window-rows-177-185/w.sh): w.sh FILE TITLE CMD... runs CMD in REPO under a clean env (no ANTHROPIC_*, CLAUDE_*,
|
||||
# MOSAIC_* or pi variables), appends the title, command, output, exit code and date -u stamps to window/FILE,
|
||||
# prints the output, and exits with CMD's exit code.
|
||||
set -uo pipefail
|
||||
W=/mnt/storage/src/mosaic-stack/agents/sage/work/window-repin-4429a104f
|
||||
f="$W/$1"; title="$2"; shift 2
|
||||
E=(env -i HOME="$HOME" PATH="$HOME/.local/bin:/usr/local/bin:/usr/bin:/bin" LANG=C.UTF-8
|
||||
XDG_RUNTIME_DIR="$XDG_RUNTIME_DIR" DBUS_SESSION_BUS_ADDRESS="${DBUS_SESSION_BUS_ADDRESS:-unix:path=$XDG_RUNTIME_DIR/bus}")
|
||||
t0=$(date -u +%FT%T.%3NZ)
|
||||
{ echo; echo "## $title"; echo "# start $t0"; echo "# command: (cd \$REPO && <clean env> $*)"; } >> "$f"
|
||||
out=$(cd /mnt/storage/src/mosaic-stack && "${E[@]}" "$@" 2>&1); rc=$?
|
||||
printf '%s\n' "$out" >> "$f"
|
||||
echo "# exit $rc, end $(date -u +%FT%T.%3NZ)" >> "$f"
|
||||
printf '%s\n# exit %s\n' "$out" "$rc"
|
||||
exit $rc
|
||||
@@ -0,0 +1,9 @@
|
||||
npm warn deprecated [email protected]: Use your platform's native DOMException instead
|
||||
|
||||
added 128 packages in 2s
|
||||
npm warn install-scripts 3 packages had install scripts blocked because they are not covered by allowScripts:
|
||||
npm warn install-scripts @google/[email protected] (preinstall: echo 'preinstall: no-op')
|
||||
npm warn install-scripts [email protected] (postinstall: node install.js)
|
||||
npm warn install-scripts [email protected] (postinstall: node scripts/postinstall)
|
||||
npm warn install-scripts
|
||||
npm warn install-scripts Run `npm install-scripts ls` to review, or `npm install-scripts approve <pkg>` to allow.
|
||||
@@ -0,0 +1 @@
|
||||
copied: /home/jwoltje/.local/share/mosaic-stack/copies/4429a104f6d65ccf165f6c83b5d1dce3147dfde0
|
||||
@@ -0,0 +1,16 @@
|
||||
start 2026-10-20T21:45:57Z
|
||||
stack-copy rc=0
|
||||
copied: /home/jwoltje/.local/share/mosaic-stack/copies/4429a104f6d65ccf165f6c83b5d1dce3147dfde0
|
||||
npm warn install-scripts [email protected] (postinstall: node scripts/postinstall)
|
||||
npm warn install-scripts
|
||||
npm warn install-scripts Run `npm install-scripts ls` to review, or `npm install-scripts approve <pkg>` to allow.
|
||||
oauth4webapi 3.8.8
|
||||
IMPORT_OK
|
||||
LOCK_MATCH
|
||||
163M /home/jwoltje/.local/share/mosaic-stack/copies/4429a104f6d65ccf165f6c83b5d1dce3147dfde0
|
||||
/dev/nvme1n1p5 458G 405G 30G 94% /home
|
||||
copy 4429a104f: roles 6, projects 1, arbiters 2
|
||||
HOLDS chief instance.name yes
|
||||
HOLDS pm instance.name no
|
||||
LOAD_OK
|
||||
end 2026-10-20T21:45:59Z
|
||||
@@ -0,0 +1,109 @@
|
||||
// W10 of repin-4429a104f.md (e1272d1a), adapted from Darkwing's window-rows-177-185/w10-browser.mjs: the tester listener
|
||||
// on 127.0.0.1:7333 through the webui browser harness (packages/webui/tests/browser.mjs, same blob at HEAD and NEW). Reads only: before any page
|
||||
// script runs, fetch and XMLHttpRequest are wrapped so every call is logged and any method other than
|
||||
// GET or HEAD is refused in the page, and the script submits no form and clicks no button. The chat
|
||||
// check reads the #/chat list only and never opens the W9 thread page (the launcher reads lastOpen).
|
||||
import { browser } from '/mnt/storage/src/mosaic-stack/packages/webui/tests/browser.mjs';
|
||||
|
||||
const OUT = '/mnt/storage/src/mosaic-stack/agents/sage/work/window-repin-4429a104f';
|
||||
const BASE = 'http://127.0.0.1:7333/';
|
||||
const W9_THREAD = '446201de-e8b5-4df3-9356-d0d5422cc899';
|
||||
const GUARD = `(() => {
|
||||
const log = window.__w10 = [];
|
||||
const ok = m => m === 'GET' || m === 'HEAD';
|
||||
const f = window.fetch;
|
||||
window.fetch = (input, init = {}) => {
|
||||
const method = String(init.method || (input instanceof Request ? input.method : 'GET')).toUpperCase();
|
||||
const url = String(input instanceof Request ? input.url : input);
|
||||
log.push({ method, url, refused: !ok(method) });
|
||||
return ok(method) ? f(input, init) : Promise.reject(new TypeError('w10 refused ' + method));
|
||||
};
|
||||
const open = XMLHttpRequest.prototype.open, send = XMLHttpRequest.prototype.send;
|
||||
XMLHttpRequest.prototype.open = function (method, url, ...rest) { this.__m = String(method).toUpperCase(); this.__u = String(url); return open.call(this, method, url, ...rest); };
|
||||
XMLHttpRequest.prototype.send = function (...a) { log.push({ method: this.__m, url: this.__u, xhr: true, refused: !ok(this.__m) }); if (!ok(this.__m)) throw new TypeError('w10 refused ' + this.__m); return send.apply(this, a); };
|
||||
})();`;
|
||||
|
||||
const b = await browser({ machine: false });
|
||||
const result = {};
|
||||
let failed = false;
|
||||
const check = (name, pass, detail) => { result[name] = { pass, ...(detail === undefined ? {} : { detail }) }; if (!pass) failed = true; };
|
||||
try {
|
||||
await b.call('Page.addScriptToEvaluateOnNewDocument', { source: GUARD });
|
||||
await b.viewport(1280, 1600);
|
||||
const wait = expr => b.evaluate(`(async()=>{for(let n=0;n<300;n++){if(${expr})return true;await new Promise(r=>setTimeout(r,50));}return false;})()`);
|
||||
|
||||
await b.navigate(BASE + '#/settings');
|
||||
const ready = await wait('!!document.querySelector("#tester-banner") && !!document.querySelector("#routes-form") && !!document.querySelector(".tester-name-form")');
|
||||
check('settings loaded', ready);
|
||||
const s = await b.evaluate(`(() => {
|
||||
const q = x => document.querySelector(x);
|
||||
return {
|
||||
banner: q('#tester-banner')?.textContent.trim() ?? null,
|
||||
h1: q('#bus-view h1')?.textContent.trim() ?? null,
|
||||
forms: [...document.querySelectorAll('form')].map(f => f.id || f.className),
|
||||
convFormHidden: q('#conv-form')?.hidden ?? null,
|
||||
panels: [...document.querySelectorAll('#bus-view h2')].map(h => h.textContent.trim()),
|
||||
instancesTable: !!q('#instances-table'),
|
||||
nameForms: document.querySelectorAll('.tester-name-form').length,
|
||||
routesForm: !!q('#routes-form'),
|
||||
routesSubmitEnabled: q('#routes-form button[type=submit]')?.disabled === false,
|
||||
forbidden: [...document.querySelectorAll('#launch-settings-form, .assistant-form, #token-limits-table [data-limit-reset], #send-section')].map(e => e.id || e.className || e.tagName),
|
||||
tokenLimitsPanel: !!q('#token-limits-title') || !!q('#token-limits-table'),
|
||||
};
|
||||
})()`);
|
||||
result.settings = s;
|
||||
check('tester banner', /tester/i.test(s.banner ?? ''), s.banner);
|
||||
check('instance, routes and name editors present', s.instancesTable && s.routesForm && s.nameForms > 0);
|
||||
check('only tester forms (conv-form is index.html:21, global and hidden)', s.convFormHidden === true && s.forms.every(f => f === 'conv-form' || f === 'routes-form' || /tester-name-form/.test(f) || /^instance-(add|change)-form$/.test(f)), s.forms);
|
||||
check('no launch settings, assistant, limit reset or send', s.forbidden.length === 0, s.forbidden);
|
||||
check('no Token limits panel (plan W10 item 2, amended)', s.tokenLimitsPanel === false);
|
||||
await b.screenshot(`${OUT}/w10-settings.png`);
|
||||
|
||||
await b.navigate(BASE + '#/');
|
||||
// The Board is index.html:22 #board-view; bus.js hides #bus-view on it.
|
||||
const board = await wait('document.querySelector("#bus-view")?.hidden === true && !!document.querySelector("#board-view #waiting-title")');
|
||||
await new Promise(r => setTimeout(r, 1500));
|
||||
const bd = await b.evaluate(`(() => { const v = document.querySelector('#board-view'); return {
|
||||
busViewHidden: document.querySelector('#bus-view')?.hidden ?? null,
|
||||
banner: !!document.querySelector('#tester-banner'),
|
||||
headings: [...v.querySelectorAll('h2')].map(h => h.textContent.replace(/\\s+/g, ' ').trim()),
|
||||
unavailable: /unavailable|refused|not authorized/i.test(v.textContent),
|
||||
length: v.textContent.length,
|
||||
forms: [...document.querySelectorAll('form')].map(f => f.id || f.className),
|
||||
}; })()`);
|
||||
result.board = bd;
|
||||
check('board reads', board && bd.busViewHidden === true && !bd.unavailable && bd.headings.length > 0, bd);
|
||||
await b.screenshot(`${OUT}/w10-board.png`);
|
||||
|
||||
await b.navigate(BASE + '#/chat');
|
||||
// chat.js threads(): ul.chat-thread-list with <a href="#/chat/threads/<id>">. Read only; no link is followed.
|
||||
const chatReady = await wait('!!document.querySelector("ul.chat-thread-list") || /No threads yet/.test(document.body.textContent)');
|
||||
const c = await b.evaluate(`(() => {
|
||||
const list = document.querySelector('ul.chat-thread-list');
|
||||
return {
|
||||
hash: location.hash,
|
||||
banner: !!document.querySelector('#tester-banner'),
|
||||
threads: list ? [...list.querySelectorAll('li')].map(li => ({ href: li.querySelector('a')?.getAttribute('href') ?? null, name: li.querySelector('a')?.textContent.trim() ?? null, instance: li.querySelector('.muted')?.textContent.trim() ?? null })) : [],
|
||||
conversationOpen: !!document.querySelector('.chat-conversation'),
|
||||
forms: [...document.querySelectorAll('form')].map(f => f.id || f.className),
|
||||
};
|
||||
})()`);
|
||||
result.chat = c;
|
||||
check('chat lists the W9 thread', chatReady && c.threads.some(t => t.href === '#/chat/threads/' + W9_THREAD), c.threads);
|
||||
check('W9 thread page not opened', c.hash === '#/chat' && c.conversationOpen === false, c.hash);
|
||||
check('tester banner on chat', c.banner);
|
||||
await b.screenshot(`${OUT}/w10-chat.png`);
|
||||
|
||||
const log = await b.evaluate('window.__w10');
|
||||
result.requests = log;
|
||||
check('no write through the listener', log.every(r => !r.refused && (r.method === 'GET' || r.method === 'HEAD')), log.filter(r => r.refused));
|
||||
check('no request to the W9 thread messages or open', !log.some(r => r.url.includes(W9_THREAD)), log.filter(r => r.url.includes(W9_THREAD)));
|
||||
} catch (e) {
|
||||
failed = true;
|
||||
result.error = String(e?.message ?? e);
|
||||
} finally {
|
||||
await b.close();
|
||||
}
|
||||
console.log(JSON.stringify(result, null, 2));
|
||||
console.log(failed ? 'W10 browser: FAIL' : 'W10 browser: pass');
|
||||
process.exit(failed ? 1 : 0);
|
||||
@@ -0,0 +1,30 @@
|
||||
// W10 diagnosis after the two failed checks of w10-browser.mjs (sign-out form listed; chat list missing the W9 thread).
|
||||
// Read only, with the same GET/HEAD guard as w10-browser.mjs. Records each form's hidden flag on Settings, the /api/config
|
||||
// sso value the page sees, and every ul.chat-thread-list on #/chat (chat.js:93 renders one per project). No screenshots.
|
||||
import { browser } from '/mnt/storage/src/mosaic-stack/packages/webui/tests/browser.mjs';
|
||||
import { readFileSync } from 'node:fs';
|
||||
const src = readFileSync(new URL('./w10-browser.mjs', import.meta.url), 'utf8');
|
||||
const GUARD = eval(src.slice(src.indexOf('const GUARD = ') + 14, src.indexOf('`;', src.indexOf('const GUARD = ')) + 1));
|
||||
const BASE = 'http://127.0.0.1:7333/';
|
||||
const W9_THREAD = '446201de-e8b5-4df3-9356-d0d5422cc899';
|
||||
const b = await browser({ machine: false });
|
||||
const out = {};
|
||||
try {
|
||||
await b.call('Page.addScriptToEvaluateOnNewDocument', { source: GUARD });
|
||||
const wait = expr => b.evaluate(`(async()=>{for(let n=0;n<300;n++){if(${expr})return true;await new Promise(r=>setTimeout(r,50));}return false;})()`);
|
||||
await b.navigate(BASE + '#/settings');
|
||||
await wait('!!document.querySelector("#routes-form")');
|
||||
out.config = await b.evaluate(`fetch('/api/config').then(r=>r.json()).then(j=>({sso:j.sso??null}))`);
|
||||
out.forms = await b.evaluate(`[...document.querySelectorAll('form')].map(f=>({id:f.id||f.className,hidden:f.hidden,action:f.getAttribute('action'),method:f.getAttribute('method')}))`);
|
||||
await b.navigate(BASE + '#/chat');
|
||||
await wait('document.querySelectorAll("ul.chat-thread-list").length >= 1');
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
out.chat = await b.evaluate(`({hash:location.hash,open:!!document.querySelector('.chat-conversation'),projects:[...document.querySelectorAll('.chat-projects section.panel')].map(s=>({project:s.querySelector('h2')?.textContent.trim(),threads:[...s.querySelectorAll('ul.chat-thread-list li a')].map(a=>a.getAttribute('href'))}))})`);
|
||||
out.requests = await b.evaluate('window.__w10');
|
||||
} finally { await b.close(); }
|
||||
const signOut = out.forms.find(f => f.id === 'sign-out');
|
||||
const listed = out.chat.projects.some(p => p.threads.includes('#/chat/threads/' + W9_THREAD));
|
||||
const writes = out.requests.filter(r => r.refused || !['GET', 'HEAD'].includes(r.method));
|
||||
console.log(JSON.stringify(out, null, 2));
|
||||
console.log(`sign-out hidden ${signOut?.hidden}, sso ${out.config.sso}; W9 thread listed ${listed}; thread page open ${out.chat.open}; writes ${writes.length}`);
|
||||
process.exit(signOut?.hidden === true && listed && !out.chat.open && writes.length === 0 ? 0 : 1);
|
||||
@@ -0,0 +1,277 @@
|
||||
# W9 go mos-1114, start 2026-10-20T22:05:51Z
|
||||
# plan e1272d1a, tool blob 3b068b1546d4, console-check.sh d068fe02, wrapper on NEW: checked
|
||||
pointer: /home/jwoltje/.mosaic-dev/state/stack-active.json
|
||||
{"copy":"4429a104f6d65ccf165f6c83b5d1dce3147dfde0","business":"mosaic-stack","pm":true,"claude":"/home/jwoltje/.local/bin/claude","console":["--port","7332","--public-host","mosaic.woltje.com","--auth-header","X-authentik-username","--allow-user","jason.woltje","--tester-port","7333"],"schema":"3i","activation":"20261020T220206Z-4429a104f6d6","at":"2026-10-20T22:02:09Z"}
|
||||
log (last five lines):
|
||||
{"at":"2026-10-20T07:58:02Z","op":"activate","from":"89af38a83afa22a8a4f0d368a0a4030ad15a0efa","to":"490e2771d3d057ab76991e2c7859cd251857e64c","backup":"20261020T075800Z-490e2771d3d0","activation":"20261020T075800Z-490e2771d3d0","result":"ok"}
|
||||
{"at":"2026-10-20T19:29:56Z","op":"activate","from":"490e2771d3d057ab76991e2c7859cd251857e64c","to":"490e2771d3d057ab76991e2c7859cd251857e64c","backup":null,"activation":"20261020T192956Z-490e2771d3d0","result":"started"}
|
||||
{"at":"2026-10-20T19:30:00Z","op":"activate","from":"490e2771d3d057ab76991e2c7859cd251857e64c","to":"490e2771d3d057ab76991e2c7859cd251857e64c","backup":"20261020T192956Z-490e2771d3d0","activation":"20261020T192956Z-490e2771d3d0","result":"ok"}
|
||||
{"at":"2026-10-20T22:02:06Z","op":"activate","from":"490e2771d3d057ab76991e2c7859cd251857e64c","to":"4429a104f6d65ccf165f6c83b5d1dce3147dfde0","backup":null,"activation":"20261020T220206Z-4429a104f6d6","result":"started"}
|
||||
{"at":"2026-10-20T22:02:09Z","op":"activate","from":"490e2771d3d057ab76991e2c7859cd251857e64c","to":"4429a104f6d65ccf165f6c83b5d1dce3147dfde0","backup":"20261020T220206Z-4429a104f6d6","activation":"20261020T220206Z-4429a104f6d6","result":"ok"}
|
||||
check:
|
||||
bus: /home/jwoltje/.local/share/mosaic-stack/copies/4429a104f6d65ccf165f6c83b5d1dce3147dfde0
|
||||
Console: /home/jwoltje/.local/share/mosaic-stack/copies/4429a104f6d65ccf165f6c83b5d1dce3147dfde0
|
||||
CLI: /home/jwoltje/.local/share/mosaic-stack/copies/4429a104f6d65ccf165f6c83b5d1dce3147dfde0
|
||||
result: pass
|
||||
bus status:
|
||||
host: mosaic-stack, pid 2950923, running, since 2026-10-20T22:02:08.133Z, notifier off
|
||||
socket: present
|
||||
writer.lock: pid 2950981
|
||||
boot: organization file loaded at 2026-10-20T22:02:08.125Z
|
||||
unit flags: match the pointer
|
||||
drift: 6 commit(s) on refactor since the pointer's copy
|
||||
# exit 0
|
||||
PASS markdown-preview.js is served and equals the copy's
|
||||
PASS /api/config on loopback: send=false edit=false
|
||||
PASS project.files through the Console: head=ae0b17c9586e51da7bc1b7e548c6acf913a55665 files=2 spec=true error=none
|
||||
PASS project.file spec/north-star.md through the Console: commit=ae0b17c9586e51da7bc1b7e548c6acf913a55665 length=99 error=none
|
||||
PASS loopback save refused: HTTP 403 error=read-only sent=false
|
||||
CONSOLE_PASS
|
||||
# exit 0
|
||||
# journal since W5: proxy proof off 1, Sign-in 0
|
||||
# Console pid 2950925 cwd /home/jwoltje/.local/share/mosaic-stack/copies/4429a104f6d65ccf165f6c83b5d1dce3147dfde0
|
||||
r097436c91816 mosaic-stack/chief claude-code claude-opus-5-5 by jason since 2026-10-20T22:02:08.941Z running
|
||||
# exit 0
|
||||
[
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"instance": "chief",
|
||||
"run": "r097436c91816",
|
||||
"launchedBy": "jason",
|
||||
"harness": "claude-code",
|
||||
"model": "claude-opus-5-5",
|
||||
"provider": "anthropic",
|
||||
"modelKey": "opus",
|
||||
"pid": 2951160,
|
||||
"startTime": "63491912",
|
||||
"runnerPid": 2951161,
|
||||
"runnerStartTime": "63491912",
|
||||
"runDir": "/home/jwoltje/.mosaic-dev/launches/mosaic-stack/r097436c91816",
|
||||
"startedAt": "2026-10-20T22:02:08.941Z",
|
||||
"live": true
|
||||
}
|
||||
]
|
||||
# exit 0
|
||||
# one running chief from this start: run r097436c91816
|
||||
chief r097436c91816 claude-code since 2026-10-20T22:02:08.951Z
|
||||
# exit 0
|
||||
sent c5b43f04 to chief
|
||||
chief (RESULT, re c5b43f04) c3e236d7:
|
||||
Got the re-pin of 4429a104f6d65ccf165f6c83b5d1dce3147dfde0 from the tester; I took no action because a tester message authorizes nothing, and I launched and changed nothing.
|
||||
# exit 0
|
||||
created project window-20261020-2205 id 77e7b45f-8c34-49a3-b2fa-9cf565177c30
|
||||
# exit 0
|
||||
created window-20261020-2205/w9 id 446201de-e8b5-4df3-9356-d0d5422cc899 instance assistant
|
||||
# exit 0
|
||||
# project window-20261020-2205, thread 446201de-e8b5-4df3-9356-d0d5422cc899
|
||||
sent b4b66ced to window-20261020-2205/w9
|
||||
assistant (RESULT, re b4b66ced) cfa7ea99:
|
||||
Assistant (run r497f1c817d4d) got the [mos test] message and is replying in one line as asked, without treating it as Jason's instruction or acting on it.
|
||||
# exit 0
|
||||
# reply received 2026-10-20T22:06:05Z
|
||||
[
|
||||
{
|
||||
"seq": 570,
|
||||
"id": "b4b66ced-d088-4b9c-a944-306f164028f9",
|
||||
"at": "2026-10-20T22:05:58.283Z",
|
||||
"business": "mosaic-stack",
|
||||
"from_role": "tester",
|
||||
"from_run": "tester-cli",
|
||||
"to_role": "assistant",
|
||||
"class": "REQUEST",
|
||||
"in_reply_to": null,
|
||||
"decision": null,
|
||||
"corrects": null,
|
||||
"body": "[mos test] reply with one line, then stop",
|
||||
"to_name": null
|
||||
},
|
||||
{
|
||||
"seq": 571,
|
||||
"id": "cfa7ea99-7ccb-4225-80a6-9a903540e337",
|
||||
"at": "2026-10-20T22:06:04.247Z",
|
||||
"business": "mosaic-stack",
|
||||
"from_role": "assistant",
|
||||
"from_run": "r497f1c817d4d",
|
||||
"to_role": "tester",
|
||||
"class": "RESULT",
|
||||
"in_reply_to": "b4b66ced-d088-4b9c-a944-306f164028f9",
|
||||
"decision": null,
|
||||
"corrects": null,
|
||||
"body": "Assistant (run r497f1c817d4d) got the [mos test] message and is replying in one line as asked, without treating it as Jason's instruction or acting on it.",
|
||||
"to_name": null
|
||||
}
|
||||
]
|
||||
# exit 0
|
||||
# thread read: 2 messages: tester->assistant REQUEST, assistant->tester RESULT
|
||||
window-20261020-0801/w9 assistant d0ba7a66
|
||||
window-20261020-2205/w9 assistant 446201de
|
||||
# exit 0
|
||||
[]
|
||||
# exit 0
|
||||
{
|
||||
"total": {
|
||||
"input": 62,
|
||||
"output": 9623,
|
||||
"cacheWrite": 186650,
|
||||
"cacheRead": 404132,
|
||||
"unknownTurns": 1
|
||||
},
|
||||
"byRun": [
|
||||
{
|
||||
"run": "r8fba7e598156",
|
||||
"input": 0,
|
||||
"output": 0,
|
||||
"cacheWrite": 0,
|
||||
"cacheRead": 0,
|
||||
"unknownTurns": 1
|
||||
},
|
||||
{
|
||||
"run": "r4a96e2142e4d",
|
||||
"input": 2,
|
||||
"output": 52,
|
||||
"cacheWrite": 11750,
|
||||
"cacheRead": 0,
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"run": "rc78c9700c8e9",
|
||||
"input": 14,
|
||||
"output": 1519,
|
||||
"cacheWrite": 18187,
|
||||
"cacheRead": 89559,
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"run": "r293f33bcbc63",
|
||||
"input": 2,
|
||||
"output": 44,
|
||||
"cacheWrite": 18595,
|
||||
"cacheRead": 0,
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"run": "r34520a581318",
|
||||
"input": 6,
|
||||
"output": 323,
|
||||
"cacheWrite": 26349,
|
||||
"cacheRead": 14307,
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"run": "r7e99838f9f93",
|
||||
"input": 2,
|
||||
"output": 44,
|
||||
"cacheWrite": 9858,
|
||||
"cacheRead": 0,
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"run": "rc964611b2092",
|
||||
"input": 4,
|
||||
"output": 120,
|
||||
"cacheWrite": 26138,
|
||||
"cacheRead": 23870,
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"run": "rbb708846b605",
|
||||
"input": 12,
|
||||
"output": 2089,
|
||||
"cacheWrite": 17285,
|
||||
"cacheRead": 73823,
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"run": "rc36b17ef3788",
|
||||
"input": 16,
|
||||
"output": 5221,
|
||||
"cacheWrite": 36717,
|
||||
"cacheRead": 202573,
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"run": "r097436c91816",
|
||||
"input": 2,
|
||||
"output": 131,
|
||||
"cacheWrite": 11915,
|
||||
"cacheRead": 0,
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"run": "r497f1c817d4d",
|
||||
"input": 2,
|
||||
"output": 80,
|
||||
"cacheWrite": 9856,
|
||||
"cacheRead": 0,
|
||||
"unknownTurns": 0
|
||||
}
|
||||
],
|
||||
"byInstance": [
|
||||
{
|
||||
"instance": "chief",
|
||||
"input": 36,
|
||||
"output": 4114,
|
||||
"cacheWrite": 85486,
|
||||
"cacheRead": 177689,
|
||||
"unknownTurns": 1
|
||||
},
|
||||
{
|
||||
"instance": "coder",
|
||||
"input": 2,
|
||||
"output": 44,
|
||||
"cacheWrite": 18595,
|
||||
"cacheRead": 0,
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"instance": "assistant",
|
||||
"input": 4,
|
||||
"output": 124,
|
||||
"cacheWrite": 19714,
|
||||
"cacheRead": 0,
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"instance": "pm",
|
||||
"input": 20,
|
||||
"output": 5341,
|
||||
"cacheWrite": 62855,
|
||||
"cacheRead": 226443,
|
||||
"unknownTurns": 0
|
||||
}
|
||||
],
|
||||
"byProvider": [
|
||||
{
|
||||
"provider": "anthropic",
|
||||
"input": 62,
|
||||
"output": 9623,
|
||||
"cacheWrite": 186650,
|
||||
"cacheRead": 404132,
|
||||
"unknownTurns": 1
|
||||
}
|
||||
],
|
||||
"byModel": [
|
||||
{
|
||||
"provider": "anthropic",
|
||||
"model": "claude-opus-5-5",
|
||||
"input": 62,
|
||||
"output": 9623,
|
||||
"cacheWrite": 186650,
|
||||
"cacheRead": 404132,
|
||||
"unknownTurns": 1
|
||||
}
|
||||
],
|
||||
"byAccount": [
|
||||
{
|
||||
"account": null,
|
||||
"input": 62,
|
||||
"output": 9623,
|
||||
"cacheWrite": 186650,
|
||||
"cacheRead": 404132,
|
||||
"unknownTurns": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
# exit 0
|
||||
# human-thread probe: skipped. S1 has 1 threads row, and threads --tester lists the 177-185 window's tester thread d0ba7a66, so no human thread exists to read
|
||||
# W9 checks and turns end 2026-10-20T22:06:06Z; the assistant run wait and S2 are w9b.sh
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
#!/usr/bin/env bash
|
||||
# Re-pin 4429a104f, W9 checks and the turns (repin-4429a104f.md at f41729178, sha256 e1272d1a; the W9 list of
|
||||
# repin-rows-177-185.md plus the journal Sign-in line and the Console cwd), on Mos's go mos-1114.
|
||||
# Adapted from Darkwing's window-rows-177-185/w9.sh. Every call goes through w.sh into W.txt; every bus call carries
|
||||
# --tester. A failed check stops the script. The wait for the assistant run and S2 are in w9b.sh, so the interim
|
||||
# report to Mos goes out between the two (report rule, waits over 5 minutes).
|
||||
# usage: w9.sh
|
||||
set -uo pipefail
|
||||
REPO=/mnt/storage/src/mosaic-stack
|
||||
WIN=$REPO/agents/sage/work/window-repin-4429a104f
|
||||
NEW=4429a104f6d65ccf165f6c83b5d1dce3147dfde0
|
||||
W5_STAMP="2026-10-20 22:02:06 UTC"
|
||||
W5_MS=$(date -d "2026-10-20T22:02:06Z" +%s)000
|
||||
PLAN=$REPO/agents/sage/work/window-plan/repin-4429a104f.md
|
||||
PLAN_SHA=e1272d1a391e00fb1291d47da9973c0ba342d65fcd42f583ea007e883c1f32b9
|
||||
TOOL_BLOB=3b068b1546d4020cffde5d73929d9130afe91911
|
||||
CC=/mnt/storage/scratch/sage-pin-de352dfaf/console-check.sh
|
||||
CC_SHA=d068fe02da897b700110a162d13d9671fe5994f053c45aff99113fade737094c
|
||||
CONSOLE_PID=2950925
|
||||
PRIOR_TID=d0ba7a66-aa3f-4918-9518-94132bce6b28
|
||||
MOSAIC=$HOME/.npm-global/bin/mosaic
|
||||
C_NEW=(node "$HOME/.local/share/mosaic-stack/copies/$NEW/packages/cli/src/cli.mjs")
|
||||
BZ=(--business mosaic-stack)
|
||||
W=$WIN/W.txt
|
||||
note() { echo "# $*" >> "$W"; echo "# $*"; }
|
||||
stop() { note "STOP: $*"; exit 1; }
|
||||
sha() { sha256sum < "$1" | cut -c1-64; }
|
||||
step() { local f="$1"; shift; $WIN/w.sh W.txt "$@" > "$WIN/$f"; local rc=$?; cat "$WIN/$f"; return $rc; }
|
||||
|
||||
note "W9 go mos-1114, start $(date -u +%FT%TZ)"
|
||||
[ "$(sha $PLAN)" = "$PLAN_SHA" ] || stop "the plan file is not e1272d1a"
|
||||
[ "$(git -C $REPO rev-parse HEAD:scripts/stack-release.sh)" = "$TOOL_BLOB" ] || stop "tool blob moved"
|
||||
[ "$(sha $CC)" = "$CC_SHA" ] || stop "console-check.sh is not d068fe02 (SCRIPTS.sha256)"
|
||||
grep -q "/copies/$NEW/scripts/mosaic" "$MOSAIC" || stop "the wrapper is not pinned to NEW"
|
||||
note "plan e1272d1a, tool blob 3b068b1546d4, console-check.sh d068fe02, wrapper on NEW: checked"
|
||||
|
||||
# checks
|
||||
step .w9-status.txt "W9 status" scripts/stack-release.sh status mosaic-stack || stop "W9 status exit"
|
||||
grep -q "\"copy\":\"$NEW\"" $WIN/.w9-status.txt && grep -q '"pm":true' $WIN/.w9-status.txt && grep -q '"schema":"3i"' $WIN/.w9-status.txt || stop "W9 status: pointer not on NEW, pm true, 3i"
|
||||
grep -q 'unit flags: match the pointer' $WIN/.w9-status.txt || stop "W9 status: unit flags"
|
||||
step .w9-cc.txt "W9 console-check NEW ($CC, d068fe02)" bash $CC $NEW || stop "console-check exit"
|
||||
grep -qx CONSOLE_PASS $WIN/.w9-cc.txt || stop "console-check not CONSOLE_PASS"
|
||||
J=$(journalctl --user -u mosaic-webui.service --since "$W5_STAMP" --no-pager)
|
||||
N=$(printf '%s\n' "$J" | grep -c 'Proxy: proxy proof off'); S=$(printf '%s\n' "$J" | grep -c 'Sign-in:')
|
||||
{ echo; echo "## W9 webui journal since $W5_STAMP: 'Proxy: proxy proof off' and 'Sign-in:' counts"; echo "proxy proof off $N, Sign-in $S"; } >> "$W"
|
||||
note "journal since W5: proxy proof off $N, Sign-in $S"
|
||||
[ "$N" = 1 ] || stop "proxy proof off count is $N, not 1"
|
||||
[ "$S" = 0 ] || stop "Sign-in count is $S, not 0"
|
||||
systemctl --user show -p MainPID --value mosaic-webui.service | grep -qx "$CONSOLE_PID" || stop "Console MainPID is not $CONSOLE_PID"
|
||||
CWD=$(readlink /proc/$CONSOLE_PID/cwd)
|
||||
{ echo; echo "## W9 Console pid $CONSOLE_PID cwd"; ls -l /proc/$CONSOLE_PID/cwd | sed 's/^.* -> /-> /'; } >> "$W"
|
||||
note "Console pid $CONSOLE_PID cwd $CWD"
|
||||
[ "$CWD" = "$HOME/.local/share/mosaic-stack/copies/$NEW" ] || stop "Console cwd is not the NEW copy"
|
||||
step .w9-launches.txt "W9 launches list" $MOSAIC launches list || stop "launches list"
|
||||
step .w9-launches.json "W9 launches list --json" $MOSAIC launches list --json || stop "launches list --json"
|
||||
sed -i '$d' $WIN/.w9-launches.json
|
||||
CHIEF=$(node -e '
|
||||
const l=JSON.parse(require("fs").readFileSync(process.argv[1],"utf8")),since=Number(process.argv[2]);
|
||||
const c=l.filter(x=>x.business==="mosaic-stack"&&x.instance==="chief"&&x.live===true);
|
||||
if(c.length!==1||!(Date.parse(c[0].startedAt)>=since)){console.error(`running chiefs ${c.length}`);process.exit(1)}
|
||||
process.stdout.write(c[0].run)' $WIN/.w9-launches.json "$W5_MS") || stop "launches: not one running chief from this start"
|
||||
note "one running chief from this start: run $CHIEF"
|
||||
step .w9-agents.txt "W9 agents --tester" $MOSAIC agents "${BZ[@]}" --tester || stop "agents"
|
||||
grep -E '(^|[[:space:]])chief[[:space:]].*working' $WIN/.w9-agents.txt && stop "the chief is working"
|
||||
|
||||
# turns
|
||||
step .w9-talk-chief.txt "W9 talk chief --tester" $MOSAIC talk chief "[mos test] re-pin $NEW: reply with one line, no staffing request" "${BZ[@]}" --tester || stop "talk chief"
|
||||
PROJ=window-$(date -u +%Y%m%d-%H%M)
|
||||
step .w9-project.txt "W9 project create $PROJ --tester" $MOSAIC project create $PROJ "${BZ[@]}" --tester || stop "project create"
|
||||
step .w9-thread.txt "W9 thread create $PROJ w9 --tester" $MOSAIC thread create $PROJ w9 "${BZ[@]}" --tester || stop "thread create"
|
||||
TID=$(sed -n "s/^created $PROJ\/w9 id \([0-9a-f-]*\) instance .*$/\1/p" $WIN/.w9-thread.txt)
|
||||
[ -n "$TID" ] || stop "no thread id"
|
||||
note "project $PROJ, thread $TID"
|
||||
echo "$TID" > $WIN/.w9-tid.txt
|
||||
step .w9-talk-thread.txt "W9 talk --thread --wait 180 --tester" $MOSAIC talk --thread "$TID" "[mos test] reply with one line, then stop" --wait 180 "${BZ[@]}" --tester || stop "talk --thread"
|
||||
note "reply received $(date -u +%FT%TZ)"
|
||||
date -u +%s > $WIN/.w9-reply-at.txt
|
||||
step .w9-thread-read.json "W9 thread read --json --tester" $MOSAIC thread read "$TID" --json "${BZ[@]}" --tester || stop "thread read"
|
||||
sed -i '$d' $WIN/.w9-thread-read.json
|
||||
node -e '
|
||||
const t=JSON.parse(require("fs").readFileSync(process.argv[1],"utf8"));
|
||||
console.log(`# thread read: ${t.length} messages: ${t.map(m=>`${m.from_role}->${m.to_role} ${m.class}`).join(", ")}`);
|
||||
process.exit(t.length===2&&t[0].from_role==="tester"&&t[1].from_role==="assistant"?0:1)' $WIN/.w9-thread-read.json | tee -a "$W" || stop "thread read is not the tester message plus one assistant reply"
|
||||
step .w9-threads.txt "W9 threads --tester" $MOSAIC threads "${BZ[@]}" --tester || stop "threads"
|
||||
grep -q "$TID\|$PROJ" $WIN/.w9-threads.txt || stop "threads does not list the W9 thread"
|
||||
step .w9-names.json "W9 C_NEW names --tester --json" "${C_NEW[@]}" names "${BZ[@]}" --tester --json || stop "names"
|
||||
step .w9-usage.json "W9 usage --tester --json" $MOSAIC usage "${BZ[@]}" --tester --json || stop "usage"
|
||||
if grep -q "${PRIOR_TID:0:8}" $WIN/.w9-threads.txt; then
|
||||
note "human-thread probe: skipped. S1 has 1 threads row, and threads --tester lists the 177-185 window's tester thread ${PRIOR_TID:0:8}, so no human thread exists to read"
|
||||
else
|
||||
note "human-thread probe: S1's one thread is not in threads --tester; probe it by hand before S2"
|
||||
fi
|
||||
note "W9 checks and turns end $(date -u +%FT%TZ); the assistant run wait and S2 are w9b.sh"
|
||||
@@ -0,0 +1,185 @@
|
||||
# W9b start 2026-10-20T22:06:27Z: waiting for the launcher to end r497f1c817d4d (thread 446201de-e8b5-4df3-9356-d0d5422cc899), no stop by hand
|
||||
# r497f1c817d4d not live in launches list --json by 2026-10-20T22:21:07Z (5 s poll)
|
||||
r097436c91816 mosaic-stack/chief claude-code claude-opus-5-5 by jason since 2026-10-20T22:02:08.941Z running
|
||||
# exit 0
|
||||
|
||||
## W9b launches log lines for r497f1c817d4d (at, event, instance, thread, run, reason, exitCode, signal only)
|
||||
at=2026-10-20T22:06:00.766Z event=launch instance=assistant thread=446201de-e8b5-4df3-9356-d0d5422cc899 run=r497f1c817d4d
|
||||
at=2026-10-20T22:21:05.149Z event=thread-idle instance=assistant thread=446201de-e8b5-4df3-9356-d0d5422cc899 run=r497f1c817d4d
|
||||
at=2026-10-20T22:21:05.171Z event=end instance=assistant thread=446201de-e8b5-4df3-9356-d0d5422cc899 run=r497f1c817d4d reason=stopped exitCode=0 signal=null
|
||||
|
||||
## W9b bus and webui journal since 2026-10-20 22:05:00 UTC, lines naming r497f1c817d4d or thread-idle
|
||||
2026-10-20T17:21:05.171444-05:00 dragon-lin mosaic[2950923]: mosaic-bus: run r497f1c817d4d (assistant) ended: stopped
|
||||
(grep exit 0)
|
||||
# SNAP sha256 639fd28a checked before S2 2026-10-20T22:21:07Z
|
||||
{
|
||||
"schema": "3i",
|
||||
"tables": {
|
||||
"decision_events": {
|
||||
"rows": 21,
|
||||
"maxSeq": 21,
|
||||
"sha256": "28dd95056663dd5eb7442a3d815b73a4a3cd311a0e854fd82dc54f7dc3e6ef26"
|
||||
},
|
||||
"decisions": {
|
||||
"rows": 21,
|
||||
"maxSeq": 21,
|
||||
"sha256": "fef1058660b0d128ef21089dda5e0fba7f71763d8325148fe521de0d3f57e4ad"
|
||||
},
|
||||
"deliveries": {
|
||||
"rows": 1740,
|
||||
"maxSeq": 1740,
|
||||
"sha256": "554ce5b377ffacc72bfde11c99c920cd5d30337c8bfa217275d0073b587e2169"
|
||||
},
|
||||
"events": {
|
||||
"rows": 1543,
|
||||
"maxSeq": 1543,
|
||||
"sha256": "0151673193d0286ce8f3b234d7d21fa2b0f43f2ceec55644cccaa5cbd77603dd"
|
||||
},
|
||||
"instance_names": {
|
||||
"rows": 0,
|
||||
"maxSeq": null,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"message_threads": {
|
||||
"rows": 4,
|
||||
"maxSeq": null
|
||||
},
|
||||
"messages": {
|
||||
"rows": 571,
|
||||
"maxSeq": 571
|
||||
},
|
||||
"meta": {
|
||||
"rows": 3,
|
||||
"maxSeq": null,
|
||||
"sha256": "89fec56e7293d19e0b2f6cd8c0ef745ebf99e4115abeaea7fbdbc98a261332d9"
|
||||
},
|
||||
"projects": {
|
||||
"rows": 2,
|
||||
"maxSeq": 2,
|
||||
"sha256": "3435f574ab94bc2fcc65fb8605251f30d4e9e63baf38e6fdf3c39c126531aa63"
|
||||
},
|
||||
"role_claims": {
|
||||
"rows": 101,
|
||||
"maxSeq": 101,
|
||||
"sha256": "fb47114defbb8a57dd148a06fbaf61b30f791a81f14b1510b8c32690506b4308"
|
||||
},
|
||||
"task_comment_cursors": {
|
||||
"rows": 220,
|
||||
"maxSeq": 220,
|
||||
"sha256": "df03c84094999299499de01107ddd08636df6156f5c9ccd2ff6e8c43e459f7e4"
|
||||
},
|
||||
"task_snapshots": {
|
||||
"rows": 408,
|
||||
"maxSeq": 408,
|
||||
"sha256": "e2243a89388afba07e8d096b4961deeb2d17c656cdcace54b46eac7001393814"
|
||||
},
|
||||
"thread_claims": {
|
||||
"rows": 4,
|
||||
"maxSeq": 4,
|
||||
"sha256": "088b8236570d8afe03364b85803fdc5034cce2cef6ed7b16f8b99bf6366524ad"
|
||||
},
|
||||
"thread_opens": {
|
||||
"rows": 0,
|
||||
"maxSeq": null,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"threads": {
|
||||
"rows": 2,
|
||||
"maxSeq": 2,
|
||||
"sha256": "819fd24c64e279d0debad5ab5dbbe533d8e6f26de58277c69510b9cbbaadbc3a"
|
||||
},
|
||||
"usage_records": {
|
||||
"rows": 34,
|
||||
"maxSeq": 34,
|
||||
"sha256": "de614f3d62c9b3819757c5659bee40085cb86cc873b7bfe381b13e254ddb7cad",
|
||||
"byRun": [
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "r8fba7e598156",
|
||||
"input": "0",
|
||||
"output": "0",
|
||||
"unknownTurns": 1
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "r4a96e2142e4d",
|
||||
"input": "2",
|
||||
"output": "52",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "rc78c9700c8e9",
|
||||
"input": "14",
|
||||
"output": "1519",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "r293f33bcbc63",
|
||||
"input": "2",
|
||||
"output": "44",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "r34520a581318",
|
||||
"input": "6",
|
||||
"output": "323",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "r7e99838f9f93",
|
||||
"input": "2",
|
||||
"output": "44",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "rc964611b2092",
|
||||
"input": "4",
|
||||
"output": "120",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "rbb708846b605",
|
||||
"input": "12",
|
||||
"output": "2089",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "rc36b17ef3788",
|
||||
"input": "16",
|
||||
"output": "5221",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "r097436c91816",
|
||||
"input": "2",
|
||||
"output": "131",
|
||||
"unknownTurns": 0
|
||||
},
|
||||
{
|
||||
"business": "mosaic-stack",
|
||||
"run": "r497f1c817d4d",
|
||||
"input": "2",
|
||||
"output": "80",
|
||||
"unknownTurns": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"untimed": [
|
||||
"message_threads",
|
||||
"meta",
|
||||
"task_comment_cursors"
|
||||
]
|
||||
}
|
||||
# exit 0
|
||||
# S2.json sha256 1a444f5ac0049bc78e397b6928e1008cfe8cbc30989bbf2042b4ed27f56a4173
|
||||
# W9b end 2026-10-20T22:21:07Z
|
||||
rc=0
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env bash
|
||||
# Re-pin 4429a104f, W9 tail (adapted from Darkwing's window-rows-177-185/w9b.sh, under mos-0948's ruling for that window: the launcher
|
||||
# ends the assistant run at threadIdleSeconds 900 after the 22:06:05Z reply, about 22:21:05Z). Nothing is stopped by hand. Report if live at 22:27Z.
|
||||
# usage: w9b.sh
|
||||
set -uo pipefail
|
||||
REPO=/mnt/storage/src/mosaic-stack
|
||||
WIN=/mnt/storage/src/mosaic-stack/agents/sage/work/window-repin-4429a104f
|
||||
RUN=r497f1c817d4d
|
||||
TID=446201de-e8b5-4df3-9356-d0d5422cc899
|
||||
DATA=/home/jwoltje/.mosaic-dev
|
||||
SNAP=$WIN/snapshot.mjs
|
||||
SNAP_SHA=639fd28a2674aaa03ce824e3394b4052f21cdef7d6fa49bae61a9927ed341e67
|
||||
PLAN=$REPO/agents/sage/work/window-plan/repin-4429a104f.md
|
||||
PLAN_SHA=e1272d1a391e00fb1291d47da9973c0ba342d65fcd42f583ea007e883c1f32b9
|
||||
TOOL_BLOB=3b068b1546d4020cffde5d73929d9130afe91911
|
||||
MOSAIC=$HOME/.npm-global/bin/mosaic
|
||||
DEADLINE=$(date -d "2026-10-20T22:27:00Z" +%s)
|
||||
MARK18=$(date -d "2026-10-20T22:22:00Z" +%s)
|
||||
W=$WIN/W.txt
|
||||
note() { echo "# $*" >> "$W"; echo "# $*"; }
|
||||
stop() { note "STOP: $*"; exit 1; }
|
||||
sha() { sha256sum < "$1" | cut -c1-64; }
|
||||
step() { local f="$1"; shift; $WIN/w.sh W.txt "$@" > "$WIN/$f"; local rc=$?; cat "$WIN/$f"; return $rc; }
|
||||
# launches log lines for the run: at, event, instance, thread, run, reason, exitCode, signal only
|
||||
runlog() { node -e '
|
||||
const keep=["at","event","instance","thread","run","reason","exitCode","signal"];
|
||||
for(const s of require("fs").readFileSync(process.argv[1],"utf8").trim().split("\n")){const o=JSON.parse(s);if(o.run!==process.argv[2])continue;
|
||||
console.log(keep.filter(k=>k in o).map(k=>`${k}=${o[k]}`).join(" "))}' "$DATA/launches/mosaic-stack.jsonl" "$RUN"; }
|
||||
|
||||
note "W9b start $(date -u +%FT%TZ): waiting for the launcher to end $RUN (thread $TID), no stop by hand"
|
||||
[ "$(sha $PLAN)" = "$PLAN_SHA" ] || stop "the plan file is not e1272d1a"
|
||||
[ "$(git -C $REPO rev-parse HEAD:scripts/stack-release.sh)" = "$TOOL_BLOB" ] || stop "tool blob moved"
|
||||
END=; M18=
|
||||
while :; do
|
||||
$MOSAIC launches list --json > $WIN/.w9b-poll.json 2>&1 || stop "launches poll"
|
||||
LIVE=$(node -e 'const l=JSON.parse(require("fs").readFileSync(process.argv[1],"utf8"));process.stdout.write(l.filter(x=>x.run===process.argv[2]&&x.live===true).map(x=>x.run).join(" "))' $WIN/.w9b-poll.json $RUN)
|
||||
[ -z "$LIVE" ] && { END=$(date -u +%FT%TZ); break; }
|
||||
NOW=$(date +%s)
|
||||
if [ -z "$M18" ] && [ $NOW -ge $MARK18 ]; then M18=1; note "22:22Z mark $(date -u +%FT%TZ): $RUN still live; launches log lines for it:"; runlog | tee -a "$W"; fi
|
||||
[ $NOW -ge $DEADLINE ] && break
|
||||
sleep 5
|
||||
done
|
||||
if [ -z "$END" ]; then
|
||||
note "STOP: $RUN still live at $(date -u +%FT%TZ) (22:27Z mark); a stop is Mos's call. S2 waits."
|
||||
runlog | tee -a "$W"
|
||||
exit 4
|
||||
fi
|
||||
note "$RUN not live in launches list --json by $END (5 s poll)"
|
||||
step .w9b-launches-after.txt "W9b launches list after the assistant run" $MOSAIC launches list
|
||||
{ echo; echo "## W9b launches log lines for $RUN (at, event, instance, thread, run, reason, exitCode, signal only)"; runlog; } | tee -a "$W"
|
||||
{ echo; echo "## W9b bus and webui journal since 2026-10-20 22:05:00 UTC, lines naming $RUN or thread-idle"; journalctl --user -u [email protected] -u mosaic-webui.service --since "2026-10-20 22:05:00 UTC" --no-pager -o short-iso-precise | grep -E "$RUN|thread-idle|threadIdle"; echo "(grep exit ${PIPESTATUS[1]})"; } | tee -a "$W"
|
||||
[ "$(sha $SNAP)" = "$SNAP_SHA" ] || stop "SNAP sha before S2"
|
||||
note "SNAP sha256 639fd28a checked before S2 $(date -u +%FT%TZ)"
|
||||
step S2.json "S2 snapshot --held" node $SNAP --store "$DATA/bus/bus.sqlite" --held || stop "S2"
|
||||
sed -i '$d' $WIN/S2.json
|
||||
note "S2.json sha256 $(sha $WIN/S2.json)"
|
||||
note "W9b end $(date -u +%FT%TZ)"
|
||||
@@ -0,0 +1,43 @@
|
||||
# W0b-W4 start 2026-10-20T22:00:49Z
|
||||
# plan e1272d1a, tool blob 3b068b1546d4, P5 four scripts at NEW and clean, business-check.mjs eece4d46: checked 2026-10-20T22:00:49Z
|
||||
# W0 copy present, w0.txt LOAD_OK
|
||||
# W0b: /home/jwoltje/.config/mosaic-dev/businesses/mosaic-stack.json.pre-window-20261020T220049Z, sha256 1e49bdf05e62607972958f5b7298cfd600c7825812370e26d7c2a842f2af9b93, recorded in backups.txt
|
||||
rbb708846b605 mosaic-stack/chief claude-code claude-opus-5-5 by jason since 2026-10-20T19:29:59.045Z running
|
||||
rc36b17ef3788 mosaic-stack/pm claude-code claude-opus-5-5 by chief since 2026-10-20T20:20:56.252Z running
|
||||
# exit 0
|
||||
# W1 start stamp 2026-10-20T22:00:49Z
|
||||
# SNAP sha256 639fd28a checked before S1
|
||||
# S1.json sha256 a7649760c3439705c8b5f3af26d0c21aea1081c1eb295fd02aef3a642064194b
|
||||
pointer: /home/jwoltje/.mosaic-dev/state/stack-active.json
|
||||
{"copy":"490e2771d3d057ab76991e2c7859cd251857e64c","business":"mosaic-stack","pm":true,"claude":"/home/jwoltje/.local/bin/claude","console":["--port","7332","--public-host","mosaic.woltje.com","--auth-header","X-authentik-username","--allow-user","jason.woltje","--tester-port","7333"],"schema":"3i","activation":"20261020T192956Z-490e2771d3d0","at":"2026-10-20T19:30:00Z"}
|
||||
log (last five lines):
|
||||
{"at":"2026-10-20T01:41:05Z","op":"pm-on","from":"89af38a83afa22a8a4f0d368a0a4030ad15a0efa","to":"89af38a83afa22a8a4f0d368a0a4030ad15a0efa","backup":null,"activation":"20261020T014103Z-89af38a83afa","result":"ok","pm":"on"}
|
||||
{"at":"2026-10-20T07:58:00Z","op":"activate","from":"89af38a83afa22a8a4f0d368a0a4030ad15a0efa","to":"490e2771d3d057ab76991e2c7859cd251857e64c","backup":null,"activation":"20261020T075800Z-490e2771d3d0","result":"started"}
|
||||
{"at":"2026-10-20T07:58:02Z","op":"activate","from":"89af38a83afa22a8a4f0d368a0a4030ad15a0efa","to":"490e2771d3d057ab76991e2c7859cd251857e64c","backup":"20261020T075800Z-490e2771d3d0","activation":"20261020T075800Z-490e2771d3d0","result":"ok"}
|
||||
{"at":"2026-10-20T19:29:56Z","op":"activate","from":"490e2771d3d057ab76991e2c7859cd251857e64c","to":"490e2771d3d057ab76991e2c7859cd251857e64c","backup":null,"activation":"20261020T192956Z-490e2771d3d0","result":"started"}
|
||||
{"at":"2026-10-20T19:30:00Z","op":"activate","from":"490e2771d3d057ab76991e2c7859cd251857e64c","to":"490e2771d3d057ab76991e2c7859cd251857e64c","backup":"20261020T192956Z-490e2771d3d0","activation":"20261020T192956Z-490e2771d3d0","result":"ok"}
|
||||
check:
|
||||
bus: /home/jwoltje/.local/share/mosaic-stack/copies/490e2771d3d057ab76991e2c7859cd251857e64c
|
||||
Console: /home/jwoltje/.local/share/mosaic-stack/copies/490e2771d3d057ab76991e2c7859cd251857e64c
|
||||
CLI: /home/jwoltje/.local/share/mosaic-stack/copies/490e2771d3d057ab76991e2c7859cd251857e64c
|
||||
result: pass
|
||||
bus status:
|
||||
host: mosaic-stack, pid 3229540, running, since 2026-10-20T19:29:57.662Z, notifier off
|
||||
socket: present
|
||||
writer.lock: pid 3229657
|
||||
boot: organization file loaded at 2026-10-20T19:29:57.661Z
|
||||
unit flags: match the pointer
|
||||
drift: 109 commit(s) on refactor since the pointer's copy
|
||||
# exit 0
|
||||
# W3-plan.txt sha256 45de68d42b4cf88640fe0986d071dba4fa076b7db86ff4ed34de4bb6fa2915c6
|
||||
DropInPaths=
|
||||
ExecStart={ path=/home/jwoltje/.local/share/mosaic-stack/copies/490e2771d3d057ab76991e2c7859cd251857e64c/scripts/mosaic ; argv[]=/home/jwoltje/.local/share/mosaic-stack/copies/490e2771d3d057ab76991e2c7859cd251857e64c/scripts/mosaic bus start mosaic-stack --pm ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }
|
||||
WorkingDirectory=/home/jwoltje/.local/share/mosaic-stack/copies/490e2771d3d057ab76991e2c7859cd251857e64c
|
||||
# exit 0
|
||||
DropInPaths=
|
||||
ExecStart={ path=/usr/bin/node ; argv[]=/usr/bin/node /home/jwoltje/.local/share/mosaic-stack/copies/490e2771d3d057ab76991e2c7859cd251857e64c/packages/webui/src/cli.mjs serve --checkout /mnt/storage/src/mosaic-stack --port 7332 --public-host mosaic.woltje.com --auth-header X-authentik-username --allow-user jason.woltje --tester-port 7333 ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }
|
||||
WorkingDirectory=/home/jwoltje/.local/share/mosaic-stack/copies/490e2771d3d057ab76991e2c7859cd251857e64c
|
||||
# exit 0
|
||||
# W4 checks: DropInPaths empty on both, both ExecStart name the OLD copy, bus has --pm, no quote or backslash in either ExecStart
|
||||
# W4 bus Environment: 2 assignments; quote or backslash: none (values not recorded)
|
||||
# W0b-W4 end 2026-10-20T22:00:50Z
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env bash
|
||||
# Re-pin 4429a104f, W0b-W4 (repin-4429a104f.md at f41729178, sha256 e1272d1a...32b9; mos-1105, mos-1107 go). W0 ran before P2.
|
||||
# Adapted from Darkwing's window-rows-177-185/wsteps.sh.
|
||||
# Nothing is stopped. Each step goes through w.sh into W.txt; a failed check stops the script.
|
||||
# usage: wsteps.sh
|
||||
set -uo pipefail
|
||||
REPO=/mnt/storage/src/mosaic-stack
|
||||
WIN=$REPO/agents/sage/work/window-repin-4429a104f
|
||||
OLD=490e2771d3d057ab76991e2c7859cd251857e64c
|
||||
NEW=4429a104f6d65ccf165f6c83b5d1dce3147dfde0
|
||||
PLAN=$REPO/agents/sage/work/window-plan/repin-4429a104f.md
|
||||
PLAN_SHA=e1272d1a391e00fb1291d47da9973c0ba342d65fcd42f583ea007e883c1f32b9
|
||||
TOOL_BLOB=3b068b1546d4020cffde5d73929d9130afe91911
|
||||
BC=$REPO/agents/sage/work/window-plan/repin-de352dfaf/business-check.mjs
|
||||
BC_SHA=eece4d4671e1ce15ba81e1654c641925ac4988b343687b062897392285a8a1a7
|
||||
BIZ=$HOME/.config/mosaic-dev/businesses/mosaic-stack.json
|
||||
BIZ_SHA=1e49bdf05e62607972958f5b7298cfd600c7825812370e26d7c2a842f2af9b93
|
||||
DATA=/home/jwoltje/.mosaic-dev
|
||||
SNAP=$WIN/snapshot.mjs
|
||||
SNAP_SHA=639fd28a2674aaa03ce824e3394b4052f21cdef7d6fa49bae61a9927ed341e67
|
||||
MOSAIC=$HOME/.npm-global/bin/mosaic
|
||||
W=$WIN/W.txt
|
||||
note() { echo "# $*" >> "$W"; echo "# $*"; }
|
||||
stop() { note "STOP: $*"; exit 1; }
|
||||
sha() { sha256sum < "$1" | cut -c1-64; }
|
||||
|
||||
note "W0b-W4 start $(date -u +%FT%TZ)"
|
||||
[ "$(git -C $REPO show f41729178:agents/sage/work/window-plan/repin-4429a104f.md | sha256sum | cut -c1-64)" = "$PLAN_SHA" ] || stop "plan at f41729178 is not e1272d1a"
|
||||
[ "$(sha $PLAN)" = "$PLAN_SHA" ] || stop "the plan file in REPO is not e1272d1a"
|
||||
[ "$(git -C $REPO rev-parse HEAD:scripts/stack-release.sh)" = "$TOOL_BLOB" ] || stop "tool blob moved"
|
||||
git -C $REPO diff --quiet $NEW HEAD -- scripts/stack-release.sh scripts/webui-service.sh scripts/bus-service.sh scripts/stack-copy.sh || stop "P5: the four scripts differ from NEW"
|
||||
[ -z "$(git -C $REPO status --porcelain -- scripts/stack-release.sh scripts/webui-service.sh scripts/bus-service.sh scripts/stack-copy.sh)" ] || stop "P5: the four scripts are dirty"
|
||||
[ "$(sha $BC)" = "$BC_SHA" ] || stop "business-check.mjs sha"
|
||||
note "plan e1272d1a, tool blob 3b068b1546d4, P5 four scripts at NEW and clean, business-check.mjs eece4d46: checked $(date -u +%FT%TZ)"
|
||||
|
||||
# W0 ran at 21:45:57Z (w0.txt): the copy must still be there with LOAD_OK recorded.
|
||||
[ -f "$HOME/.local/share/mosaic-stack/copies/$NEW/scripts/mosaic" ] || stop "W0 copy missing"
|
||||
grep -qx LOAD_OK $WIN/w0.txt || stop "w0.txt has no LOAD_OK"
|
||||
note "W0 copy present, w0.txt LOAD_OK"
|
||||
|
||||
# W0b
|
||||
[ "$(sha $BIZ)" = "$BIZ_SHA" ] || stop "business file sha256 is not P1's 1e49bdf0"
|
||||
STAMP=$(date -u +%Y%m%dT%H%M%SZ)
|
||||
COPY=$BIZ.pre-window-$STAMP
|
||||
[ ! -e "$COPY" ] || stop "$COPY exists"
|
||||
cp -p "$BIZ" "$COPY" || stop "W0b cp"
|
||||
[ "$(sha "$COPY")" = "$BIZ_SHA" ] || stop "W0b copy sha256"
|
||||
echo "W0b $(date -u +%FT%TZ) business file copy $COPY sha256 $(sha "$COPY") (source $BIZ sha256 $(sha "$BIZ"))" >> $WIN/backups.txt
|
||||
note "W0b: $COPY, sha256 $(sha "$COPY"), recorded in backups.txt"
|
||||
|
||||
# W1
|
||||
$WIN/w.sh W.txt "W1 agents --tester" $MOSAIC agents --business mosaic-stack --tester > $WIN/.w1-agents.txt || stop "W1 agents"
|
||||
grep -E '(^|[[:space:]])chief[[:space:]].*working' $WIN/.w1-agents.txt && stop "W1: the chief is working"
|
||||
$WIN/w.sh W.txt "W1 launches list" $MOSAIC launches list || stop "W1 launches list"
|
||||
note "W1 start stamp $(date -u +%FT%TZ)"
|
||||
[ "$(sha $SNAP)" = "$SNAP_SHA" ] || stop "SNAP sha before S1"
|
||||
note "SNAP sha256 639fd28a checked before S1"
|
||||
$WIN/w.sh W.txt "S1 snapshot --held" node $SNAP --store "$DATA/bus/bus.sqlite" --held > $WIN/S1.json || stop "S1"
|
||||
sed -i '$d' $WIN/S1.json # w.sh prints "# exit N" last; S1.json keeps the snapshot only
|
||||
note "S1.json sha256 $(sha $WIN/S1.json)"
|
||||
|
||||
# W2
|
||||
$WIN/w.sh W.txt "W2 status" scripts/stack-release.sh status mosaic-stack || stop "W2 status"
|
||||
|
||||
# W3
|
||||
$WIN/w.sh W.txt "W3 activate NEW --pm --plan" scripts/stack-release.sh activate $NEW mosaic-stack --pm --plan > $WIN/W3-plan.txt || stop "W3 plan exit"
|
||||
sed -i '$d' $WIN/W3-plan.txt
|
||||
note "W3-plan.txt sha256 $(sha $WIN/W3-plan.txt)"
|
||||
|
||||
# W4
|
||||
$WIN/w.sh W.txt "W4 bus unit (Environment omitted from the transcript)" systemctl --user show [email protected] -p ExecStart -p WorkingDirectory -p DropInPaths || stop "W4 bus"
|
||||
$WIN/w.sh W.txt "W4 webui unit" systemctl --user show mosaic-webui.service -p ExecStart -p WorkingDirectory -p DropInPaths || stop "W4 webui"
|
||||
BUSL=$(systemctl --user show [email protected] -p ExecStart -p DropInPaths -p WorkingDirectory)
|
||||
WEBL=$(systemctl --user show mosaic-webui.service -p ExecStart -p DropInPaths -p WorkingDirectory)
|
||||
for u in BUSL WEBL; do v=${!u}; grep -qx 'DropInPaths=' <<< "$v" || stop "W4 $u DropInPaths not empty"; grep '^ExecStart=' <<< "$v" | grep -q "copies/$OLD/" || stop "W4 $u ExecStart does not name the OLD copy"; grep '^ExecStart=' <<< "$v" | grep -q "copies/$NEW" && stop "W4 $u ExecStart names NEW"; grep '^ExecStart=' <<< "$v" | grep -q "[\"'\\\\]" && stop "W4 $u ExecStart has a quote or backslash"; done
|
||||
grep '^ExecStart=' <<< "$BUSL" | grep -q -- ' --pm' || stop "W4 bus ExecStart has no --pm"
|
||||
note "W4 checks: DropInPaths empty on both, both ExecStart name the OLD copy, bus has --pm, no quote or backslash in either ExecStart"
|
||||
ENVL=$(systemctl --user show [email protected] -p Environment)
|
||||
note "W4 bus Environment: $(tr ' ' '\n' <<< "${ENVL#Environment=}" | grep -c =) assignments; quote or backslash: $(grep -q "[\"'\\\\]" <<< "$ENVL" && echo FOUND || echo none) (values not recorded)"
|
||||
note "W0b-W4 end $(date -u +%FT%TZ)"
|
||||
Reference in New Issue
Block a user