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 <[email protected]>
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
# 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.
|
||||
|
||||
`<business>` is the business the bus host runs. `<project>` 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.
|
||||
- The organization has security-reviewer and merge-gate instances, added
|
||||
through the chief of staff's organization change with Mos's go, and
|
||||
both are in `launch.instances`.
|
||||
- `arbiters.technical` is `cto`, which step 5 assumes.
|
||||
|
||||
## Steps
|
||||
|
||||
1. Create the project repository, if it doesn't exist yet:
|
||||
|
||||
```
|
||||
mosaic project init <business> <project>
|
||||
mosaic project check <business> <project>
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
Before saving, open the same file in a second Console tab. Save in the
|
||||
first tab. Pass: the save makes one local commit with Jason as author,
|
||||
and the editor shows the new commit. Then edit and save in the second
|
||||
tab, which still holds the old commit: 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 <task>
|
||||
```
|
||||
|
||||
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 <decision>
|
||||
git -C <working repository> 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 <business> --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);
|
||||
- `mosaic trail` shows new raises citing the new commit, and no
|
||||
raise citing the step 2 commit accepted after the save;
|
||||
- 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 command row 141 adds
|
||||
(`docs/TOOLS.md` names it once that row lands), then send it a
|
||||
message by that name:
|
||||
|
||||
```
|
||||
mosaic agents
|
||||
mosaic talk <name from the agents list> "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.
|
||||
+240
-4
@@ -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: 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 GATED_ONLY and the
|
||||
role grants through rows 135 and 139." Sage's plan for the rows adds
|
||||
that 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,30 @@ 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. Its one grant is
|
||||
`git.merge.protected` as a cross-role action, which is what landing
|
||||
checks. Raising a decision needs no grant. It has no write tools.
|
||||
Because only the instance that raised an approval can consume 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 +227,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 +241,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 +285,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 +308,49 @@ 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 and thread that raised it. A
|
||||
later run of the same instance, on the same thread, 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 +359,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 +386,70 @@ 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
|
||||
Markdown files in `docs/`. The user opens a file at its current commit,
|
||||
edits its Markdown source beside a rendered preview, 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. The
|
||||
preview runs no script from the file and is built from code in this
|
||||
repository. A WYSIWYG editor may replace the source view only with a
|
||||
library that 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. No library passed
|
||||
that for 1.5.
|
||||
- **REQ-PROJ-4.** Agents review the human's spec commits. Each human
|
||||
commit to the spec saved through the Console editor (REQ-PROJ-3) sends
|
||||
one notice to the PM and the CTO. A commit the human makes with git
|
||||
outside the Console sends no notice yet. 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 +679,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 +820,45 @@ 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. Today the host refuses a non-fast-forward push to the working
|
||||
repository (`packages/seat/src/working.mjs`), so no role can force
|
||||
push. REQ-WAIT-1 makes any future path to one a hard wait.
|
||||
- REQ-PROJ-4 covers Console saves only (row 143). Noticing spec commits
|
||||
made with git outside the Console is a later row.
|
||||
- REQ-LAND-1's refusal of a gated merge decision is pinned in rows 137
|
||||
and 139. Row 139 carries it, or row 137 if 139 lands first.
|
||||
|
||||
## Risks and open questions
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ test('requirements returns the committed list to a holding role session, and no
|
||||
const pm = agent('pm');
|
||||
const list = call(b, pm, 'requirements');
|
||||
assert.deepEqual(list, loadRequirements());
|
||||
assert.equal(list.requirements.length, 43);
|
||||
assert.equal(list.requirements.length, 58);
|
||||
assert.deepEqual(call(b, agent('coder'), 'requirements'), list);
|
||||
assert.throws(() => call(b, human, 'requirements'), /agent-required/);
|
||||
assert.throws(() => call(b, reader, 'requirements'), /read-only/);
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
{
|
||||
"prd": "docs/prd/mosaic-stack.md",
|
||||
"version": "1.4",
|
||||
"version": "1.5",
|
||||
"requirements": [
|
||||
{ "id": "REQ-ROLE-1", "title": "Each role is a reviewed roles/<name>.json: contract, authority map, credentials" },
|
||||
{ "id": "REQ-ROLE-2", "title": "One holder per role instance, one per thread for the assistant; the chief of staff may end a run, others need a decision" },
|
||||
{ "id": "REQ-ROLE-3", "title": "The user and the chief of staff write the organization file; the chief of staff's writes go through a logged broker verb" },
|
||||
{ "id": "REQ-ROLE-4", "title": "The first organization is Mosaic Stack: chief of staff, assistant, PM, CTO, coder and reviewer" },
|
||||
{ "id": "REQ-ROLE-5", "title": "Q167 adds security-reviewer and merge-gate; merge-gate raises the merge in the technical domain and lands it" },
|
||||
{ "id": "REQ-ROLE-6", "title": "Agents are proactive: each role contract says to act within its grants without waiting to be asked" },
|
||||
{ "id": "REQ-COS-1", "title": "The chief of staff runs the organization: hires, terminates, launches; never talks to the user" },
|
||||
{ "id": "REQ-COS-2", "title": "The PM asks the chief of staff for staff; a staff request names the roles and how many of each" },
|
||||
{ "id": "REQ-ASSIST-1", "title": "The assistant is the user's main agent and passes organization work to the chief of staff" },
|
||||
{ "id": "REQ-ASSIST-2", "title": "The broker limits the assistant to the user and the chief of staff in both directions; refusals logged" },
|
||||
{ "id": "REQ-ASSIST-3", "title": "The assistant tells the user what other roles sent it in its own words and does not relay their text" },
|
||||
{ "id": "REQ-VAR-1", "title": "Variables in four layers, declared in code; limits intersect; unknown keys refused" },
|
||||
{ "id": "REQ-VAR-2", "title": "One system config, never auto-written; secrets only as references the broker reads" },
|
||||
{ "id": "REQ-CRED-1", "title": "Each role instance has its own Gitea and Vikunja token, held by the broker" },
|
||||
@@ -17,11 +21,22 @@
|
||||
{ "id": "REQ-DEC-2", "title": "Decisions route by class: logged, to the domain arbiter, or to the human" },
|
||||
{ "id": "REQ-DEC-3", "title": "Authorized-human resolutions come only from a mosaic CLI session outside any agent run" },
|
||||
{ "id": "REQ-DEC-4", "title": "A blocking gated decision reaches an authorized human at once; the rest go in a daily digest" },
|
||||
{ "id": "REQ-DEC-5", "title": "An approval outlives its run, binds to the decision, instance and thread, and is consumed once" },
|
||||
{ "id": "REQ-DEC-6", "title": "A spec commit never reopens a settled decision" },
|
||||
{ "id": "REQ-WAIT-1", "title": "Hard waits always go to the human: spend, delete, irreversible, exposure, accounts, external messages, protected push" },
|
||||
{ "id": "REQ-WAIT-2", "title": "No role file grants a hard wait; changing the list or granting a listed action is itself a hard wait" },
|
||||
{ "id": "REQ-WAIT-3", "title": "An action added to the vocabulary is a hard wait until a PRD version says it is not" },
|
||||
{ "id": "REQ-MSG-1", "title": "Messages are addressed to a role, append-only, delivered to the current holder; assistant messages name a thread" },
|
||||
{ "id": "REQ-MSG-2", "title": "Messages can be addressed by an instance name unique in its business; the message records the name and the instance" },
|
||||
{ "id": "REQ-TASK-1", "title": "Tasks live in Vikunja, each citing a requirement id; the verbs enforce field writers" },
|
||||
{ "id": "REQ-TASK-2", "title": "Polling is the source of truth: a 30-second board poll and an hourly reconcile" },
|
||||
{ "id": "REQ-TASK-3", "title": "The installer points at an existing Vikunja or deploys the unmodified upstream image" },
|
||||
{ "id": "REQ-TASK-4", "title": "The queue keeps the agents' lock, review rounds and audit log; no two-way sync" },
|
||||
{ "id": "REQ-PROJ-1", "title": "Each project keeps its records in its own local git repository, with no remote and a fixed, validated layout" },
|
||||
{ "id": "REQ-PROJ-2", "title": "Only the human commits the north-star spec; it counts only when its last commit is by the business human" },
|
||||
{ "id": "REQ-PROJ-3", "title": "The Console edits the spec and docs Markdown as source with a preview; a stale save is refused" },
|
||||
{ "id": "REQ-PROJ-4", "title": "Each human spec commit saved in the Console sends one notice to the PM and the CTO for review" },
|
||||
{ "id": "REQ-LAND-1", "title": "A resolved merge decision lands into the working repository main through the host, only for a granted role" },
|
||||
{ "id": "REQ-CLI-1", "title": "mosaic is the front door: talk to the assistant in a thread, the inbox, tasks, agents and trails" },
|
||||
{ "id": "REQ-CLI-2", "title": "The assistant session mosaic talks to is launched and owned by the stack, not T3" },
|
||||
{ "id": "REQ-WEB-1", "title": "The WebUI shows the CLI's data, a chat area of projects and threads, and Settings for agent limits" },
|
||||
|
||||
@@ -18,10 +18,10 @@ test("the list holds the PRD's requirement ids, in its order, at its version", (
|
||||
const ids = [...prd.matchAll(/^- \*\*(REQ-[A-Z]+-[0-9]+)\.\*\*/gm)].map((m) => m[1]);
|
||||
// Any other mention of a bold id would be a bullet this pattern missed.
|
||||
assert.equal(ids.length, [...prd.matchAll(/\*\*REQ-/g)].length);
|
||||
assert.equal(ids.length, 43);
|
||||
assert.equal(ids.length, 58);
|
||||
assert.deepEqual(list.requirements.map((r) => r.id), ids);
|
||||
assert.match(prd, new RegExp(`^- Status: approved, version ${list.version.replace('.', '\\.')}\\.`, 'm'));
|
||||
assert.deepEqual([list.prd, list.version], ['docs/prd/mosaic-stack.md', '1.4']);
|
||||
assert.deepEqual([list.prd, list.version], ['docs/prd/mosaic-stack.md', '1.5']);
|
||||
});
|
||||
|
||||
test('the committed list loads frozen', () => {
|
||||
@@ -74,7 +74,7 @@ test('the schema refuses any other shape', () => {
|
||||
const twice = raw();
|
||||
twice.requirements.push(structuredClone(twice.requirements[0]));
|
||||
writeFileSync(join(dir, 'twice.json'), JSON.stringify(twice));
|
||||
assert.throws(() => loadRequirements(join(dir, 'twice.json')), listError('requirements[43].id: REQ-ROLE-1 twice'));
|
||||
assert.throws(() => loadRequirements(join(dir, 'twice.json')), listError('requirements[58].id: REQ-ROLE-1 twice'));
|
||||
} finally {
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user