docs: Q167 rows after comment 225, the editor (148), the workflow roles (149) and rescoped 135, 137, 138, 139, 141 and 143 (vikunja:19/314)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
jason.woltjeandClaude Opus 5.5 committed 2026-10-15 18:00:38 -05:00
1 parent 81e59d25c7
commit d5a9bf4c3b
1 file changed
+511
+511
View File
@@ -0,0 +1,511 @@
# Q167, rows after comment 225: the editor, the workflow roles, rescoped rows (2026-10-15)
Status: written by Sage, lead, for Vikunja P19 task 314. It follows
`docs/plans/BRIEF-TEMPLATE.md`, one `##` heading per row. The preamble of
`docs/plans/2026-10-15_q167-north-star-rows.md` applies here too: the hard
waits, the suites, the mutant rule and the schema-window rule.
Comment 225 on task 314 is the revised row list, after Jason's added Q167
text (quoted in `docs/plans/2026-10-15_q167-rows-r2.md`). Jason answered
"Your decisions look good. Proceed." Rows 146 and 147 are in r2. This file
holds the two new rows, 148 and 149, and a new section for each row that
comment 225 rescoped: 135, 137, 138, 139, 141 and 143. A rescoped row is
re-pinned to its section here, and its section in the first brief no longer
governs it. Rows 136, 140 and 142 are unchanged.
Rulings that bind these rows:
- Each project has a separate local git repository, laid out by row 147.
- Agents read `spec/north-star.md` and never commit to it. Only the human
commits to the spec.
- Agents write docs, requirements and decisions as agent-authored commits
through row 147's validators.
- The editor's library: one vendored, pinned library with a permissive
license, recorded; its sha256 in the repository; no runtime fetch; served
from `public/` under the Console's existing CSP with no loosening; a
security review by Filbert and Dewey until row 149's security-reviewer
role exists. Decision 123 applies to every `public/` change.
Order: 146, then 147, then 138 and 148.
## A Console editor for the project's spec and docs
Row 148.
### Problem
Jason wants to read and change a project's north-star spec and docs
without an agent, in a WYSIWYG markdown editor, with git history. Row 147
gives each project a local git repository, but the only ways to change it
are an editor on the host and `git commit` by hand.
### Owner and reviewer
- Owner: Researcher.
- Reviewers: Filbert and Dewey. Dewey's review is the security review
until row 149's security-reviewer role exists.
### Files owned
- `packages/webui/src/public/`: the editor view, and the vendored library
under `public/vendor/<library>-<version>/` with its LICENSE file
- `packages/webui/src/serve.mjs`: one read route and one save route
- `packages/webui/src/bus.mjs` and `packages/webui/src/reads.mjs`: the
calls to the human transport
- `packages/bus/src/broker.mjs` and `packages/bus/src/human-cli.mjs`: the
human-only read and save verbs
- `packages/project/`: a human writer beside row 147's agent writer, if
147's API doesn't already take a human author
- tests in each package, the webui browser tests, READMEs and
`docs/TOOLS.md`
### What ships
- Library choice first. Before any `public/` change, Researcher picks one
library and sends Sage its name, version, license, size in bytes and
the sha256 of each vendored file. Sage puts them in this section and
re-pins the row, and Mos gives the decision 123 go on them. The library
must run under `script-src 'self'` with no eval and no `new Function`,
load nothing at runtime, and need no CSP change. If no library meets
that, the editor is a textarea with a rendered preview, built from code
in the repository, and the brief says so.
- `vendor.sha256` in the vendor directory lists each vendored file. A test
checks the files against it, so a changed vendored file fails the suite.
- Reading. The Console lists `spec/north-star.md` and the files under
`docs/` for a project, and opens one with its current commit. The read
goes through the human transport like the Console's other reads.
- Saving. A save is one human-only bus verb through the human-cli proof.
It follows the Settings write at `serve.mjs:233`: the signed-in user,
the exact Origin, same-origin Fetch Metadata, JSON, strict keys and a
size limit. The size limit is row 147's 1 MiB file bound, on this route
only; the 16 KiB message limit stays. The bus writes the file and makes
one local commit with the business's human as author. Only
`spec/north-star.md` and `docs/*.md` are writable. Requirements and
decisions stay with row 147's writer and its schemas.
- A stale base refuses. Each save carries the commit the editor opened. If
the file's last commit is newer, the save refuses `stale-base`, writes
nothing, and the Console tells the user to reload.
- Rendering runs no script. Raw HTML in markdown is shown as text. Links
with a `javascript:` or `data:` scheme are not rendered as links. The
CSP already blocks external images.
- Tests: a save makes one commit with the human author and the right
content; an agent capability refuses the save verb; a stale base refuses
and writes nothing; a path outside the two allowed refuses; each
boundary check refuses as the Settings tests do; a browser test that a
`<script>`, an `onerror` attribute and a `javascript:` link in the
markdown run nothing; the vendor hash test.
### Out of scope
Agents writing the spec. Requirements and decision editing. Any remote or
push for the project repository. Any CSP change: if the work needs one, the
row stops and tells Sage.
### Gate
Filbert and Dewey approve on the row's issue naming the candidate manifest;
Mos's decision 123 go on the `public/` diff and the vendored files; the
webui, bus, cli and project suites and every `scripts/test-*.sh` green.
Needs row 147 done.
## Security-reviewer and merge-gate roles, and proactive contracts
Row 149.
### Problem
Jason named four agents for the coding workflow: coder, code review,
security review and merge gate. The Stack has coder and reviewer. No role
does a security review, and no role holds landing alone. Jason also said
agents are proactive, and no role contract says so.
### Owner and reviewer
- Owner: Dewey.
- Reviewer: Filbert.
### Files owned
- `roles/security-reviewer.json` and `roles/security-reviewer.md`, new
- `roles/merge-gate.json` and `roles/merge-gate.md`, new
- every `roles/*.md`, one proactive line each
- `packages/business/` where definitions are known or validated, if a new
definition must be declared there
- tests and READMEs
### What ships
- coder and reviewer stay as they are.
- security-reviewer: read-only tools (read, grep, find, ls) and the
verdict. No bash, no write, no edit, no git push, no credentials beyond
what a verdict needs. If the bus requires message.send to deliver a
verdict, it gets that too, and BUILD.md says why. Its contract: review a
candidate for security only, and approve or block with the reason.
- merge-gate: holds only row 137's land op, with no other grant and no
write tools. Its contract: land an approved merge when the decision,
the verdicts and the gate all pass, and otherwise report the refusal.
- Every role contract gets one line: 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.
- Instances of the new roles are added through chief's organization
change verb (row 132), never by editing Jason's business file. Adding
them to the mosaic-stack business is a live step after the re-pin, with
Mos's go. It is not part of the row.
- Tests: both role files load and validate; security-reviewer's tool list
has no write or shell tool; merge-gate's only grant is the land op; a
contract test that finds the proactive line in every `roles/*.md`.
### Out of scope
The land op itself (row 137). GATED_ONLY and routing (row 139). Adding
instances to any business.
### Gate
Filbert approves on the row's issue naming the candidate manifest; the
business, bus and harness suites and every `scripts/test-*.sh` green. Needs
rows 137 and 139 done, because merge-gate's grant needs the land op and
git.merge.protected out of GATED_ONLY.
## PRD 1.5 under Q167: specs as files, agent decisions, workflow roles and hard waits
Row 135, rescoped.
### Problem
The PRD routes every gated decision to the human (REQ-DEC-2), and
GATED_ONLY in `packages/business/src/vocabulary.mjs` holds policy.change,
prd.approve and git.merge.protected, so no role file can grant them. The
PRD has no requirement for a project's layout, for a north-star spec kept
as a file the human edits, for agent landing, for name addressing, for the
four workflow roles, or for agents reviewing Jason's spec changes.
### Owner and reviewer
- Owner: Sage. Q167 makes Jason's confirmation the approval, so there is
no in-Stack prd.approve for this version.
- Reviewer: Filbert.
### Files owned
- `docs/prd/mosaic-stack.md`, as a new version 1.5 with a source block
quoting Jason's Q167 text and his added text. It is never edited in
place.
- `docs/acceptance/314.md`, the acceptance script Jason runs.
### What ships
- REQ-DEC-2 replaced: a decision that cites the project's current spec
commit goes to the arbiter for its domain. Only a decision with no spec
citation, or a hard wait, goes to Jason.
- A hard-waits requirement naming the list in the preamble, with the
action each maps to, including new ones for deleting data, new internet
exposure and new external accounts. git.push.protected covers
force-push and history rewrite.
- Requirements for: the project layout in a local git repository (row
147); the north-star spec as `spec/north-star.md`, committed only by the
human; the Console editor (row 148); a new spec commit never reopening a
settled decision; approvals that outlive the run; agent landing into the
business working repository; pm asking chief for staff; messages
addressed by agent name; the four workflow roles, coder, reviewer,
security-reviewer and merge-gate; proactive role contracts; agents
reviewing Jason's spec commits; the assistant summarizing instead of
relaying.
- The acceptance script, as sent to Mos in sage-0376 and corrected in
sage-0377, updated for the editor and the file-based spec.
### Out of scope
Code. Every behaviour change is in rows 136 to 149.
### Gate
Filbert approves on the row's issue naming the candidate manifest. The row
lands after 297's PRD 1.4, which is in.
## Agents land approved merges into the business working repository
Row 137, rescoped.
### Problem
No role can land a merge. git.merge.protected is in GATED
(`packages/bus/src/broker.mjs`) and GATED_ONLY, and land-work
(`scripts/land-work.sh`, row 116) runs only from a conductor checkout into
canonical `refactor`. The host's git socket
(`packages/cli/src/git-socket.mjs`) already carries push and fetch for
coder and reviewer runs, checked by the broker. The working repository's
`main` is reseeded from the project root, so a landing on `main` would not
survive a reseed.
### Owner and reviewer
- Owner: Darkwing.
- Reviewers: Filbert and Dewey.
### Files owned
- `packages/cli/src/git-socket.mjs` and the host code it calls, including
the seed
- a shared module for land-work's checks and gate, moved out of
`scripts/land-work/` only as far as both callers need
- `packages/bus/src/broker.mjs`, the authority check for the new op only
- tests in `packages/cli/tests/`, `packages/bus/tests/` and
`scripts/test-*.sh` for the above
- docs/TOOLS.md and package READMEs, the paragraphs on landing
### What ships
- The seed writes the project root's HEAD to `refs/heads/root`, forced.
`main` is created once. After that it moves only by a landing, or by a
fast-forward to `root` when `main` is an ancestor of `root`, and it is
never forced again.
- push's unrelated-history check compares against `main`.
- A `land` op on the host git socket. The run that holds an approved
git.merge.protected decision (row 136 lets a later run of the same
instance use it) asks the host to land the work ref the decision names
into `main`.
- The host runs the checks land-work runs today: the decision is resolved
with the approval option, the ref is at the reviewed commit, a verdict
approves it, it is not superseded, the base hasn't moved, and there is no
root file. Any refusal is an action.refused on the task's trail with
land-work's code.
- land-work's gate runs when the project root is a mosaic-stack checkout,
decided by an exact check that BUILD.md names. For any other project the
land refuses `gate-missing`. A project-declared gate is a later row.
- A landing is recorded as the action.allowed for git.merge.protected with
the landed commit, and consumes the decision.
- The sandbox binds the op only for a role that holds a resolved merge
decision, the same way push and fetch are bound today.
- `read.mjs` keeps its cli-resolved check. Row 139 relaxes it.
- Canonical `refactor` is never a target. land-work.sh keeps working for
Sage's landings.
- BUILD.md names the change to push and fetch behaviour that the seed
change causes.
- Tests: a reseed moves `root` and leaves a landed `main`; `main`
fast-forwards to `root` when it is an ancestor and stays put when it
isn't; push's unrelated-history check against `main`; a mosaic-stack
checkout runs the gate; another project refuses `gate-missing`; each
land-work refusal code.
### Out of scope
Routing and GATED_ONLY (row 139). The merge-gate role, which gets the land
op through row 149. Any push to a remote. Force-push or history rewrite
stays impossible.
### Gate
Filbert and Dewey approve on the row's issue naming the candidate manifest;
bus, cli and harness suites and every `scripts/test-*.sh` green. Needs row
136 done.
## The north-star spec is a file in the project repository
Row 138, rescoped.
### Problem
Decisions carry no reference to the spec that covered them, so nothing can
say a decision was settled under an earlier spec. Agents have no way to
read a project's spec, and row 147's record writer has no broker verb or
harness tool.
### Owner and reviewer
- Owner: Rocko.
- Reviewer: Dewey.
### Files owned
- `packages/bus/src/store.mjs`, the 3e to 3f step and its migration
- `packages/bus/src/broker.mjs`, the decision columns, the spec read verb
and the record-writer verb
- `packages/harness/`, the read tool and the record-writer tool
- `packages/business/src/vocabulary.mjs` and `roles/*.json`, only for the
record-writer action and its grants
- tests in each package, MIGRATION.md in the row's packet, package READMEs
### What ships
- The spec is `spec/north-star.md` in the project's repository (row 147).
A human-authored commit to it is the confirmation. There is no spec
table and no propose-and-confirm verb.
- decisions gain `spec_path` and `spec_commit`. A raise that cites the
spec records the spec file's current commit, and the bus refuses a
citation of any other commit.
- A new spec commit never reopens a settled decision. A decision settled
under one commit stays settled after the next.
- A read verb and harness tool give any role instance of the business the
spec file at a commit and its git log. Agents can't commit to it: row
147's writer refuses `spec/` for an agent author, and this row adds no
other write path.
- The record-writer broker verb and harness tool call row 147's writer for
docs, requirements and decisions, with the run's instance as author.
- Migration 3e to 3f preserves every existing row, tested on a copy of a
3e store, with the steps written for the window.
- Tests: a raise records the current spec commit; a stale citation
refuses; a settled decision stays settled after a new spec commit; the
read tool returns the file and log; an agent's write to `spec/` refuses
through every path; the record writer commits with the agent author.
### Out of scope
Routing on the spec (row 139). Any change to who may resolve a decision.
The Console editor (row 148).
### Gate
Dewey approves on the row's issue naming the candidate manifest; bus,
business, harness and cli suites and every `scripts/test-*.sh` green; the
migration tested on a 3e copy. Needs row 147 done. Lands in its own window
after 3e is live.
## Decisions that cite the spec go to an agent; only hard waits reach Jason
Row 139, rescoped.
### Problem
`classify` (`packages/business/src/resolve.mjs`) and `#classification`
(`packages/bus/src/broker.mjs`) make anything a role isn't granted
"gated", and decision.raise routes gated to the human. GATED_ONLY holds
policy.change and prd.approve, which caused 9 of the 16 decisions sent to
Jason on 2026-10-15.
### Owner and reviewer
- Owner: Dewey.
- Reviewer: Filbert.
### Files owned
- `packages/business/src/vocabulary.mjs`, GATED_ONLY and the new hard-wait
actions
- `packages/bus/src/broker.mjs`, GATED and decision.raise routing
- the `read.mjs` cli-resolved check that row 137 keeps
- `roles/*.json`, grants only as the PRD 1.5 text requires
- tests in the bus and business packages, and READMEs
### What ships
- GATED and GATED_ONLY become the hard-waits list from PRD 1.5 and nothing
else, with new actions for deleting data, new internet exposure and new
external accounts.
- A spec covers a decision when the raise cites the project's current spec
commit (row 138). A covered raise routes to the business's arbiter for
its domain, never to the human, unless the action is a hard wait.
- A hard wait always routes to the human, spec or no spec. A change to the
hard-waits list or a grant of a hard-wait action is itself a hard wait.
- The grant to set instance names (row 141). chief-of-staff gets it
within-role. Whichever of 139 and 141 lands second adds the grant, and
until then names are set only by the human through the CLI.
- Tests for each hard wait, for a spec-covered merge going to the arbiter,
for an uncited decision still going to the human, and for a stale spec
citation.
### Out of scope
The spec file and its citation (row 138). The landing mechanism (row 137).
### Gate
Filbert approves on the row's issue naming the candidate manifest; bus and
business suites and every `scripts/test-*.sh` green. Needs rows 135, 136
and 138 done.
## Messages are addressed by agent name
Row 141, rescoped.
### Problem
REQ-MSG-1 addresses a message to a role. Q166 and pm's in-Stack decision
623b1665 (resolved yes by Jason, 21:45:23Z) ask for agent names. Mos's
decision 28a5782d note: decision 109 notices go to the assistant until
messages can be addressed by agent.
### Owner and reviewer
- Owner: Darkwing.
- Reviewer: Filbert.
### Files owned
- `packages/bus/src/store.mjs`, the 3f to 3g step and its migration
- `packages/bus/src/broker.mjs`, message.send and the name writer
- `packages/cli/src/cli.mjs` and the harness tool for message.send
- tests and READMEs
### What ships
- A table `instance_names(business, instance, name)`, and `to_name` on
messages. `to_role` stays the instance key, so delivery and claims don't
change.
- A name is unique in its business and can't equal any instance key or any
role name.
- message.send takes a name or a role. A name resolves to its instance and
the message records both. A role still delivers as today.
- The writer is human-only, through the CLI, until the grant described in
row 139's section lands.
- Migration 3f to 3g preserves every row, tested on a copy of a 3f store.
- Tests: send by name delivers to the instance; a duplicate name, a name
equal to an instance key and a name equal to a role name each refuse; an
agent's name write refuses; the migration.
### Out of scope
Thread routing beyond what names need.
### Gate
Filbert approves on the row's issue naming the candidate manifest; touched
suites and every `scripts/test-*.sh` green; the migration tested on a 3f
copy. Lands in its own window after 3f is live.
## Agents review Jason's spec commits, and the assistant summarizes
Row 143, rescoped.
### Problem
Jason's spec changes go straight to work with no agent check against
settled decisions and work in flight, and the assistant relays chief's
text word for word: of 49 messages to the human on 2026-10-15, 24 came
from the assistant, mostly repeats.
### Owner and reviewer
- Owner: Researcher, after row 142.
- Reviewer: Dewey.
### Files owned
- `roles/assistant.md`, `roles/pm.md`, `roles/cto.md`, contract text
- `packages/bus/src/broker.mjs` and `packages/business/src/vocabulary.mjs`
for the notice and the BLOCK class, if needed
- tests and READMEs
### What ships
- When the human commits to `spec/north-star.md` through row 148's save
verb, the bus sends one notice to pm and cto naming the commit.
- pm and cto read the change through row 138's read tool and check it
against settled decisions and work in flight. Each answers with a BLOCK
naming the conflict, or an accept. A BLOCK doesn't revert the commit; it
goes to the assistant.
- The assistant tells Jason the result in its own words, and its contract
says to summarize chief's text and not repeat it.
- Tests: one notice per spec commit; no notice for an agent's record
commit; a BLOCK reaches the assistant; a contract text test.
### Out of scope
The spec file and its citation (row 138), routing (row 139) and the editor
(row 148).
### Gate
Dewey approves on the row's issue naming the candidate manifest; touched
suites and every `scripts/test-*.sh` green. Needs rows 138, 142 and 148
done.