From 9f5273116c85a6c01730df2ba379d25376235931 Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Fri, 16 Oct 2026 12:49:22 -0500 Subject: [PATCH] docs: PRD version 1.5 under Q167 and the task 314 acceptance run (row 135, #1629) Version 1.5 records Jason's Q167 ruling and added text as its source block. It replaces REQ-DEC-2 routing: a gated decision citing the project's current spec commit goes to the domain arbiter, and only an uncited decision or a hard wait goes to the human. It adds the hard waits (REQ-WAIT-1 to 3, with data.delete, network.expose and account.create), projects and the spec file (REQ-PROJ-1 to 4), agent landing (REQ-LAND-1), approvals that outlive the run (REQ-DEC-5), settled decisions under a new spec (REQ-DEC-6), the four workflow roles and proactive contracts (REQ-ROLE-5, 6), staff requests (REQ-COS-2), assistant summaries (REQ-ASSIST-3) and name addressing (REQ-MSG-2). docs/acceptance/314.md is the run Jason does in the Stack once the rows are live. Co-Authored-By: Claude Opus 5.5 --- docs/acceptance/314.md | 146 +++++++++++++++++++++++++ docs/prd/mosaic-stack.md | 230 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 372 insertions(+), 4 deletions(-) create mode 100644 docs/acceptance/314.md diff --git a/docs/acceptance/314.md b/docs/acceptance/314.md new file mode 100644 index 000000000..f4b710ebd --- /dev/null +++ b/docs/acceptance/314.md @@ -0,0 +1,146 @@ +# Acceptance run for task 314 (Q167) + +Jason runs this inside the Stack once rows 135 to 143 and 147 to 149 are +live. It checks PRD version 1.5: one need goes from his spec to a landed +commit, and only hard waits reach his inbox. + +`` is the business the bus host runs. `` is the +project the need belongs to, `stack` for this run. Every command runs on +the host, as Jason. + +The need is a `mosaic version` command that prints the release and the +bus schema. + +## Before the run + +- `mosaic bus status` says the host is live. +- `mosaic inbox` shows no open decision. If one is open, resolve or + supersede it first, so step 6 starts from an empty inbox. + +## Steps + +1. Create the project repository, if it doesn't exist yet: + + ``` + mosaic project init + mosaic project check + ``` + + Pass: `check` reports the layout valid. The first commit's author is + Jason. (REQ-PROJ-1) + +2. Open the spec in the Console editor and write it: + + > North star: anyone can tell what is running in one command. + > Need: a `mosaic version` command that prints the release and the bus + > schema. + + Save. Pass: the save makes one local commit with Jason as author, and + the editor shows the new commit. Open the file again at the old commit, + edit it and save: the save is refused and writes nothing. (REQ-PROJ-2, + REQ-PROJ-3) + +3. Tell the assistant about the need: + + ``` + mosaic talk assistant "New need: the mosaic version command in spec/north-star.md. Start it." + ``` + + Pass: `talk` prints only the assistant's reply to this message. + +4. Watch the work start: + + ``` + mosaic tasks + mosaic agents + mosaic trail + ``` + + Pass, all on the trail: + - pm makes the tasks and sends the chief of staff a staff request + naming the roles and counts (REQ-COS-2); + - the chief of staff launches a coder, a reviewer and a + security-reviewer through role.launch (REQ-ROLE-5); + - the coder pushes a work ref, and the reviewer and the + security-reviewer each approve it. + +5. Watch it land: + + ``` + mosaic trail + git -C log --oneline -3 main + ``` + + Pass: + - pm hands the approved candidate to merge-gate, and merge-gate + raises the `git.merge.protected` decision citing + `spec/north-star.md` at the commit from step 2; + - the CTO resolves it, not Jason (REQ-DEC-2); + - merge-gate lands it, the trail records the allowed action with the + landed commit, and the commit is on the working repository's `main` + (REQ-LAND-1). + +6. Check the inbox, then ask for one hard wait on purpose: + + ``` + mosaic inbox + mosaic talk assistant "Open a new account for the project on an outside service." + mosaic inbox + ``` + + Pass: the first `inbox` is empty, so nothing from steps 3 to 5 reached + Jason. After the request, the inbox holds one decision for + `account.create`. Resolve it with the reject option. (REQ-WAIT-1) + +7. Restart the host halfway through the next merge. Use a second small + change, for example "print the help when an option is unknown", and + restart once the CTO has resolved its merge decision and before + merge-gate lands it. Mos or Jason runs the restart: + + ``` + mosaic bus stop + mosaic bus start --pm + ``` + + Pass: the merge lands from a new run of the same merge-gate instance + with the approval from before the restart, and no new decision is + raised. + (REQ-DEC-5) + +8. Change the spec in the Console editor: also print the commit. Save. + + Pass: + - the save makes a new commit by Jason; + - `mosaic trail` shows no decision settled under the step 2 commit + reopened (REQ-DEC-6); + - new raises cite the new commit, and a raise citing the step 2 + commit is refused `stale-spec`; + - pm and the CTO each answer the spec commit with an accept + (REQ-PROJ-4). + +9. Change the spec in a way that breaks a settled decision, for example: + "the version command prints nothing and exits." Save. + + Pass: pm or the CTO answers with a BLOCK naming the conflict, the + commit stays, and the assistant tells Jason about the block in its own + words. The assistant's message doesn't quote the chief of staff's text. + (REQ-PROJ-4, REQ-ASSIST-3) Then revert the spec in the editor with a + new commit. + +10. Give the coder instance a name with the CLI name command from row 141, + then send it a message by that name: + + ``` + mosaic agents + mosaic talk "Reply with your role name." + ``` + + Pass: the reply comes from the instance with that name, and the trail + records both the name and the instance. (REQ-MSG-2) + +## Result + +The run passes when every step passes. Record the run with the date, the +release, the bus schema and the result of each step in Vikunja task 314. +A failed step names the requirement it checks, so the fix goes back to +that row. diff --git a/docs/prd/mosaic-stack.md b/docs/prd/mosaic-stack.md index bff092b56..61a4ae0b4 100644 --- a/docs/prd/mosaic-stack.md +++ b/docs/prd/mosaic-stack.md @@ -1,6 +1,6 @@ # PRD: Mosaic Stack -- Status: approved, version 1.4. Jason approved draft 0.4 unchanged as +- Status: approved, version 1.5. Jason approved draft 0.4 unchanged as 1.0 on 2026-10-05 (lead decision 61). They approved version 1.1, the Organization requirements, in decision 03130d08-ddce-480d-a601-e59f64744fc3 on 2026-10-14. They approved version 1.2, the chief of staff, the @@ -10,8 +10,45 @@ decision 143). Mos reviewed the 1.3 text before it landed. Version 1.4 adds REQ-WEB-3 and REQ-INST-1, approved by Jason in decisions 021af0c8 (prd.approve, yes; request dfebf8ce) and 1ea053cc (prd.approve, - yes; request b28979c9). It is never edited in place. Changes are a new + yes; request b28979c9). Version 1.5 records Jason's Q167 ruling and + his added Q167 text, relayed by Mos on 2026-10-15. Under Q167 Jason's + confirmation of the text is the approval, so there is no in-Stack + prd.approve for it. It is never edited in place. Changes are a new version. +- Version 1.5 source, Jason's words relayed by Mos on 2026-10-15: + - Q167: "Me having to approve every decision within the Stack is not + working for me. I gave a directive, I want it to be done." and "Use + the T3 seats to make these updates and changes, so I can have a + functional system." + - Q167, added text: "All north star specs should be visible and + modifiable by the user within each given Project. I need to be able + to read and make the changes ad-hoc without an agent when desired. + This will allow review and revise to occur outside the chat. The + agent will be able to see the changes of course. Changes made should + use git (at least locally) to maintain the change history. + Organization of data in a Project is critical. We need a data + structure with json files and templates for everything. Markdown + files with a WYSIWYG editor for the north star/spec files. + Documentation within the project. Consistent storage of docs, reqs, + decisions, etc. should be kept in the project for reference as + needed. We will need to have these agents for a coding workflow: - + coder - code review - security review - merge gate. The appropriate + agent profile will be assigned to the agents. The roles and tools + allow agentic control of the needed workflow steps. Autonomy within + the rails is encouraged. Agents are proactive. The rest of your + reading is accurate." + - On the revised row list (task 314, comment 225): "Your decisions look + good. Proceed." + - Jason's waits list, as Mos gave it from Jason's AGENTS.md: spending + money, deleting data, anything irreversible, new internet exposure, + new external accounts, messages to people outside the fleet, and + force-push or history rewrite. Mos's reading, Q5: Q167 covers + shrinking the always-gated list to that list. Any change to the list + itself, and any grant of a listed action to a role, also goes to + Jason. + - Mos's reading, Q4: agents land into the business working + repository's protected branch through the host. This repository's + canonical `refactor` branch stays the lead's landing. - Version 1.3 source, Jason's words relayed by Mos: - Q153: "2. agreed. Make it modular though. We should be able to extend without code change on the core app." Mos's reading, which @@ -158,6 +195,28 @@ parent requirement is refused. assistant's name is set in the organization file. Jason's may be named Mos. +Added in version 1.5 (Q167): + +- **REQ-ROLE-5.** The coding workflow has four roles, each with its own + role file: + - coder, which writes the change; + - reviewer, which gives the code review verdict; + - security-reviewer, which reviews a candidate for security only and + approves or blocks with the reason. It has read-only tools and the + verdict, and no shell, no write tools and no push; + - merge-gate, which takes a candidate the reviewers approved, raises + the merge decision for it in the technical domain, so the CTO + decides, and lands it once the decision is resolved (REQ-LAND-1). Otherwise it reports the refusal. It holds the + merge and the land operation and no other grant, and it has no write + tools. Because an approval is consumed only by the instance that + raised it (REQ-DEC-5), the role that lands is the role that raises. + + Instances of these roles are added through the chief of staff's + organization change verb (REQ-ROLE-3). +- **REQ-ROLE-6.** Agents are proactive. Every role contract says: within + your grants, act on what you see without waiting to be asked, and + raise a decision or send a message for anything outside them. + Added in version 1.2: - **REQ-COS-1.** The chief of staff runs the organization. It hires and @@ -166,6 +225,10 @@ Added in version 1.2: from the assistant and assigns it through the roles that do it. It never talks to the user. Gated decisions still reach the human through the inbox (REQ-DEC-2, REQ-DEC-4). +- **REQ-COS-2.** The PM asks the chief of staff for staff. A staff request + names the roles and how many of each. The chief of staff launches them + through role.launch, within the agent limits (REQ-LIMIT-1). (Version + 1.5.) - **REQ-ASSIST-1.** The assistant is the user's main agent. Each user has one assistant role per organization. It talks with the user, and it passes work for the organization to the chief of staff. It doesn't @@ -176,6 +239,9 @@ Added in version 1.2: chief of staff; - only the user and the chief of staff may send to the assistant; - every refused send is logged with its reason. +- **REQ-ASSIST-3.** The assistant tells the user what other roles sent it + in its own words. It summarizes and doesn't relay their text. (Version + 1.5.) ### Variables @@ -217,10 +283,21 @@ Added in version 1.2: - its timestamps. A correction is a new row. -- **REQ-DEC-2.** Routing follows the decision's class: +- **REQ-DEC-2.** Routing follows the decision's class and whether it + cites the project's spec (REQ-PROJ-2). Version 1.5 replaces the 1.0 + text, which sent every gated decision to the human: - routine and within-role decisions are logged; - cross-role decisions go to the business's arbiter for that domain; - - gated decisions go to the human. + - a gated decision whose raise cites the project's current spec commit + goes to the business's arbiter for its domain, technical or delivery, + and not to the human; + - a gated decision with no spec citation goes to the human; + - a hard wait (REQ-WAIT-1) goes to the human whether or not it cites + the spec. + + A raise that cites a spec commit other than the current one is + refused, and so is a raise citing a spec whose last commit isn't the + human's. - **REQ-DEC-3.** A human resolution, by an authorized human, comes only from a `mosaic` CLI session started outside any agent run. Agents reach the decision store only through a broker. The broker stamps role and run from the launch record. @@ -229,6 +306,48 @@ Added in version 1.2: connector (#1509). Everything else goes into one daily digest at 08:00 Central. (Round 2, answers 2A and 3A; round 3, 4A and 5A.) +Added in version 1.5 (Q167): + +- **REQ-DEC-5.** An approval outlives the run that raised it. It binds to + the decision and to the role instance that raised it. A later run of + the same instance may consume it once. The first consuming action is + recorded, a second consume is refused, and another instance can't + consume it. Superseding a decision follows the same rule. +- **REQ-DEC-6.** A new spec commit never reopens a settled decision. Each + decision records the spec path and commit its raise cited. A decision + settled under one commit stays settled when a later commit lands, and + new raises cite the new commit. + +### Hard waits + +Added in version 1.5 (Q167). + +- **REQ-WAIT-1.** These are the hard waits. Each always goes to the + human, and each maps to actions in the closed vocabulary: + + | Jason's wait | Actions | + | --- | --- | + | Spending money | `spend` | + | Deleting data | `data.delete`, new in 1.5 | + | Anything irreversible | `data.delete`, `git.push.protected` and REQ-WAIT-3 | + | New internet exposure | `network.expose`, new in 1.5: a listener, port, tunnel, DNS record or proxy route reachable from outside the host. `deploy` stays a hard wait too. | + | New external accounts | `account.create`, new in 1.5, and `credential.mint` | + | Messages to people outside the fleet | `message.external` | + | Force-push or history rewrite | `git.push.protected`, which covers a push to a protected branch and any force push or history rewrite on any branch | + + The always-gated lists in the broker and the business vocabulary hold + exactly these actions. `git.merge.protected`, `policy.change`, + `prd.approve` and `role.revoke` leave those lists and route by + REQ-DEC-2. REQ-ROLE-2 still requires a resolved decision for a revoke. +- **REQ-WAIT-2.** No role file may grant a hard-wait action, at any + class, and the validator refuses a file that does. A change to the + hard-waits list, or a grant of a hard-wait action to a role, is itself + a hard wait. The list changes only by a reviewed commit to the + vocabulary, under a new PRD version that Jason approves. +- **REQ-WAIT-3.** An action added to the vocabulary is a hard wait until a + PRD version says it isn't. The reviewed commit that adds it names which + it is. + ### Messages - **REQ-MSG-1.** Messages are addressed to a role. They are append-only @@ -237,6 +356,13 @@ Added in version 1.2: the assistant sends work to the chief of staff, the reply comes back to the same thread. T3 and Discord carry messages; the address is still the role. +- **REQ-MSG-2.** Messages can also be addressed by agent name. A role + instance may have a name, unique in its business, that equals no + instance key and no role name. A send takes a name or a role. A name + resolves to its instance, the message records both, and a role still + delivers as REQ-MSG-1 says. The human sets names through the CLI. The + chief of staff sets them once its role file grants that within-role. + (Version 1.5.) ### Tasks @@ -257,6 +383,65 @@ Added in version 1.2: - **REQ-TASK-4.** The queue keeps the agents' lock, review rounds and audit log. No field syncs in both directions. +### Projects + +Added in version 1.5 (Q167). + +- **REQ-PROJ-1.** Each project keeps its records in its own local git + repository, separate from its code checkout, with no remote. The + layout is fixed and versioned: `project.json`, `spec/north-star.md`, + `docs/`, `requirements/` and `decisions/` with one JSON file per + record, and `templates/` with a template for each kind. Each JSON kind + has a schema, and a record that fails it is refused. `mosaic project + init` creates the repository with its first commit as the business's + human. +- **REQ-PROJ-2.** The north-star spec is `spec/north-star.md` in the + project repository. Only the human commits to it. Agents read it and + never write it. The spec counts only when its last commit's author is + the business's human. Agents write docs, requirements and decisions as + agent-authored commits, through the layout's validators. +- **REQ-PROJ-3.** The Console has an editor for the spec and the files + under `docs/`. The user opens a file at its current commit, edits it as + formatted Markdown, and saves it as one local commit with the human as + author. A save made from a commit older than the file's last commit is + refused and writes nothing. Rendering runs no script from the file. + The editor library is vendored and pinned with a permissive license + and a recorded hash for each file, loads nothing at runtime, and needs + no change to the Console's content security policy. +- **REQ-PROJ-4.** Agents review the human's spec commits. Each human + commit to the spec sends one notice to the PM and the CTO. They check + the change against settled decisions and work in flight, and each + answers with an accept or a BLOCK that names the conflict. A BLOCK + doesn't revert the commit. It goes to the assistant through the chief + of staff (REQ-ASSIST-2), and the assistant tells the user (REQ-ASSIST-3). + +### Landing + +Added in version 1.5 (Q167, Mos's reading Q4). + +- **REQ-LAND-1.** Agents land approved merges into the business working + repository. The run that holds an approved `git.merge.protected` + decision asks the host to land the work ref the decision names into + the working repository's `main`. The host runs the landing checks and + the project's gate: + - the decision is resolved with the approval option; + - the ref is at the reviewed commit, and a verdict approves it; + - the decision isn't superseded; + - the base hasn't moved. + + A refusal is logged on the task's trail with its code, and a project + with no gate is refused. A landing is recorded as the allowed action + with the landed commit, and it consumes the decision (REQ-DEC-5). This + repository's canonical branch is never a target. + + Only a role whose role file grants `git.merge.protected` as a + cross-role action can land. A merge decision raised by a role without + that grant is gated, and its approval never lands, whether the arbiter + or the human gave it. So an arbiter's judgment can't move landing to a + role REQ-ROLE-5 didn't give it. The land operation refuses a gated + decision; the check ships with whichever of rows 137 and 139 lands + second. + ### Interface - **REQ-CLI-1.** `mosaic` is the front door. From it Jason can: @@ -486,6 +671,10 @@ itself from them, five pieces in a row. For each piece: (Round 1, answer A; the assistant and threads from version 1.2.) +Version 1.5 adds Jason's Q167 acceptance run, `docs/acceptance/314.md`. +It passes when one need goes from Jason's spec to a landed commit with +only hard waits in his inbox. + ## Technical considerations - Vikunja v2.7.0 is AGPL-3.0. Its API tokens can't create users or mint @@ -623,6 +812,39 @@ itself from them, five pieces in a row. For each piece: the requirement only. - REQ-WEB-2 is held for the Console decide buttons amendment (vikunja:19/266), so its id is not reused here. +- Version 1.5: + - The 1.0 text of REQ-DEC-2 was: "Routing follows the decision's + class: routine and within-role decisions are logged; cross-role + decisions go to the business's arbiter for that domain; gated + decisions go to the human." On 2026-10-15 the Stack routed 16 + decisions, and all 16 went to Jason. 9 of them were `policy.change` + or `prd.approve`, which no role file could grant. + - Before 1.5 the always-gated lists, `GATED` in + `packages/bus/src/broker.mjs` and `GATED_ONLY` in + `packages/business/src/vocabulary.mjs`, held nine actions: + `credential.mint`, `git.merge.protected`, `git.push.protected`, + `deploy`, `spend`, `message.external`, `policy.change`, + `prd.approve` and `role.revoke`. Row 139 (#1633) changes them to + REQ-WAIT-1's list and adds `data.delete`, `network.expose` and + `account.create`. + - The arbiters are the organization file's `arbiters.technical` and + `arbiters.delivery` (`packages/bus/src/broker.mjs`). + - Where each requirement is built, all under Vikunja P19 task 314: + REQ-DEC-5 is row 136 (#1630); REQ-PROJ-1 is row 147 (#1641); + REQ-PROJ-2 and REQ-DEC-6 are row 138 (#1632); REQ-COS-2 is row 140 + (#1634). Those are landed. REQ-LAND-1 is row 137 (#1631); + REQ-DEC-2 and REQ-WAIT-1 to REQ-WAIT-3 are row 139 (#1633); + REQ-MSG-2 is row 141 (#1635); REQ-PROJ-4 and REQ-ASSIST-3 are row 143 + (#1637); REQ-PROJ-3 is row 148 (#1642); REQ-ROLE-5 and REQ-ROLE-6 + are row 149. This amendment adds the requirements only. + - The spec counts as confirmed when its last commit's author name is + the business's `human` (`packages/project/src/read.mjs`). The broker + refuses a raise that cites another commit with `stale-spec`, and an + unconfirmed spec with `spec-unconfirmed`. Until `mosaic project + init` runs for a project, spec reads and record writes for it are + refused. + - `git.push.protected` covering force pushes on any branch is new in + 1.5. Row 139 builds it. ## Risks and open questions -- 2.55.0