plans: v1 briefs for C2-09b rooms, C2-10c Console room view and C2-15 hybrid universes, with C2-15 named Opus 5.5 under Q177; new codes room-not-open and R8 for Sage (mos-1233, Q211, Vikunja 464)

This commit is contained in:
jason.woltje committed 2026-10-21 17:26:32 -05:00
1 parent cca206cdce
commit 72ceda9356
1 file changed
+227
+227
View File
@@ -1165,6 +1165,233 @@ Dewey runs the script and approves. It is green on Sage's gate with every `scrip
---
## v1 rows past the slice: rooms and hybrid universes (mos-1233)
Gosalyn, 2026-10-21 (from `date -u`), for mos-1233 (Vikunja 464). Mos reads Q211 to put rooms with @tags
(TARGET.md:99) and hybrid universes (TARGET.md:82) in v1. Design 9.2's "Not ready by 10-27" is a
capacity estimate, not a cut. If one misses 10-27 it is reported late. These three briefs follow the
form above and keep every rule listed at the top of this file. Bus writes and the editor rows (C2-02,
C2-03b, C2-11a, C2-11b, C2-19) stay as they are, since Q195 makes the editor an add-on. C2-16 to C2-18
stay later. Owners follow design 8 and Q177. Where a brief names only a model, Sage picks the seat.
Base: `refactor` at cca206cdc. Each row builds on its parents' candidates and rebases onto their
landings (Q177). C2-09a is row 219, C2-05a row 216, C2-05b row 224, C2-06 row 217 and C2-10b row 225,
all briefed and not landed. Line cites are at cca206cdc. A builder re-reads them on its base.
New refusal codes below go to Sage with these briefs, as the rule at the top asks: `room-not-open`
(C2-09b) and the problem code R8 (C2-15).
---
## C2-09b rooms: room.open, room.send with @tags, room.read
### Problem
TARGET.md:99 asks that she "converse with N agents in one chat session with @tagged messages to specify
only one addressee where desired". After C2-09a she can hold one thread per creative instance, but each
thread is a separate chat. `thread.send` reaches one thread's instance
(`packages/bus/src/broker.mjs:3511-3536`), and nothing sends one message to several threads or reads
them as one timeline. Design 6 sets out the room verbs.
### Owner and reviewer
- Owner: Rocko, gpt-6.1-sol (design 8).
- Reviewer: Dewey.
- After: C2-09a (row 219).
### Files owned
`packages/bus/src/broker.mjs` (the three room verbs only), a new pure module
`packages/bus/src/address.mjs` with the @tag parse, its export, `packages/bus/README.md` (the verb table
rows), and tests in `packages/bus/tests`.
### What ships
Design 6, C2-09b. A room is a project. Its members are the project's thread instances, the
`THREAD_DEFINITIONS` instances that C2-09a's `thread.create` accepts.
- `room.open {project}`. Human only. For each thread instance it creates a thread named after the
instance key, owned by the caller, through the same insert as `thread.create`. A same-name thread that
the caller owns on the same instance is reused. A same-name thread on another instance, or another
owner's, makes `room.open` refuse `room-thread-name-taken` and create nothing. Returns
`{project, threads: [{id, instance, name}]}`, sorted by instance key.
- `room.send {project, body}`. Human only. `parseAddress(body)` in `address.mjs` reads leading
`@name` tokens, each ended by whitespace, up to the first token that doesn't start with `@`. Names
resolve through `#named` (`broker.mjs:1480-1488`) or as instance keys, and must be members. With no
tag every member gets the message. Repeated tags count once. An unknown tag refuses
`unknown-addressee` and inserts nothing. A body of tags only refuses `invalid-request`. A room
whose member threads aren't all there refuses `room-not-open`. The body is stored as written, tags
included. Each target gets what `thread.send` writes today: `#checkMessaging(business, 'human',
instance)`, one message row, `#route` and one `human.input` event. All inserts use one `#now()` and
run inside the dispatch transaction, so one refused target leaves nothing inserted. Returns
`{ids: [...], to: [...]}`.
- `room.read {project, after?, limit?}`. Human only. The caller's member threads' messages, oldest
first by `messages.seq`, each with its `thread` and `instance`. The human's messages from one
`room.send` share `at`, body and sender, and come back as one entry with `to` listing the instances.
Paging follows `thread.messages` (`THREAD_PAGE`, `:260`): `after` is a message id in one of the
room's threads, else `message-not-found`.
- The tester gets none of the three verbs, so they aren't added to `TESTER_VERBS` (`:117-119`). A tester
session refuses as for any verb outside that list. An agent session refuses `human-required`.
- No schema change. Thread names stay unique per project (`packages/bus/schema.sql:249`).
Tests, from design 6: `@continuity x` makes exactly one message, in continuity's thread. No tag makes
one per member. `@nobody x` refuses with the `messages` count unchanged. A tag after the first word is
plain text. `room.open` against a same-name thread on another instance refuses and creates nothing, and a
second `room.open` reuses the threads. Also: a `#named` display name resolves, repeated tags send once, a
tags-only body refuses, a member whose messaging list refuses `human` makes the whole send insert
nothing, `room.read` merges one send into one entry, pages with `after`, and refuses an `after` from
another project. `parseAddress` has a table test, which C2-10c's parity test reuses.
### Out of scope
The Console room view (C2-10c). Agents reading each other's replies (C2-16). A Discord channel bound to
a room (C2-18). A CLI verb for rooms.
### Gate
Dewey approves the manifest. The bus suite is green on Sage's gate, along with every
`scripts/test-*.sh`. Grep `packages/*/tests` for `broker.mjs` and `TESTER_VERBS` before in-review,
since `packages/bus/tests/tester-writes.test.mjs` reads the tester list.
### Handoffs
Every seat hands off directly (DECISIONS Q210, mos-1221). When the owner pushes a build or a new round,
or the reviewer posts a verdict, that seat messages the next seat's T3 thread and Sage's with
`mcp__t3__t3_send_message`. Copy Mos's thread only when Mos has a step.
---
## C2-10c Console room view: merged timeline and @name completion
### Problem
The Console's chat lists threads one at a time. Its seam calls `thread.*` only
(`packages/webui/src/chat.mjs:19-27`), and the webui channel plugin allows only those verbs
(`packages/plugins/channel/webui/index.mjs:4-12`). So she can't see a room or send to it from the Console
(design 6, 7.4).
### Owner and reviewer
- Owner: a Haiku 5.5 subagent at high effort, dispatched by Sage (design 8, lead decision 129).
- Reviewer: Dewey.
- After: C2-09b, C2-10b (row 225).
### Files owned
`packages/webui/src/chat.mjs` (three room calls), `packages/webui/src/chat-http.mjs` (the room routes and
their codes), `packages/plugins/channel/webui/index.mjs` (the three room verbs in `VERBS`),
`packages/webui/src/public/chat.js` and `chat.css` (the room view), and tests in `packages/webui/tests`
and `packages/plugins/tests`.
### What ships
- A room view per project: an "Open room" control calls `room.open`. The timeline reads `room.read`
and shows every member's messages in one list, each marked with its agent's `persona.name` or
instance name. A human room message shows once with its addressees. Agent replies render through
C2-10b's cited-item renderer, with its scope badges and notices.
- The composer completes `@` against the room's members. The broker stays the authority: the browser
sends the body as typed through `room.send`, and shows the broker's `unknown-addressee` refusal as a
fixed line.
- `chat-http.mjs` maps `unknown-addressee` and `room-thread-name-taken` to 409 and `room-not-open` to 409,
with fixed text for each, as it does for the thread codes (`:15-23`).
Tests: webui tests for the merged timeline, one entry per room send, the reply renderer in the room,
completion against members, and each refusal's fixed line. A parity test runs C2-09b's `parseAddress`
case table through the browser's tag reader and asserts the same addressees for every case. The plugin
test asserts the webui channel allows the three room verbs and still refuses others.
### Out of scope
The broker verbs (C2-09b). Agents seeing each other's replies (C2-16). Library pages (C2-11b). Her sign-in
from her machine waits on SSO (#412) or Jason's interim ruling (design 10 step 5).
### Gate
Dewey approves the manifest. The webui and plugins suites are green on Sage's gate, along with every
`scripts/test-*.sh`. Grep for hash pins on `chat.js`, `chat-http.mjs` and the channel plugin before
in-review.
### Handoffs
Every seat hands off directly (DECISIONS Q210, mos-1221). When the owner pushes a build or a new round,
or the reviewer posts a verdict, that seat messages the next seat's T3 thread and Sage's with
`mcp__t3__t3_send_message`. Copy Mos's thread only when Mos has a step.
---
## C2-15 hybrid universes: exclusions, pins and the end-to-end crossover
### Problem
TARGET.md:79-84 allows a crossover only as a deliberate, user-sanctioned hybrid universe that reads the
character info of its sources and doesn't break her constraints. The parts are spread out. C2-01's
validator reads a hybrid entry (`packages/library/src/mapping.mjs:69-120`), and its reader skips R6 for a
link into a source (`reader.mjs:206-209`). C2-05a's queries and C2-06's guard take hybrids as a shape. M9
in C2-04 keeps agents off the mapping, so only her hand edit makes a hybrid. Three things are missing:
an `exclude` isn't checked against the sources, a link into an excluded path isn't reported, and nothing
checks a `pin` (design 1.4). Design 8 lists C2-15 with no model.
### Owner and reviewer
- Owner: an Opus 5.5 seat that Sage picks. Under Q177 Opus and gpt-6.1-sol share the harder builds. I
name Opus because the row crosses three rows' code and the universe boundary that keeps her worlds
apart.
- Reviewer: Filbert, who reviews C2-05a.
- After: C2-05a (row 216), C2-05b (row 224), C2-06 (row 217).
### Files owned
`packages/library/src/mapping.mjs` (the `exclude` check), `packages/library/src/problems.mjs` (R8),
`packages/library/src/reader.mjs` (the excluded-link R6 and the pin check), the guard file from C2-06
(`packages/library/src/guard.mjs`, the excluded-path cite only), `docs/case2/SETUP-SHEET.md` from C2-12 (one
hybrid section), and tests in `packages/library/tests` and `packages/bus/tests`.
### What ships
- The validator refuses `library-mapping-invalid` for an `exclude` that doesn't lie inside a book folder
of one of the hybrid's sources, and for a `pin.entity` outside them. Its existence at a commit is the
reader's to check.
- The reader adds R6 for a link from a hybrid file into an excluded path. The index already drops it
from the hybrid's results (C2-05a).
- R8, "pinned value changed", reported only, like R5 and R6. At each commit the reader reports R8 on the
pinned entity when the file is missing, or when its front matter `field` doesn't equal `value`. It also
reports R8 on a hybrid file, with the line, when its front matter sets `field` to another value and a
front matter wikilink in that file resolves to the entity. Values compare as the reader's parsed text
against `String(value)`. That second case is my reading of design 1.4's "when a hybrid file changes
it". The reviewer checks it against the design.
- The guard refuses `citation-cross-universe` for an item that cites a hybrid file together with an
excluded source path. An item that cites only one source universe is that universe's item, as now.
- The setup sheet gets one section on making a hybrid by hand: the entry's keys, `exclude`, `pin` and
`notes`, and that the continuity role cites the notes.
Tests, through a business-file hybrid on a bare repo in her layout's shape, and not only a hand-built
mapping: `library_find` and `library_search` in the hybrid return its own files and its sources' canon,
each with its source universe, and never a source's playground or an excluded path. `library_get` keeps
`links_out` into sources and drops excluded targets. A source universe's lookups never return hybrid
files. A cite to source canon in a hybrid item passes the guard, and one beside an excluded path
refuses with the `messages` count unchanged. `library_universe` returns sources, constraints and notes.
One case per validator refusal, per R8 case and for the excluded-link R6, and an agent's organization
write that adds a hybrid refuses `organization-projects-protected` (M9).
### Out of scope
Promotion and every write path (C2-02, C2-19). The Console's crossover button (C2-11b). Any check of a
plain-word constraint in code: `notes` stay for the continuity role to read and cite (design 1.4). Draft
universes as hybrid sources are refused by C2-01c (design ruling after r11, three levels).
### Gate
Filbert approves the manifest. The library and bus suites are green on Sage's gate, along with every
`scripts/test-*.sh`.
### Handoffs
Every seat hands off directly (DECISIONS Q210, mos-1221). When the owner pushes a build or a new round,
or the reviewer posts a verdict, that seat messages the next seat's T3 thread and Sage's with
`mcp__t3__t3_send_message`. Copy Mos's thread only when Mos has a step.
---
## Brief: row A, ZAI_API_KEY in the session env allowlist
### Problem