sage: row 64 D2 evidence, scratch-root builder, driver, check and both coder manifests (mos-0863 D2, #1557 comment 29228)
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
// D2 scratch root (mos-0863 D2, mos-0847): the example file plus the plug-in keys, nothing live.
|
||||
// Usage: node d2-build.mjs <harness> writes d2/config/{config.json,businesses/mosaic-stack.json}
|
||||
import { chmodSync, mkdirSync, readFileSync, writeFileSync, existsSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { spawnSync } from "node:child_process";
|
||||
const LAND = "/mnt/storage/scratch/sage-r64/land";
|
||||
const D2 = "/mnt/storage/scratch/sage-r64/d2";
|
||||
const harness = process.argv[2];
|
||||
if (!["pi", "claude-code"].includes(harness)) throw new Error("harness?");
|
||||
const FAR = "2099-01-01";
|
||||
const secrets = join(D2, "secrets");
|
||||
mkdirSync(secrets, { recursive: true, mode: 0o700 });
|
||||
const w = (f, o) => { mkdirSync(join(f, ".."), { recursive: true }); writeFileSync(f, JSON.stringify(o, null, 2) + "\n"); };
|
||||
const doc = JSON.parse(readFileSync(join(LAND, "packages/business/examples/mosaic-stack.example.json"), "utf8"));
|
||||
const edits = [];
|
||||
// Every /home/you token path and YYYY-MM-DD date becomes a stand-in file and a far date.
|
||||
const walk = (o, at) => {
|
||||
for (const [k, v] of Object.entries(o)) {
|
||||
if (v && typeof v === "object") walk(v, `${at}.${k}`);
|
||||
else if (k === "file" && typeof v === "string" && v.startsWith("/home/you/")) {
|
||||
const f = join(secrets, v.split("/").pop());
|
||||
writeFileSync(f, "placeholder-not-a-token"); chmodSync(f, 0o600);
|
||||
o[k] = f; edits.push(`${at}.file -> stand-in`);
|
||||
} else if ((k === "expires" || k === "rotateBy") && v === "YYYY-MM-DD") { o[k] = FAR; edits.push(`${at}.${k} -> ${FAR}`); }
|
||||
}
|
||||
};
|
||||
walk(doc, "");
|
||||
let n = 1; for (const r of Object.values(doc.roles)) if (r.tracker && "botId" in r.tracker) r.tracker.botId = n++;
|
||||
if (doc.tracker?.sync && "botId" in doc.tracker.sync) doc.tracker.sync.botId = n++;
|
||||
edits.push("botIds 1..n (example has 0)");
|
||||
doc.vars["tracker.baseUrl"] = "http://127.0.0.1:9"; doc.vars["gitea.baseUrl"] = "http://127.0.0.1:9"; edits.push("baseUrls -> 127.0.0.1:9");
|
||||
for (const m of Object.values(doc.launch.models)) m.provider = "anthropic";
|
||||
doc.launch.limits.models = { anthropic: doc.launch.limits.models["your-provider"] }; edits.push("your-provider -> anthropic");
|
||||
doc.roles.coder.vars = { ...doc.roles.coder.vars, harness, thinking: "medium" }; edits.push(`coder vars harness ${harness}, thinking medium`);
|
||||
doc.plugins = { ...(doc.plugins ?? {}), harness: ["pi", "claude-code"] }; edits.push("plugins.harness [pi, claude-code]");
|
||||
const project = join(D2, "project");
|
||||
if (!existsSync(join(project, ".git"))) {
|
||||
mkdirSync(project, { recursive: true });
|
||||
const g = (...a) => { const r = spawnSync("git", ["-c", "user.name=d2", "-c", "[email protected]", "-C", project, ...a], { encoding: "utf8" }); if (r.status) throw new Error(r.stderr); };
|
||||
g("init", "-q", "-b", "main"); writeFileSync(join(project, "README.md"), "D2 scratch project\n"); g("add", "README.md"); g("commit", "-q", "-m", "one");
|
||||
}
|
||||
doc.projects.stack.root = project; edits.push("projects.stack.root -> scratch repo on main");
|
||||
w(join(D2, "config", "config.json"), { configVersion: 1, environment: "development", dataRoot: join(D2, harness === "pi" ? "datapi" : "data"),
|
||||
execution: { backend: "docker", provider: "zai", model: "glm-5.3-flash", adapter: "mock" } });
|
||||
w(join(D2, "config", "businesses", "mosaic-stack.json"), doc);
|
||||
mkdirSync(join(D2, harness === "pi" ? "datapi" : "data"), { recursive: true, mode: 0o700 });
|
||||
console.log(edits.join("\n"));
|
||||
@@ -0,0 +1,22 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { createHash } from "node:crypto";
|
||||
const D2 = "/mnt/storage/scratch/sage-r64/d2", LAND = "/mnt/storage/scratch/sage-r64/land";
|
||||
const want = JSON.parse(readFileSync(`${LAND}/roles/coder.json`, "utf8")).skills;
|
||||
for (const h of ["claude-code", "pi"]) {
|
||||
const raw = readFileSync(`${D2}/manifest-${h}.json`);
|
||||
const m = JSON.parse(raw);
|
||||
const prompt = readFileSync(`${D2}/prompt-${h}.md`, "utf8");
|
||||
const names = (m.skills ?? []).map((s) => s.name);
|
||||
let files = 0, bad = 0, inPrompt = 0;
|
||||
for (const s of m.skills) for (const [path, sha256] of Object.entries(s.files)) { const f = { path, sha256 };
|
||||
files++;
|
||||
const src = readFileSync(`${LAND}/skills/${s.name}/${f.path}`);
|
||||
if (createHash("sha256").update(src).digest("hex") !== f.sha256) bad++;
|
||||
const open = `<skill-file skill="${s.name}" path="${f.path}">\n`;
|
||||
if (prompt.includes(open + src.toString("utf8"))) inPrompt++;
|
||||
}
|
||||
const markers = (prompt.match(/^<skill-file /gm) ?? []).length;
|
||||
console.log(h, "manifest sha256", createHash("sha256").update(raw).digest("hex"), "skills", names.join(","),
|
||||
"matchesRole", JSON.stringify(names) === JSON.stringify(want), "files", files, "digestMismatch", bad, "inPrompt", inPrompt, "markers", markers,
|
||||
"skillsHeading", /^## Skills$/m.test(prompt));
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
claude-code manifest sha256 cc9b4423319da1af1df7c2011ff7f93dd05305a62d2f50d10eb7b3a475604488 skills ms-unslop,ms-sdlc,ms-file-read,ms-file-write matchesRole true files 4 digestMismatch 0 inPrompt 4 markers 4 skillsHeading true
|
||||
pi manifest sha256 c6e437125bc857e8b3d8f9dfe3197478dceb5ad4066f2875df1b970dead42fb4 skills ms-unslop,ms-sdlc,ms-file-read,ms-file-write matchesRole true files 4 digestMismatch 0 inPrompt 4 markers 4 skillsHeading true
|
||||
@@ -0,0 +1,6 @@
|
||||
credential names loaded: CLAUDE_CODE_OAUTH_TOKEN
|
||||
launch: {"ok":true,"result":{"run":"rc13bcd555652","instance":"coder","harness":"claude-code","model":"claude-sonnet-5-5"}}
|
||||
runDir: /mnt/storage/scratch/sage-r64/d2/data/launches/mosaic-stack/rc13bcd555652
|
||||
usage: {"event":"usage-unknown","business":"mosaic-stack","run":"rc13bcd555652","instance":"coder","turn":"be113361-ee62-42f7-a776-f38d4b004943","source":"@none","code":"baseline-unknown"}
|
||||
reply: {"from_role":"coder","from_run":"rc13bcd555652","body":"ms-unslop, ms-sdlc, ms-file-read, ms-file-write"}
|
||||
log: run rc13bcd555652 (coder) ended: stopped
|
||||
@@ -0,0 +1,34 @@
|
||||
import fs from "node:fs";
|
||||
const D = "d2/";
|
||||
const chk = fs.readFileSync("d2-check.txt", "utf8").trim();
|
||||
const fence = "```";
|
||||
const body = `Row 64 D2 (mos-0863 D2, mos-0864): one managed coder session per harness on a scratch root, with the two bundle manifests below.
|
||||
|
||||
Setup. The scratch root is \`/mnt/storage/scratch/sage-r64/d2\`, built from \`packages/business/examples/mosaic-stack.example.json\` at 6b6567b8b plus the plug-in keys (mos-0847). The edits: \`plugins.harness [pi, claude-code]\`, provider \`your-provider\` to \`anthropic\`, coder vars harness and thinking medium, the /home/you token paths to stand-in files with far dates, botIds 1..n, base URLs to 127.0.0.1:9, and the project root to a scratch repo on main. The eight skills were installed and activated there with \`scripts/skill.sh\` from the landed tree. Nothing under ~/.mosaic-dev was touched. The driver uses the real launcher, host and harness modules from a worktree at 6b6567b8b. Scripts and logs are in \`agents/sage/work/queue-64/d2/\`.
|
||||
|
||||
Claude Code, run rc13bcd555652. One short turn. The coder was asked to list the skill names in its Skills section and replied \`ms-unslop, ms-sdlc, ms-file-read, ms-file-write\`. Then it was stopped (ended: stopped).
|
||||
|
||||
Pi, run r3455505dd5da. Launch only, no turn. The runner claimed coder and exited 0 on stop. There was no model turn because this host has no credential pi reads: pi takes ANTHROPIC_API_KEY or ANTHROPIC_OAUTH_TOKEN, and the host's one managed credential is CLAUDE_CODE_OAUTH_TOKEN. That gap goes to Mos.
|
||||
|
||||
Check (\`d2-check.mjs\`). Each manifest lists the coder's four skills in role order. Every file sha256 equals the landed \`skills/\` file. Each file appears byte for byte after its \`<skill-file>\` marker in prompt.md, under \`## Skills\`. No credential value appears in either manifest or prompt.
|
||||
|
||||
${fence}
|
||||
${chk}
|
||||
${fence}
|
||||
|
||||
<details><summary>manifest-claude-code.json</summary>
|
||||
|
||||
${fence}json
|
||||
${fs.readFileSync(D + "manifest-claude-code.json", "utf8").trim()}
|
||||
${fence}
|
||||
</details>
|
||||
|
||||
<details><summary>manifest-pi.json</summary>
|
||||
|
||||
${fence}json
|
||||
${fs.readFileSync(D + "manifest-pi.json", "utf8").trim()}
|
||||
${fence}
|
||||
</details>
|
||||
|
||||
Sage`;
|
||||
fs.writeFileSync("d2-comment.json", JSON.stringify({ body }));
|
||||
@@ -0,0 +1,76 @@
|
||||
// D2 driver: one managed coder session on the scratch root, real modules from the land tree.
|
||||
// Usage: node d2-drive.mjs <pi|claude-code> <turn|noturn>. Prints no credential value.
|
||||
import { readFileSync, existsSync, copyFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { homedir } from "node:os";
|
||||
const LAND = "/mnt/storage/scratch/sage-r64/land";
|
||||
const D2 = "/mnt/storage/scratch/sage-r64/d2";
|
||||
const [harness, mode] = process.argv.slice(2);
|
||||
const { Client } = await import(`${LAND}/packages/bus/src/client.mjs`);
|
||||
const { readSessions, SESSION_CREDENTIALS } = await import(`${LAND}/packages/seat/src/session.mjs`);
|
||||
const { bootConfig, loadSystem } = await import(`${LAND}/packages/cli/src/config.mjs`);
|
||||
const { startHost, startTimeOf } = await import(`${LAND}/packages/cli/src/host.mjs`);
|
||||
const { createLauncher } = await import(`${LAND}/packages/cli/src/launcher.mjs`);
|
||||
const { AGENT_MARKERS } = await import(`${LAND}/packages/cli/src/transport.mjs`);
|
||||
|
||||
const env = { ...process.env, MOSAIC_CONFIG: join(D2, "config", "config.json"), MOSAIC_ROLES_DIR: join(LAND, "roles"), MOSAIC_CLAUDE_BIN: join(homedir(), ".local/bin/claude") };
|
||||
for (const k of AGENT_MARKERS) delete env[k];
|
||||
delete env.NODE_TEST_CONTEXT;
|
||||
for (const k of SESSION_CREDENTIALS.flat()) delete env[k];
|
||||
// The host's session credential file holds one name, CLAUDE_CODE_OAUTH_TOKEN. Loaded, never printed.
|
||||
for (const line of readFileSync(join(homedir(), ".config/mosaic-dev/secrets/claude-session.env"), "utf8").split("\n")) {
|
||||
const m = line.match(/^\s*(?:export\s+)?([A-Z_][A-Z0-9_]*)=(.*)$/);
|
||||
if (m) env[m[1]] = m[2].replace(/^(['"])(.*)\1$/, "$2");
|
||||
}
|
||||
console.log("credential names loaded:", SESSION_CREDENTIALS.flat().filter((k) => env[k]).join(","));
|
||||
|
||||
const business = "mosaic-stack";
|
||||
const logs = [];
|
||||
const log = (l) => { logs.push(l); console.log("log:", l); };
|
||||
const system = loadSystem({ env });
|
||||
const boot = bootConfig({ system, businessId: business, env });
|
||||
const host = await startHost({ boot, business, log });
|
||||
const launcher = createLauncher({ host, system, env, sessionDefaults: { pollInterval: 100 }, log });
|
||||
let code = 0;
|
||||
try {
|
||||
await launcher.listen();
|
||||
const bind = async (role, run) => {
|
||||
const b = await host.bindLaunch({ business, role, run, harness: "claude-code", pid: process.pid, startTime: startTimeOf(process.pid) });
|
||||
const c = new Client({ path: host.path, cap: b.cap });
|
||||
await c.call("role.claim");
|
||||
return { b, c };
|
||||
};
|
||||
const chief = await bind("chief", `chief-d2-${harness}`);
|
||||
const cto = await bind("cto", `cto-d2-${harness}`);
|
||||
const launched = await launcher.fromSession(chief.b.cap, "coder");
|
||||
console.log("launch:", JSON.stringify(launched));
|
||||
if (!launched.ok) throw new Error("launch refused");
|
||||
const run = launched.result.run;
|
||||
const runDir = readSessions(boot.dataRoot ?? system.dataRoot).find((s) => s.run === run)?.runDir
|
||||
?? join(system.dataRoot, "launches", business, run);
|
||||
const manifest = join(runDir, "bundle", "manifest.json");
|
||||
for (let i = 0; i < 100 && !existsSync(manifest); i++) await new Promise((r) => setTimeout(r, 100));
|
||||
copyFileSync(manifest, join(D2, `manifest-${harness}.json`));
|
||||
copyFileSync(join(runDir, "bundle", "prompt.md"), join(D2, `prompt-${harness}.md`));
|
||||
console.log("runDir:", runDir);
|
||||
if (mode === "turn") {
|
||||
const sent = await cto.c.call("message.send", { to: "coder", class: "REQUEST", body: "D2 check for row 64. Reply in one line: list the skill names in your Skills section, and nothing else. Don't use any tool." });
|
||||
const end = Date.now() + 240000;
|
||||
let reply;
|
||||
while (!reply && Date.now() < end) {
|
||||
reply = (await cto.c.call("message.receive")).find((m) => m.in_reply_to === sent.id);
|
||||
if (!reply) await new Promise((r) => setTimeout(r, 1000));
|
||||
}
|
||||
console.log("reply:", reply ? JSON.stringify({ from_role: reply.from_role, from_run: reply.from_run, body: reply.body.slice(-600) }) : "NONE in 240 s");
|
||||
if (!reply) code = 3;
|
||||
} else {
|
||||
await new Promise((r) => setTimeout(r, 3000));
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("error:", e.message);
|
||||
code = 2;
|
||||
} finally {
|
||||
await launcher.close();
|
||||
await host.close(0);
|
||||
}
|
||||
process.exit(code);
|
||||
@@ -0,0 +1,4 @@
|
||||
credential names loaded: CLAUDE_CODE_OAUTH_TOKEN
|
||||
launch: {"ok":true,"result":{"run":"r3455505dd5da","instance":"coder","harness":"pi","model":"claude-sonnet-5-5"}}
|
||||
runDir: /mnt/storage/scratch/sage-r64/d2/datapi/launches/mosaic-stack/r3455505dd5da
|
||||
log: run r3455505dd5da (coder) ended: stopped
|
||||
@@ -0,0 +1,112 @@
|
||||
{
|
||||
"bundleVersion": 1,
|
||||
"business": "mosaic-stack",
|
||||
"instance": "coder",
|
||||
"definition": "coder",
|
||||
"run": "rc13bcd555652",
|
||||
"launchedBy": "chief",
|
||||
"resolvedDigest": "5629393ba23a5318bb6b70568e78b79b36c7b388eb7a52ff088fcee9d870e604",
|
||||
"harness": "claude-code",
|
||||
"provider": "anthropic",
|
||||
"model": "claude-sonnet-5-5",
|
||||
"modelKey": "sonnet",
|
||||
"thinking": "medium",
|
||||
"route": "primary",
|
||||
"routeReason": null,
|
||||
"harnessVersion": "2.1.303 (Claude Code)",
|
||||
"builtins": [
|
||||
"Read",
|
||||
"Write",
|
||||
"Edit",
|
||||
"Bash",
|
||||
"Grep",
|
||||
"Glob"
|
||||
],
|
||||
"typed": [
|
||||
"mcp__mosaic__send_message",
|
||||
"mcp__mosaic__push_working",
|
||||
"mcp__mosaic__request_review",
|
||||
"mcp__mosaic__read_spec",
|
||||
"mcp__mosaic__write_record",
|
||||
"mcp__mosaic__raise_decision",
|
||||
"mcp__mosaic__list_agents",
|
||||
"mcp__mosaic__inbox",
|
||||
"mcp__mosaic__trail"
|
||||
],
|
||||
"untyped": [
|
||||
"task.update.assigned",
|
||||
"task.scope.change"
|
||||
],
|
||||
"webSource": null,
|
||||
"skills": [
|
||||
{
|
||||
"name": "ms-unslop",
|
||||
"path": "/mnt/storage/scratch/sage-r64/d2/data/launches/mosaic-stack/rc13bcd555652/bundle/skills/ms-unslop",
|
||||
"sha256": "0eace7c537ae711876cc82137aa5e4f84f1a2145676de8cfb2fe963f32efb530",
|
||||
"files": {
|
||||
"SKILL.md": "0eace7c537ae711876cc82137aa5e4f84f1a2145676de8cfb2fe963f32efb530"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ms-sdlc",
|
||||
"path": "/mnt/storage/scratch/sage-r64/d2/data/launches/mosaic-stack/rc13bcd555652/bundle/skills/ms-sdlc",
|
||||
"sha256": "f81aa1adf33f9d46f9783df3eeec9f705c5b65c37d48d7708cdb923eac0c5478",
|
||||
"files": {
|
||||
"SKILL.md": "f81aa1adf33f9d46f9783df3eeec9f705c5b65c37d48d7708cdb923eac0c5478"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ms-file-read",
|
||||
"path": "/mnt/storage/scratch/sage-r64/d2/data/launches/mosaic-stack/rc13bcd555652/bundle/skills/ms-file-read",
|
||||
"sha256": "28f9b76bb89f8aadfb3b8933255c54e360af741b050a7738cb0a904f7835a95e",
|
||||
"files": {
|
||||
"SKILL.md": "28f9b76bb89f8aadfb3b8933255c54e360af741b050a7738cb0a904f7835a95e"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ms-file-write",
|
||||
"path": "/mnt/storage/scratch/sage-r64/d2/data/launches/mosaic-stack/rc13bcd555652/bundle/skills/ms-file-write",
|
||||
"sha256": "ad9ee2d00b87b2c6fa36b7863c0034b8883f7e1fa2aa5390e67121eda0165e14",
|
||||
"files": {
|
||||
"SKILL.md": "ad9ee2d00b87b2c6fa36b7863c0034b8883f7e1fa2aa5390e67121eda0165e14"
|
||||
}
|
||||
}
|
||||
],
|
||||
"reliesOn": [
|
||||
"S0-1 command hook deny, no --bare",
|
||||
"S0-2 hook wrapped as <gate> || exit 2",
|
||||
"S0-3 a missing gate blocks through the wrapper",
|
||||
"S0-4 timeout -k 2 10 <gate> || exit 2 with hook timeout 20",
|
||||
"S0-5 bash is limited by the tool limit only"
|
||||
],
|
||||
"gateTimeout": {
|
||||
"n": 10,
|
||||
"k": 2,
|
||||
"hook": 20
|
||||
},
|
||||
"files": {
|
||||
"prompt.md": "ac87d103061dc25a362e4df196ad06d73d9b0868ab1b4aa0ac59338e9b5b0332",
|
||||
"policy.json": "94f5b3f5b26bc72c60f119c5a7c2b52219dbf6d3ea11153a15210fa1698bdb1c",
|
||||
"tools.json": "18a2f015bdbf419ed7f6634724a68971f4ef3cee3bb9749c112681513b52a3b3",
|
||||
"settings.json": "b1172a211542dba492cb5773afa3a2ce578af7503d13c04b4060ed0d38266ffa",
|
||||
"mcp.json": "1cb0c79bce23651432d7374f5b030a8c3f5eb86273c55b207faf8897dbd996f5"
|
||||
},
|
||||
"sources": {
|
||||
"gate": {
|
||||
"path": "/mnt/storage/scratch/sage-r64/land/packages/harness/src/gate.mjs",
|
||||
"sha256": "a74ef2db4093c0c797ba9e7e28e4e4df0ceac9040385f00e60a273f39af9610b"
|
||||
},
|
||||
"tools": {
|
||||
"path": "/mnt/storage/scratch/sage-r64/land/packages/harness/src/tools.mjs",
|
||||
"sha256": "051b0a699e9f034cc70c992f4dda546a982b6e55695ef1e001d32c240761c5a4"
|
||||
},
|
||||
"claudeGate": {
|
||||
"path": "/mnt/storage/scratch/sage-r64/land/packages/harness/src/claude-gate.mjs",
|
||||
"sha256": "32b5090760c95eea0e1232ff36ec13a1d9b58335b2eade621196dec1ebdbe784"
|
||||
},
|
||||
"mcpServer": {
|
||||
"path": "/mnt/storage/scratch/sage-r64/land/packages/harness/src/mcp-server.mjs",
|
||||
"sha256": "ce0107c3b21e07925b6543b6b925da8b8768823448d4fcf30b620883cfd2d39e"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
{
|
||||
"bundleVersion": 1,
|
||||
"business": "mosaic-stack",
|
||||
"instance": "coder",
|
||||
"definition": "coder",
|
||||
"run": "r3455505dd5da",
|
||||
"launchedBy": "chief",
|
||||
"resolvedDigest": "caa2d2e17ae04a5e124aca80cab28bb1e14aed687074838992c227b746da21ba",
|
||||
"harness": "pi",
|
||||
"provider": "anthropic",
|
||||
"model": "claude-sonnet-5-5",
|
||||
"modelKey": "sonnet",
|
||||
"thinking": "medium",
|
||||
"route": "primary",
|
||||
"routeReason": null,
|
||||
"harnessVersion": "0.85.1",
|
||||
"builtins": [
|
||||
"read",
|
||||
"write",
|
||||
"edit",
|
||||
"bash",
|
||||
"grep",
|
||||
"find",
|
||||
"ls"
|
||||
],
|
||||
"typed": [
|
||||
"send_message",
|
||||
"push_working",
|
||||
"request_review",
|
||||
"read_spec",
|
||||
"write_record",
|
||||
"raise_decision",
|
||||
"list_agents",
|
||||
"inbox",
|
||||
"trail"
|
||||
],
|
||||
"untyped": [
|
||||
"task.update.assigned",
|
||||
"task.scope.change"
|
||||
],
|
||||
"webSource": null,
|
||||
"skills": [
|
||||
{
|
||||
"name": "ms-unslop",
|
||||
"path": "/mnt/storage/scratch/sage-r64/d2/datapi/launches/mosaic-stack/r3455505dd5da/bundle/skills/ms-unslop",
|
||||
"sha256": "0eace7c537ae711876cc82137aa5e4f84f1a2145676de8cfb2fe963f32efb530",
|
||||
"files": {
|
||||
"SKILL.md": "0eace7c537ae711876cc82137aa5e4f84f1a2145676de8cfb2fe963f32efb530"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ms-sdlc",
|
||||
"path": "/mnt/storage/scratch/sage-r64/d2/datapi/launches/mosaic-stack/r3455505dd5da/bundle/skills/ms-sdlc",
|
||||
"sha256": "f81aa1adf33f9d46f9783df3eeec9f705c5b65c37d48d7708cdb923eac0c5478",
|
||||
"files": {
|
||||
"SKILL.md": "f81aa1adf33f9d46f9783df3eeec9f705c5b65c37d48d7708cdb923eac0c5478"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ms-file-read",
|
||||
"path": "/mnt/storage/scratch/sage-r64/d2/datapi/launches/mosaic-stack/r3455505dd5da/bundle/skills/ms-file-read",
|
||||
"sha256": "28f9b76bb89f8aadfb3b8933255c54e360af741b050a7738cb0a904f7835a95e",
|
||||
"files": {
|
||||
"SKILL.md": "28f9b76bb89f8aadfb3b8933255c54e360af741b050a7738cb0a904f7835a95e"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ms-file-write",
|
||||
"path": "/mnt/storage/scratch/sage-r64/d2/datapi/launches/mosaic-stack/r3455505dd5da/bundle/skills/ms-file-write",
|
||||
"sha256": "ad9ee2d00b87b2c6fa36b7863c0034b8883f7e1fa2aa5390e67121eda0165e14",
|
||||
"files": {
|
||||
"SKILL.md": "ad9ee2d00b87b2c6fa36b7863c0034b8883f7e1fa2aa5390e67121eda0165e14"
|
||||
}
|
||||
}
|
||||
],
|
||||
"reliesOn": [
|
||||
"S0-1 tool_call block",
|
||||
"S0-2 a throw blocks",
|
||||
"S0-3 a missing -e refuses to start",
|
||||
"S0-4 external wall clock plus agent_end check",
|
||||
"S0-5 bash is limited by the tool limit only"
|
||||
],
|
||||
"gateTimeout": null,
|
||||
"files": {
|
||||
"prompt.md": "ba0b4971d4ee8ed230840472b998aa2325c1917f8c922c20cb4f840a3106fbbf",
|
||||
"policy.json": "eca86aeacf131c1d5d0cd83ffc58c03b03b013fd2712acdd3187cbcb222c43dd",
|
||||
"tools.json": "18a2f015bdbf419ed7f6634724a68971f4ef3cee3bb9749c112681513b52a3b3"
|
||||
},
|
||||
"sources": {
|
||||
"gate": {
|
||||
"path": "/mnt/storage/scratch/sage-r64/land/packages/harness/src/gate.mjs",
|
||||
"sha256": "a74ef2db4093c0c797ba9e7e28e4e4df0ceac9040385f00e60a273f39af9610b"
|
||||
},
|
||||
"tools": {
|
||||
"path": "/mnt/storage/scratch/sage-r64/land/packages/harness/src/tools.mjs",
|
||||
"sha256": "051b0a699e9f034cc70c992f4dda546a982b6e55695ef1e001d32c240761c5a4"
|
||||
},
|
||||
"piExtension": {
|
||||
"path": "/mnt/storage/scratch/sage-r64/land/packages/harness/src/pi-extension.mjs",
|
||||
"sha256": "fcba4b8dfd9dde947a79f88376d880f383e2a04ee3c0a9ba2fa5af641fe61b35"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
{
|
||||
"businessVersion": 1,
|
||||
"id": "mosaic-stack",
|
||||
"human": "jason",
|
||||
"arbiters": {
|
||||
"delivery": "pm",
|
||||
"technical": "cto"
|
||||
},
|
||||
"projects": {
|
||||
"stack": {
|
||||
"root": "/mnt/storage/scratch/sage-r64/d2/project"
|
||||
}
|
||||
},
|
||||
"vars": {
|
||||
"tracker.baseUrl": "http://127.0.0.1:9",
|
||||
"gitea.baseUrl": "http://127.0.0.1:9"
|
||||
},
|
||||
"tracker": {
|
||||
"sync": {
|
||||
"bot": "bot-mosaic-stack-sync",
|
||||
"botId": 5,
|
||||
"credentials": {
|
||||
"vikunja": {
|
||||
"file": "/mnt/storage/scratch/sage-r64/d2/secrets/sync-vikunja.token",
|
||||
"expires": "2099-01-01"
|
||||
}
|
||||
}
|
||||
},
|
||||
"labels": {}
|
||||
},
|
||||
"roles": {
|
||||
"pm": {
|
||||
"definition": "pm",
|
||||
"holder": "sage",
|
||||
"tracker": {
|
||||
"bot": "bot-mosaic-stack-pm",
|
||||
"botId": 1
|
||||
},
|
||||
"credentials": {
|
||||
"gitea": {
|
||||
"file": "/mnt/storage/scratch/sage-r64/d2/secrets/pm-gitea.token",
|
||||
"rotateBy": "2099-01-01"
|
||||
},
|
||||
"vikunja": {
|
||||
"file": "/mnt/storage/scratch/sage-r64/d2/secrets/pm-vikunja.token",
|
||||
"expires": "2099-01-01"
|
||||
}
|
||||
},
|
||||
"vars": {
|
||||
"model": "opus"
|
||||
}
|
||||
},
|
||||
"cto": {
|
||||
"definition": "cto",
|
||||
"holder": "darkwing",
|
||||
"tracker": {
|
||||
"bot": "bot-mosaic-stack-cto",
|
||||
"botId": 2
|
||||
},
|
||||
"credentials": {
|
||||
"gitea": {
|
||||
"file": "/mnt/storage/scratch/sage-r64/d2/secrets/cto-gitea.token",
|
||||
"rotateBy": "2099-01-01"
|
||||
},
|
||||
"vikunja": {
|
||||
"file": "/mnt/storage/scratch/sage-r64/d2/secrets/cto-vikunja.token",
|
||||
"expires": "2099-01-01"
|
||||
}
|
||||
},
|
||||
"vars": {
|
||||
"model": "opus"
|
||||
}
|
||||
},
|
||||
"coder": {
|
||||
"definition": "coder",
|
||||
"tracker": {
|
||||
"bot": "bot-mosaic-stack-coder",
|
||||
"botId": 3
|
||||
},
|
||||
"credentials": {
|
||||
"gitea": {
|
||||
"file": "/mnt/storage/scratch/sage-r64/d2/secrets/coder-gitea.token",
|
||||
"rotateBy": "2099-01-01"
|
||||
},
|
||||
"vikunja": {
|
||||
"file": "/mnt/storage/scratch/sage-r64/d2/secrets/coder-vikunja.token",
|
||||
"expires": "2099-01-01"
|
||||
}
|
||||
},
|
||||
"vars": {
|
||||
"model": "sonnet",
|
||||
"harness": "pi",
|
||||
"thinking": "medium"
|
||||
}
|
||||
},
|
||||
"reviewer": {
|
||||
"definition": "reviewer",
|
||||
"tracker": {
|
||||
"bot": "bot-mosaic-stack-reviewer",
|
||||
"botId": 4
|
||||
},
|
||||
"credentials": {
|
||||
"gitea": {
|
||||
"file": "/mnt/storage/scratch/sage-r64/d2/secrets/reviewer-gitea.token",
|
||||
"rotateBy": "2099-01-01"
|
||||
},
|
||||
"vikunja": {
|
||||
"file": "/mnt/storage/scratch/sage-r64/d2/secrets/reviewer-vikunja.token",
|
||||
"expires": "2099-01-01"
|
||||
}
|
||||
},
|
||||
"vars": {
|
||||
"model": "opus"
|
||||
}
|
||||
},
|
||||
"chief": {
|
||||
"definition": "chief-of-staff",
|
||||
"vars": {
|
||||
"model": "opus"
|
||||
}
|
||||
},
|
||||
"assistant": {
|
||||
"definition": "assistant",
|
||||
"holder": "mos",
|
||||
"vars": {
|
||||
"model": "opus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"launch": {
|
||||
"by": "chief",
|
||||
"instances": [
|
||||
"coder",
|
||||
"reviewer"
|
||||
],
|
||||
"models": {
|
||||
"opus": {
|
||||
"provider": "anthropic",
|
||||
"model": "claude-opus-5-5"
|
||||
},
|
||||
"sonnet": {
|
||||
"provider": "anthropic",
|
||||
"model": "claude-sonnet-5-5"
|
||||
}
|
||||
},
|
||||
"limits": {
|
||||
"models": {
|
||||
"anthropic": {
|
||||
"claude-opus-5-5": 4,
|
||||
"claude-sonnet-5-5": 4
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"harness": [
|
||||
"pi",
|
||||
"claude-code"
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user