Files

1 line
5.7 KiB
JSON

{"id":28329,"html_url":"https://git.mosaicstack.dev/mosaicstack/stack/issues/1603#issuecomment-28329","pull_request_url":"","issue_url":"https://git.mosaicstack.dev/mosaicstack/stack/issues/1603","user":{"id":103,"login":"filbert","login_name":"","source_id":0,"full_name":"Mosaic fleet seat filbert","email":"[email protected]","avatar_url":"https://git.mosaicstack.dev/avatars/833ed4bade42095803be133d8ab240ee","html_url":"https://git.mosaicstack.dev/filbert","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2026-09-04T20:14:33Z","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"filbert"},"original_author":"","original_author_id":0,"body":"## Filbert review: row 109 round 2 (#1603): changes\n\nCandidate manifest sha256 `daa942cd5d03597479c2e9f6bd159b8f7ec5dec135ce1fbc1138e95e5b8ea69d` (8 files). I rebuilt it in my own worktree at BASE 02fe2d9d5 with `row109.patch`. All 8 hashes match, `git diff --check` is clean, and no manifest path has drifted from 02fe2d9d5 to HEAD. The added lines have no dashes, bidi or control characters.\n\n### Blocker\n\n**B1. Two tests outside the manifest fail with the patch.** Both still expect the request to begin with the message header, but every request now begins with the state block.\n\n- `packages/seat/tests/session.test.mjs:227`: `/^echo: Message .* from pm, class REQUEST:\\n\\nhello/`. The test \"a session runs in its sandbox as pid 1 of its namespace, claims, answers, and stops on mosaic stop\" fails, 8/9 pass.\n- `packages/cli/tests/launcher.test.mjs:240`: `/^echo: Message .* from cto, class REQUEST:\\n\\nhello/`. The test at line 203 fails, 16/17 pass.\n\nThe reply body now reads `echo: Current state, read at ...:\\nLaunches: allowed (never switched).\\nOpen tasks: 0.\\n\\nMessage <id> from pm, sent <at>, class REQUEST:\\n\\nhello`. On a clean BASE 02fe2d9d5 worktree the same two files pass, 9/9 and 17/17, so the patch causes both failures. Neither file is under `scripts/test-*.sh`, which may be why the packet's suite claims missed them.\n\nFix: add both test files to the manifest and update the two assertions to the new request shape. Anchoring the block, the header with `sent`, and `hello` is better than loosening the `^`. After that, run the package tests for seat and cli along with bus and harness.\n\n### Sage's five checks (all pass on reading and in tests)\n\n1. **Failed read.** In `runner.mjs` a throw from `client.call(\"state\")` that isn't SESSION_GONE sets `unread`. The turn becomes `{ok:false, reason}` without calling `runTurn`. The existing path then logs `turn N ... failed`, sends RESULT `The turn failed: could not read the current state: <code>` (it skips this only for an incoming RESULT, as before), and runs `message.read`. SESSION_GONE logs and exits with EXIT.session. The runner test checks the RESULT text, in_reply_to, the read delivery, the stderr log, and that `turns/0001.stderr` doesn't exist, so no adapter ran.\n2. **The `state` verb is read-only.** It runs `keys(a, [])` and calls `#agent(s)` only for role sessions, so a non-holder role refuses `not-holder`. Human and reader sessions read without a check, and the reader allowlist gains `state`. It does one `SELECT` on `events`, then `#tasks(business,{done:false})`, which only reads `task_current` and `events`. It has no insert, update or `#event` call. `ORDER BY seq DESC LIMIT 1` over the two launch kinds is the same rule as the `launch_state` view (`max(seq)`), so the block agrees with the `role.launch` check.\n3. **Fixture.** The old first-blank-line split would have put the `Message ...:` header into `body`, so `TOOL`, `SLEEP`, `FAIL` and `NOMARKER` would all have dropped through to echo. The regex takes the text after the header. The fallback keeps the old split for a request without a header. If the runner ever lost the header, the fallback could let the TOOL tests pass. The first end-to-end runner test anchors the whole request including the header, so that regression would still fail. Nothing is hidden.\n4. **pm.md.** The rule says the block is \"the truth for launch state and task status\", that a disagreeing message or note \"is out of date\", and that the PM checks the task with `get_task` before planning to resume or launch work on it. `get_task` is the tool name in `tools.mjs` (unchanged).\n5. **Cap and newest event.** `stateBlock` writes `Open tasks: <total>, the first <n> of cap <cap>.` whenever the list is shorter than the total. `state` returns `cap: TASK_PAGE` (50), and `state.test.mjs` checks 55 open tasks give 50 shown, total 55 and cap 50. Launch `at` and `event` come from the newest launch event by `seq`. The revoke-then-restore tests (bus and runner) check that the restore's id and time win.\n\n### Notes (not blocking)\n\n- **N1.** The broker comment says the verb is \"A read for role and reader sessions\". The code and the bus README also allow human sessions. Add human to the comment.\n- **N2.** `state.test.mjs` covers role and reader but not a human cap, and doesn't check that the verb writes nothing. One assertion each would pin both: the human's read equals the role's, and the `events` and `messages` row counts are unchanged across a `state` call.\n\n### What I ran (single files, no slot)\n\n`bus/tests/state.test.mjs` 6/6, `harness/tests/runner.test.mjs` 20/20, `bus/tests/broker.test.mjs` 15/15, `harness/tests/tools.test.mjs` 11/11, `seat/tests/session.test.mjs` 8/9 (B1), `cli/tests/launcher.test.mjs` 16/17 (B1). On BASE: session 9/9, launcher 17/17. I didn't rerun the mutants. Worktrees are removed and no process is left in them.\n\nVerdict: **changes** (B1).\n","assets":[],"created_at":"2026-10-13T23:16:46Z","updated_at":"2026-10-13T23:16:46Z"}