feat(case1): add trackerless factory business file (#1819)

This commit is contained in:
jason.woltje committed 2026-10-23 19:12:43 -05:00
1 parent 6002698c32
commit 571376c30e
7 files changed
+274

No files matched your search

+4
View File
@@ -5443,3 +5443,7 @@ Row 299 (573, #1806, Gander, Filbert): before, the P10 band test timed a fault r
2026-10-23 | Goldie | Row 323 / #1819 before | Case 1 lacks a committed business file. Brief requires actual .53 values and refuses guessing. New branch goldie/row323 from local refactor da537e7d1; source review shows project root, literal human id, tracker sync identity/reference metadata and launch model values absent from DESIGN, plus nonempty launch.instances requires another role. Asked Sage (goldie-0008); no config or test written, no test run. Details agents/goldie/work/queue-323/BUILD.md.
2026-10-23 | Goldie | Row 323 / #1819 static blocker (sage-3823) | Mos-1554 requires no bot and an absent, never-created tracker token path. Static tracing confirms this refuses install validation (business cli84-97, credentials78-83) and bus boot (runtime131/157, bus credentials225-228), even without tracker.baseUrl; unset env also refuses at bus credentials278. Reported Sage goldie-0009; no JSON/test/credential written, no tests. Accepted source values/role and refusal-test rulings are recorded in BUILD.md; waiting for product-boundary resolution.
2026-10-24 | Goldie | Row 323 / #1819 resumed draft (sage-3859) | Rebasing prior notes onto Q247 landing dd6cb5872 resolved only append logs. Added trackerless .53 factory JSON: jason, approved project root, chief+assistant for required nonempty launch.instances, claude-code/Opus5.5/high, tester on. No credentials or token placeholder. Seven new tests prepare exact-doc loading plus scratch real validate/install/boot and three refusal paths; one restoring tester-switch mutant prepared. No old test edits; no tests before Sage CLEAR. Source choices/rulings in BUILD.md.
2026-10-24 | Goldie | Row 323 / #1819 pre-test commit (sage-3861 CLEAR) | Sage explicitly requests commit before runs; JSON/new7-case test/restoring mutant and field provenance committed untested before slot work. Exact sources distinguish mos-1554 human/no-bot intent, sage-3820 roles, sage-3822 project/model, and Q247 tracker omission. No old test edits. Next runs: new file, business whole, CLI whole, mutant/restored file, serialized scratch TMPDIR timeout-k10.
+45
View File
@@ -30,3 +30,48 @@ Static trace proves refusal, reported to Sage in goldie-0009:
- business/src/business.mjs:41 requires tracker bot names to begin bot-, :42 requires positive botId. Mos's illustrative no-bot-mosaic-stack-sync would fail that shape; a bot-no-bot marker still cannot solve the absent-file refusal.
Status: real fail-closed product boundary. No business JSON, test, placeholder credential, host action or tests written/run. Await Sage/Mos resolution; do not bypass by inventing a token or expanding product scope. Only investigation notes exist in this worktree. Claim attempts continue separately under the queue window's explicit retry instruction.
## Resumed after Q247 landing — sage-3859
Current base is pushed `dd6cb5872b972bcabb99b82589b2905e4e47dd3e`. Preserved earlier investigation as a notes-only commit, then rebased onto that tip; only append-only BUILD-LOG/SESSIONS conflicts, resolved retaining the entire landed files and appending this row's original suffix. Earlier equivalent local refactor doc commits were skipped by git as already applied. No other row323 source existed before this resume.
Q247 removes the static blocker: this file now omits tracker entirely, with no dummy bot/token/reference. No tracker credential or token file is required or created. The separate Claude session login file remains the operator's run-sheet step, as described in DESIGN section3; this document contains no credential value or reference, and this work reads no credential.
Approved values and minimal role set:
- business mosaic-stack, factory bus.tester true, no library key/project (DESIGN sections1/2/7).
- human jason (Mos-1554, sage-3823); project mosaic-stack at /srv/mosaic/src/mosaic-stack (sage-3822).
- chief-of-staff chief and credential-free assistant, both arbiters chief, launch.by chief, launch.instances [assistant] (sage-3820). The loader requires nonempty launch.instances excluding the launcher (business.mjs:186-191), so a chief-only document cannot load. No other role is needed.
- Both roles use claude-code; plugins.harness enables only claude-code. No pi route or fallback.
- chief model claude-opus-5-5 is Sage's explicit choice (sage-3822). Provider anthropic/model claude-opus-5-5 is the repository model mapping at packages/business/README.md:185. There is no separate per-model default thinking catalog in the implementation: choose high from the Claude harness's supported LEVELS at packages/plugins/harness/claude-code/index.mjs:28, following the existing chief route convention at packages/cli/tests/session-launch.test.mjs:83. Both roles use that one declared model/effort; no extra model or capacity policy is introduced.
One new file packages/business/tests/case1-business-file.test.mjs has seven cases. It first loads the shipped JSON bytes unchanged from a temporary business-file location (loader checks shape, no host path access). Its runtime/CLI/install cases copy the document into a scratch input and replace only the project root with a scratch fixture root, per sage-3820's instruction to use test fixture paths. The real factory installer takes that input via --business-file and uses its real bootstrap/business validation, with only stack-copy stubbed (no clone/install/network). The boot case uses bootConfig + actual startBroker and asserts no tracker config or credential status. Negative cases cover bus.tester false (bus-tester-off), literal library (final validate unsupported key, per sage-3820), and a library project (factory plan profile-library-business). No pre-existing test changed.
The new tester-switch mutant flips only bus.tester in the shipped JSON, targets the new exact-document assertion, then restores/checks bytes in finally. Prepared but not run. Tests and mutant remain held until Sage CLEAR; only syntax/diff/static JSON checks have run. Row323 claimant is still in-progress from rev3749.
## Field provenance and pre-test commit — sage-3861
Sage-3861 CLEAR explicitly requires committing the draft before any run, so test counts attach to a commit. This is a specific exception to the usual green-before-commit rule. Until recorded below, this commit is untested. No old test is modified.
| Document field | Value and source |
| --- | --- |
| businessVersion | 1, business loader's version requirement (business/src/business.mjs:233). Schema value, not a mos-1554 host choice. |
| id | mosaic-stack, row195 DESIGN section7 (sage-1813), restated by row323 brief. |
| human | jason, mos-1554 relayed by sage-3823. |
| arbiters.delivery / arbiters.technical | chief / chief, sage-3820's explicit minimal-role ruling; both reference the chief-of-staff definition. |
| projects.mosaic-stack.root | /srv/mosaic/src/mosaic-stack, sage-3822's explicit project-id/root decision. DESIGN supplied /srv/mosaic as home but did not supply this root. |
| vars.bus.tester | true, DESIGN section2 factory profile and installer bus-tester-off requirement. |
| plugins.harness | [claude-code], brief's Claude-only/P19 mos-0865 boundary and DESIGN section3. |
| roles.chief.definition | chief-of-staff, brief/roles/chief-of-staff.json; no credential or tracker bot. |
| roles.assistant.definition | assistant, sage-3820 acceptance of this one extra credential-free role, required because launch.instances must be nonempty and exclude chief. |
| roles.*.vars.harness | claude-code for both; same Claude-only rule, no fallback route. |
| roles.*.vars.model | claude-opus-5-5 for both, chief model explicitly chosen in sage-3822; reuse the single declared model for assistant to avoid adding another model decision. |
| roles.*.vars.thinking | high, supported effort in packages/plugins/harness/claude-code/index.mjs:28; existing chief convention packages/cli/tests/session-launch.test.mjs:83. The repository has no per-model default-effort catalog; this is an explicit supported-convention choice, not an invented catalog default. |
| launch.by | chief, brief and F7's requirement to name the chief launch; sage-3820. |
| launch.instances | [assistant], sage-3820 and business.mjs:186-191's nonempty/non-launcher rule. |
| launch.models.claude-opus-5-5.provider / model | anthropic / claude-opus-5-5, repository model mapping packages/business/README.md:185 and sage-3822. The model id is also the map key so no extra alias is introduced. |
| Omitted tracker / credentials / library | Q247/mos-1555 and sage-3859 supersede mos-1554's proposed absent-token placeholder; no bot, token path, credential value or library project/key is present. |
Only human=jason is a literal field value supplied by mos-1554. The no-bot intent also comes from mos-1554; Q247 implements it by omission. Other fields deliberately cite the actual design/schema/Sage source rather than attributing them to mos-1554.
Planned runs under sage-3861: new file whole; business suite whole; CLI suite whole; tester-switch mutant; restored new file whole. Fresh scratch TMPDIR and timeout-k10 for each, one process at a time. Existing-test red or any additional old-test edit stops work; first-run new red is recorded and reported. Push remains own branch goldie/row323 after the test sequence/report evidence is concrete.
@@ -0,0 +1,2 @@
85e6b9ac62785734fb9d854ea70ea550e171b5060b5cad0417e2f42f0b60c59e docs/guides/case1-business.mosaic-stack.json
aecd1c0f0fe1eb46800a7dea6f1f2f6a965f1daa33a39f9837bb1e2c19e0abfc packages/business/tests/case1-business-file.test.mjs
+26
View File
@@ -0,0 +1,26 @@
"""Row 323 tester-switch mutant; run only after Sage CLEAR."""
import hashlib
import os
from pathlib import Path
import subprocess
root = Path(__file__).resolve().parents[4]
source = root / 'docs/guides/case1-business.mosaic-stack.json'
fixed = source.read_bytes()
needle = b'"bus.tester": true'
assert fixed.count(needle) == 1
try:
source.write_bytes(fixed.replace(needle, b'"bus.tester": false'))
result = subprocess.run([
'timeout', '-k', '10', '90', 'node', '--test', '--test-reporter=tap',
'--test-name-pattern=row 323: committed Case 1 document loads',
'packages/business/tests/case1-business-file.test.mjs',
], cwd=root, env=os.environ, text=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
Path(__file__).with_suffix('.log').write_text(result.stdout)
print(f'bus.tester mutant: exit {result.returncode}', flush=True)
assert result.returncode == 1, result.stdout
assert '# fail 1\n' in result.stdout and 'false !== true' in result.stdout, result.stdout
finally:
source.write_bytes(fixed)
assert source.read_bytes() == fixed
print('restored sha256 ' + hashlib.sha256(fixed).hexdigest(), flush=True)
+2
View File
@@ -1612,3 +1612,5 @@ are never rewritten or removed; corrections are new entries.
2026-10-23T23:52Z | Duckworth (Opus 5.5) | row 324 round 1 static review on dbdfcfd52 (sage-3853) | APPROVE (static), manifest 52874356 matches, every business.tracker reader handles absence, present null refuses, no @sync when absent, N1 doc (duckworth-0298) |
2026-10-23T22:59Z | Goldie (a13dd6d5-5e73-4b7d-8318-02abeff24940) | Row 323 / #1819 Case 1 factory business | New goldie/row323 worktree from da537e7d1; source review finds host/project/human/tracker/model values absent from DESIGN, asked Sage under explicit no-guess boundary (goldie-0008). No tests/config/host action; claim retries authorized.
2026-10-23T23:02Z | Goldie (a13dd6d5-5e73-4b7d-8318-02abeff24940) | Row 323 / #1819 no-bot static trace | Confirmed required absent tracker token refuses both install validation and bus boot regardless of tracker.baseUrl; reported exact source lines to Sage (goldie-0009), stopped product work per sage-3823. No tests/config/credentials/host action.
2026-10-24T00:11Z | Goldie (a13dd6d5-5e73-4b7d-8318-02abeff24940) | Row 323 / #1819 resumed after Q247 | On dd6cb5872, trackerless Case1 JSON and seven new scratch tests drafted; no old test changes or credentials. Prepared mutant, syntax/diff/static JSON checks only; asking Sage for test CLEAR.
2026-10-24T00:12Z | Goldie (a13dd6d5-5e73-4b7d-8318-02abeff24940) | Row 323 / #1819 pre-test commit | sage-3861 CLEAR explicitly requests a committed draft before testing. Field provenance recorded; no old tests changed. Runs pending, no green claim.
@@ -0,0 +1,48 @@
{
"businessVersion": 1,
"id": "mosaic-stack",
"human": "jason",
"arbiters": {
"delivery": "chief",
"technical": "chief"
},
"projects": {
"mosaic-stack": {
"root": "/srv/mosaic/src/mosaic-stack"
}
},
"vars": {
"bus.tester": true
},
"plugins": {
"harness": ["claude-code"]
},
"roles": {
"chief": {
"definition": "chief-of-staff",
"vars": {
"harness": "claude-code",
"model": "claude-opus-5-5",
"thinking": "high"
}
},
"assistant": {
"definition": "assistant",
"vars": {
"harness": "claude-code",
"model": "claude-opus-5-5",
"thinking": "high"
}
}
},
"launch": {
"by": "chief",
"instances": ["assistant"],
"models": {
"claude-opus-5-5": {
"provider": "anthropic",
"model": "claude-opus-5-5"
}
}
}
}
@@ -0,0 +1,147 @@
// Row 323 (#1819): .53 factory business document; all execution stays in scratch fixtures.
import { test } from "node:test";
import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { loadBusiness } from "../src/index.mjs";
import { REPO, REPO_ROLES, systemConfig, tmp, writeJson } from "./helpers.mjs";
import { bootConfig } from "../../cli/src/config.mjs";
import { startBroker } from "../../bus/src/runtime.mjs";
import { Client } from "../../bus/src/client.mjs";
const DOCUMENT = join(REPO, "docs/guides/case1-business.mosaic-stack.json");
const COMMIT = "c".repeat(40);
const document = () => JSON.parse(readFileSync(DOCUMENT, "utf8"));
function world(t) {
const root = tmp();
t.after(() => rmSync(root, { recursive: true, force: true }));
const home = join(root, "home");
const configDir = join(home, ".config/mosaic-dev");
mkdirSync(configDir, { recursive: true, mode: 0o700 });
const doc = document();
// Replace the approved host project path only in the scratch execution input.
// The exact shipped document is separately loaded below without any substitution.
for (const project of Object.values(doc.projects)) {
project.root = join(root, "fixture-project");
mkdirSync(project.root, { recursive: true });
}
const input = writeJson(join(root, "input/mosaic-stack.json"), doc);
const config = join(configDir, "config.json");
const business = join(configDir, "businesses/mosaic-stack.json");
const copy = join(root, "fake-stack-copy");
writeFileSync(copy, '#!/usr/bin/env bash\n[ "$1" = copy ] && [ "$3" = --copies ] || exit 4\nmkdir -p "$4/$2/scripts" && : >"$4/$2/scripts/mosaic"\n', { mode: 0o755 });
const env = {
PATH: `${dirname(process.execPath)}:/usr/bin:/bin`, HOME: home,
MOSAIC_CONFIG: config, MOSAIC_ROLES_DIR: REPO_ROLES, CASE2_STACK_COPY: copy,
};
const install = () => spawnSync(join(REPO, "scripts/case2-install.sh"), [
"--business", "mosaic-stack", "--business-file", input, "--commit", COMMIT, "--profile", "factory",
], { env, encoding: "utf8", timeout: 30000 });
return { root, home, doc, input, config, configDir, business, env, install };
}
const output = (r) => r.stdout + r.stderr;
function configure(x) {
// Reuse the existing scratch system-config fixture, never a real install config.
const fixture = JSON.parse(readFileSync(systemConfig(x.root), "utf8"));
fixture.dataRoot = join(x.root, "data");
mkdirSync(fixture.dataRoot, { recursive: true, mode: 0o700 });
writeJson(x.config, fixture);
writeJson(x.business, x.doc);
return fixture;
}
test("row 323: committed Case 1 document loads unchanged through the business loader", (t) => {
const x = world(t);
const bytes = readFileSync(DOCUMENT);
mkdirSync(dirname(x.business), { recursive: true, mode: 0o700 });
writeFileSync(x.business, bytes, { mode: 0o600 });
const b = loadBusiness("mosaic-stack", { dir: x.configDir, rolesDir: REPO_ROLES });
assert.deepEqual(readFileSync(x.business), bytes);
assert.equal(b.id, "mosaic-stack");
assert.equal(b.human, "jason");
assert.equal(b.vars["bus.tester"], true);
assert.equal(b.tracker, null);
assert.equal(Object.hasOwn(document(), "tracker"), false);
assert.equal(Object.hasOwn(document(), "library"), false);
assert.deepEqual(b.projects, { "mosaic-stack": { root: "/srv/mosaic/src/mosaic-stack" } });
assert.deepEqual(Object.keys(b.roles), ["chief", "assistant"]);
assert.deepEqual(b.plugins.harness, ["claude-code"]);
assert.equal(b.launch.by, "chief");
assert.deepEqual(b.launch.instances, ["assistant"]);
assert.deepEqual(b.arbiters, { delivery: "chief", technical: "chief" });
assert.deepEqual(b.launch.models["claude-opus-5-5"], { provider: "anthropic", model: "claude-opus-5-5" });
for (const role of Object.values(b.roles)) {
assert.equal(role.vars.harness, "claude-code");
assert.equal(role.vars.model, "claude-opus-5-5");
assert.equal(role.vars.thinking, "high");
assert.deepEqual(role.credentials, {});
assert.equal(role.tracker, null);
}
});
test("row 323: real business validate accepts the Case 1 fixture without tracker credentials", (t) => {
const x = world(t);
configure(x);
const r = spawnSync(process.execPath, [join(REPO, "packages/business/src/cli.mjs"), "validate", "mosaic-stack"],
{ env: x.env, encoding: "utf8", timeout: 30000 });
assert.equal(r.status, 0, output(r));
assert.equal(JSON.parse(r.stdout).business, "mosaic-stack");
});
test("row 323: real factory install accepts the document's scratch input and writes it unchanged", (t) => {
const x = world(t);
const r = x.install();
assert.equal(r.status, 0, output(r));
assert.deepEqual(JSON.parse(readFileSync(x.business, "utf8")), x.doc);
assert.match(output(r), /business mosaic-stack validates/);
assert.equal(existsSync(join(x.configDir, "personas")), false);
assert.equal(existsSync(join(x.configDir, "secrets/mosaic-stack")), false);
});
test("row 323: the Case 1 business boots without a tracker or @sync credential", async (t) => {
const x = world(t);
const system = configure(x);
const boot = bootConfig({ system, businessId: "mosaic-stack", env: x.env });
assert.equal(Object.hasOwn(boot, "trackers"), false);
const runtime = await startBroker(boot);
t.after(() => runtime.close());
assert.deepEqual(runtime.credentials.status(), []);
const reader = new Client({ path: runtime.path, cap: runtime.readers[0].cap });
assert.deepEqual(await reader.call("credentials"), []);
});
test("row 323: factory install refuses bus.tester false before writing", (t) => {
const x = world(t);
x.doc.vars["bus.tester"] = false;
writeJson(x.input, x.doc);
const r = x.install();
assert.equal(r.status, 1, output(r));
assert.match(output(r), /refused: bus-tester-off:/);
assert.equal(existsSync(x.business), false);
assert.equal(existsSync(x.config), false);
});
test("row 323: literal library key refuses through final business validation", (t) => {
const x = world(t);
x.doc.library = {};
writeJson(x.input, x.doc);
const r = x.install();
assert.equal(r.status, 1, output(r));
assert.match(output(r), /refused: validate: .*unsupported business file key: "library"/);
assert.equal(existsSync(x.business), false);
});
test("row 323: a library project refuses through the factory profile plan", (t) => {
const x = world(t);
x.doc.projects.books = { kind: "library" };
writeJson(x.input, x.doc);
const r = x.install();
assert.equal(r.status, 1, output(r));
assert.match(output(r), /refused: profile-library-business:/);
assert.equal(existsSync(x.business), false);
assert.equal(existsSync(x.config), false);
});