prd: version 1.4, REQ-WEB-3 and REQ-INST-1 (vikunja:19/297, row 144)
Jason-approved merge, landed unchanged: git diff 07c12b51b..b3dd8de83
from work/vikunja-19-297. Business reviewer verdict 0d4c1c68 approve on that
commit; Jason resolved merge decision 29ff6589 via the CLI. No commit on
refactor since 07c12b51b touches these paths.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -1,14 +1,17 @@
|
||||
# PRD: Mosaic Stack
|
||||
|
||||
- Status: approved, version 1.3. Jason approved draft 0.4 unchanged as
|
||||
- Status: approved, version 1.4. 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
|
||||
assistant, threads and agent limits, through Mos on 2026-10-14 (lead
|
||||
decisions 141 and 142). Version 1.3 records their rulings on plug-ins
|
||||
and token counting, Q153 to Q155, relayed by Mos on 2026-10-14 (lead
|
||||
decision 143). Mos reviewed the 1.3 text before it landed. It is never
|
||||
edited in place. Changes are a new version.
|
||||
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
|
||||
version.
|
||||
- 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
|
||||
@@ -272,6 +275,10 @@ Added in version 1.2:
|
||||
view shows every agent limit, the usage counted against each, and the
|
||||
model each role instance runs, and lets the user change them
|
||||
(REQ-LIMIT-1 to REQ-LIMIT-3).
|
||||
- **REQ-WEB-3.** The Console has controls to restart the bus and to
|
||||
reload the organization file. Each control is a gated, trailed action.
|
||||
A reload applies `launch.instances` changes to running sessions without
|
||||
a manual `systemctl restart`. (Version 1.4, decision 021af0c8.)
|
||||
|
||||
### Launching
|
||||
|
||||
@@ -460,6 +467,15 @@ Added in version 1.1 (decision 03130d08).
|
||||
types.
|
||||
- **REQ-FED-1.** Installs can federate with each other. This is post-v1.
|
||||
|
||||
### Installer
|
||||
|
||||
Added in version 1.4 (decision 1ea053cc).
|
||||
|
||||
- **REQ-INST-1.** The installer offers optional components. Each one is
|
||||
pinned, health-checked and removable, and is switched on in the
|
||||
organization file or system config. The first is SearXNG: JSON output
|
||||
enabled, limiter off, bound to loopback only.
|
||||
|
||||
## Acceptance criteria and success measures
|
||||
|
||||
v1 is done when Jason gives one-sentence requests to the assistant, in a
|
||||
@@ -589,6 +605,24 @@ itself from them, five pieces in a row. For each piece:
|
||||
- Channels: the human channel is `via: 'cli'` in the broker, the
|
||||
WebUI reaches the bus by running the human CLI, and Discord isn't
|
||||
connected to the bus.
|
||||
- Version 1.4:
|
||||
- Jason approved REQ-WEB-3 in decision 021af0c8 (prd.approve, choice
|
||||
yes; the approval message was request 2e031716, from request
|
||||
dfebf8ce). The requirement is the approved sentence, set as three
|
||||
sentences with the same clauses.
|
||||
- Jason approved REQ-INST-1 in decision 1ea053cc (prd.approve, choice
|
||||
yes; the approval message was request 94a11a59, from request
|
||||
b28979c9, Q162). The text is as approved. The build task under it is
|
||||
the SearXNG install component, which backs the `searxng-bundled`
|
||||
web source (`web.source`, vikunja:19/296). This amendment adds the
|
||||
requirement only.
|
||||
- Today a change to `launch.instances` reaches running sessions only
|
||||
after the bus service is restarted by hand. The build tasks under
|
||||
REQ-WEB-3 are the bus hot reload, the Console controls, and running
|
||||
sessions picking up `launch.instances` changes. This amendment adds
|
||||
the requirement only.
|
||||
- REQ-WEB-2 is held for the Console decide buttons amendment
|
||||
(vikunja:19/266), so its id is not reused here.
|
||||
|
||||
## 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, 41);
|
||||
assert.equal(list.requirements.length, 43);
|
||||
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,6 +1,6 @@
|
||||
{
|
||||
"prd": "docs/prd/mosaic-stack.md",
|
||||
"version": "1.3",
|
||||
"version": "1.4",
|
||||
"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" },
|
||||
@@ -25,6 +25,7 @@
|
||||
{ "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" },
|
||||
{ "id": "REQ-WEB-3", "title": "The Console restarts the bus and reloads the organization file, gated and trailed; reload applies launch.instances live" },
|
||||
{ "id": "REQ-LAUNCH-1", "title": "The chief of staff launches role sessions within the agent limits, logged and revocable; threads start on demand" },
|
||||
{ "id": "REQ-LIMIT-1", "title": "Agent limits have no code ceiling and are set from WebUI Settings and mosaic: total, per provider, per model" },
|
||||
{ "id": "REQ-LIMIT-2", "title": "A daily quota per OAuth account or CLIProxyAPI client key, counting only the stack's own use" },
|
||||
@@ -42,6 +43,7 @@
|
||||
{ "id": "REQ-THREAD-1", "title": "Threads live under projects" },
|
||||
{ "id": "REQ-THREAD-2", "title": "The user creates projects and named threads; each thread is its own assistant session with kept history" },
|
||||
{ "id": "REQ-TPL-1", "title": "Templates for agent roles and for organization types" },
|
||||
{ "id": "REQ-FED-1", "title": "Federation between installs (post-v1)" }
|
||||
{ "id": "REQ-FED-1", "title": "Federation between installs (post-v1)" },
|
||||
{ "id": "REQ-INST-1", "title": "The installer offers optional components: pinned, health-checked, removable, switched on in config; first is SearXNG" }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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, 41);
|
||||
assert.equal(ids.length, 43);
|
||||
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.3']);
|
||||
assert.deepEqual([list.prd, list.version], ['docs/prd/mosaic-stack.md', '1.4']);
|
||||
});
|
||||
|
||||
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[41].id: REQ-ROLE-1 twice'));
|
||||
assert.throws(() => loadRequirements(join(dir, 'twice.json')), listError('requirements[43].id: REQ-ROLE-1 twice'));
|
||||
} finally {
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user