@rubytech/create-maxy-code 0.1.221 → 0.1.222
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +46 -1
- package/package.json +1 -1
- package/payload/platform/lib/graph-write/dist/__tests__/action-provenance-gate.test.js +60 -23
- package/payload/platform/lib/graph-write/dist/__tests__/action-provenance-gate.test.js.map +1 -1
- package/payload/platform/lib/graph-write/dist/index.d.ts +4 -1
- package/payload/platform/lib/graph-write/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/graph-write/dist/index.js +17 -5
- package/payload/platform/lib/graph-write/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-write/src/__tests__/action-provenance-gate.test.ts +58 -31
- package/payload/platform/lib/graph-write/src/index.ts +16 -7
- package/payload/platform/plugins/admin/__tests__/admin-can-enumerate.test.sh +129 -0
- package/payload/platform/plugins/admin/mcp/dist/index.js +39 -7
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/references/publish-site-routing.md +44 -0
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +4 -4
- package/payload/platform/plugins/contacts/PLUGIN.md +2 -2
- package/payload/platform/plugins/docs/references/internals.md +1 -1
- package/payload/platform/plugins/docs/references/platform.md +2 -2
- package/payload/platform/plugins/memory/PLUGIN.md +1 -1
- package/payload/platform/plugins/url-get/mcp/dist/tools/url-get.d.ts +2 -1
- package/payload/platform/plugins/url-get/mcp/dist/tools/url-get.d.ts.map +1 -1
- package/payload/platform/plugins/url-get/mcp/dist/tools/url-get.js +27 -21
- package/payload/platform/plugins/url-get/mcp/dist/tools/url-get.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +13 -0
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts +24 -0
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.js +100 -11
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/specialist-drift.d.ts +8 -0
- package/payload/platform/services/claude-session-manager/dist/specialist-drift.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/specialist-drift.js +7 -2
- package/payload/platform/services/claude-session-manager/dist/specialist-drift.js.map +1 -1
- package/payload/server/public/assets/{AdminShell-BcxEZnpu.js → AdminShell-BiEwDSRL.js} +1 -1
- package/payload/server/public/assets/{Checkbox-DL-HdT29.js → Checkbox-COiFXiXL.js} +1 -1
- package/payload/server/public/assets/{admin-DMo5DWKH.js → admin-Ca9ckLZx.js} +1 -1
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-BoUw4oYz.js → architectureDiagram-Q4EWVU46-DI6JZI13.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-DOscnO3m.js → blockDiagram-DXYQGD6D-dgDvswLd.js} +1 -1
- package/payload/server/public/assets/{brand-SZW-27T7.css → brand-CAMMU5lz.css} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-aZ1IuZ_F.js → c4Diagram-AHTNJAMY-odaGY4GZ.js} +1 -1
- package/payload/server/public/assets/channel-DfwLbKck.js +1 -0
- package/payload/server/public/assets/{chunk-336JU56O-DS3ksXBG.js → chunk-336JU56O-BpbY8F27.js} +2 -2
- package/payload/server/public/assets/{chunk-426QAEUC-BLRn2STO.js → chunk-426QAEUC-BWbVhEVC.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-BrhOvJ01.js → chunk-4TB4RGXK-C3IfRdvA.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-BZZwZX5Q.js → chunk-5FUZZQ4R-CSRMBAGr.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-YXZKnPCz.js → chunk-5PVQY5BW-CGAe6GJJ.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-DAMCJHKQ.js → chunk-EDXVE4YY-BnXC8cYQ.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-DsD95Bqn.js → chunk-ENJZ2VHE-7qfDalAB.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-DxtrRClx.js → chunk-ICPOFSXX-TRvVGIDw.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-CN4kLK-H.js → chunk-OYMX7WX6-Cfv8vBvI.js} +1 -1
- package/payload/server/public/assets/{chunk-U2HBQHQK-BPTv3Oj1.js → chunk-U2HBQHQK-BfLvbEyu.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-DxBry33v.js → chunk-X2U36JSP-Cj3k-dYC.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-BZ4N75oy.js → chunk-YZCP3GAM-CygW6I0h.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-Dqr161Q1.js → chunk-ZZ45TVLE-CBF3hFJH.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-CE0XZQre.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-Bj41Y3XD.js +1 -0
- package/payload/server/public/assets/clone-DTd5nONj.js +1 -0
- package/payload/server/public/assets/{dagre-DtZ0wKkH.js → dagre-BTGABQJX.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-BPKhT-ZX.js → dagre-KV5264BT-B2lbkuGd.js} +1 -1
- package/payload/server/public/assets/{data-D6IQdm0R.js → data-CHdaTjgn.js} +1 -1
- package/payload/server/public/assets/{diagram-5BDNPKRD-CATnafi7.js → diagram-5BDNPKRD-BUK4LqT8.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-ChZYQfji.js → diagram-G4DWMVQ6-e49HrvxL.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-DHW6kYd3.js → diagram-MMDJMWI5-k4Kx_qWe.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-CnS4Zci8.js → diagram-TYMM5635-DzavOUdK.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-DKYv2YWp.js → erDiagram-SMLLAGMA-CJKecRhi.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-BWvoZWlh.js → flowDiagram-DWJPFMVM-GM7H1TDt.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-CpCb-xKy.js → ganttDiagram-T4ZO3ILL-kDEA1A-3.js} +1 -1
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-CvHrDKQ-.js → gitGraphDiagram-UUTBAWPF-jVZZdeg2.js} +1 -1
- package/payload/server/public/assets/{graph-labels-CWJy0O4w.js → graph-labels-CavkO4DG.js} +1 -1
- package/payload/server/public/assets/{graph-PkZKVkWD.js → graph-tqCqSngu.js} +1 -1
- package/payload/server/public/assets/{graphlib-DjnyHqGy.js → graphlib-DFU2rJiY.js} +1 -1
- package/payload/server/public/assets/{infoDiagram-42DDH7IO-D_MywcVn.js → infoDiagram-42DDH7IO-CFxVoRBy.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-N9m-f-Eb.js → ishikawaDiagram-UXIWVN3A-CDvZs3Ua.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-DE0q7uSM.js → journeyDiagram-VCZTEJTY-DUI1m9vW.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-Dj5hb9Bq.js → kanban-definition-6JOO6SKY-C_jSVK7W.js} +1 -1
- package/payload/server/public/assets/{line-C6ph0i4M.js → line-DfwJeo6J.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-BrfmEvCA.js → mermaid-parser.core-BN-2kBfU.js} +1 -1
- package/payload/server/public/assets/{mermaid.core-DYnHKfDv.js → mermaid.core-C6amhHAQ.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-DaSaZfhR.js → mindmap-definition-QFDTVHPH-eTKDlw3c.js} +1 -1
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-BAu9Ezbv.js → pieDiagram-DEJITSTG-DNX5VeMZ.js} +1 -1
- package/payload/server/public/assets/{public-UKgkJxKv.js → public-BADBLzOZ.js} +3 -3
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-DRsbL1Xd.js → quadrantDiagram-34T5L4WZ-BFnmYiHX.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-B9QcsXV6.js → requirementDiagram-MS252O5E-DvHvTyzu.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-DsZbvIlD.js → sankeyDiagram-XADWPNL6-CMFnNT1G.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-BlT4O2N8.js → sequenceDiagram-FGHM5R23-BYon1ouU.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-JFgk1K3Y.js → stateDiagram-FHFEXIEX-n6l3hcuJ.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-CS46-Mhi.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-DOsHw1ip.js → timeline-definition-GMOUNBTQ-DFPFHrQF.js} +1 -1
- package/payload/server/public/assets/{useSelectionMode-JDGvwvIk.js → useSelectionMode-iqIyL24g.js} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-CQWIhqZY.js → vennDiagram-DHZGUBPP-DZLturYa.js} +1 -1
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-D5Fh7YVL.js → wardleyDiagram-NUSXRM2D-BBt2pdjM.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-C-tINQEs.js → xychartDiagram-5P7HB3ND-DOZxLvEi.js} +1 -1
- package/payload/server/public/data.html +5 -5
- package/payload/server/public/graph.html +6 -6
- package/payload/server/public/index.html +6 -6
- package/payload/server/public/public.html +5 -5
- package/payload/server/public/assets/channel-CzcSNxDm.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-DFOM3vCn.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-HplDfaL1.js +0 -1
- package/payload/server/public/assets/clone-G-2rqnSR.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-NXz27DaV.js +0 -1
- /package/payload/server/public/assets/{brand-SzZmKKjz.js → brand-DfykKss4.js} +0 -0
package/dist/index.js
CHANGED
|
@@ -18,7 +18,7 @@ import { classifyPortHolder } from "./preflight-port-classifier.js";
|
|
|
18
18
|
import { parsePluginList, computeInstallActions, computeConfigureActions, parseExternalPlugins, } from "./lib/plugin-install.js";
|
|
19
19
|
import { findPremiumMcpDirs } from "./lib/premium-mcp-discover.js";
|
|
20
20
|
import { pickLanInterface, mergeSmbConf, formatSambaMarker, } from "./samba-provision.js";
|
|
21
|
-
import { networkInterfaces, userInfo } from "node:os";
|
|
21
|
+
import { networkInterfaces, userInfo, homedir } from "node:os";
|
|
22
22
|
const PAYLOAD_DIR = resolve(import.meta.dirname, "../payload");
|
|
23
23
|
// Brand manifest — read from payload to derive all brand-specific installation values.
|
|
24
24
|
// The bundler stamps brand.json into the payload at build time.
|
|
@@ -3276,6 +3276,51 @@ WantedBy=multi-user.target
|
|
|
3276
3276
|
// and fail with EADDRINUSE. Fresh installs: the stop is a no-op.
|
|
3277
3277
|
const unitName = BRAND.serviceName.replace(".service", "");
|
|
3278
3278
|
const claudeSessionManagerUnitShort = claudeSessionManagerUnitName.replace(".service", "");
|
|
3279
|
+
// Task 579 — admin-enumeration acceptance gate. Runs against the
|
|
3280
|
+
// freshly-deployed payload before the systemctl restart cluster so a
|
|
3281
|
+
// regression in the admin tool surface fails the install and keeps
|
|
3282
|
+
// the old service running. The harness exit code is the gate; a
|
|
3283
|
+
// non-zero exit logs the JSONL evidence path to install.log and
|
|
3284
|
+
// process.exit(1) before we touch any unit. Set MAXY_SKIP_ENUMERATE_GATE=1
|
|
3285
|
+
// to bypass for cases where the operator is iterating on a different
|
|
3286
|
+
// surface and accepts the regression risk; absence is the default.
|
|
3287
|
+
if (!process.env.MAXY_SKIP_ENUMERATE_GATE) {
|
|
3288
|
+
const harness = join(INSTALL_DIR, "platform/plugins/admin/__tests__/admin-can-enumerate.test.sh");
|
|
3289
|
+
if (existsSync(harness)) {
|
|
3290
|
+
const brandConfigDir = join(homedir(), BRAND.configDir, ".claude");
|
|
3291
|
+
console.log(" Running admin-enumerate acceptance gate...");
|
|
3292
|
+
const gateResult = spawnSync("bash", [harness], {
|
|
3293
|
+
stdio: "inherit",
|
|
3294
|
+
env: {
|
|
3295
|
+
...process.env,
|
|
3296
|
+
CLAUDE_CONFIG_DIR: brandConfigDir,
|
|
3297
|
+
INSTALL_DIR,
|
|
3298
|
+
},
|
|
3299
|
+
});
|
|
3300
|
+
if (gateResult.status !== 0) {
|
|
3301
|
+
const installLog = join(homedir(), BRAND.configDir, "logs", "install.log");
|
|
3302
|
+
const ts = new Date().toISOString();
|
|
3303
|
+
try {
|
|
3304
|
+
mkdirSync(dirname(installLog), { recursive: true });
|
|
3305
|
+
appendFileSync(installLog, `${ts} [admin-enumerate-gate] FAIL exit=${gateResult.status ?? "null"} — admin seat could not locate seeded site within budget. Payload NOT swapped into systemd.\n`);
|
|
3306
|
+
}
|
|
3307
|
+
catch {
|
|
3308
|
+
// best-effort
|
|
3309
|
+
}
|
|
3310
|
+
console.error(`\n ❌ admin-enumerate gate failed (exit ${gateResult.status ?? "null"}).\n` +
|
|
3311
|
+
` The new payload is on disk at ${INSTALL_DIR} but systemd was NOT restarted.\n` +
|
|
3312
|
+
` Old service is still running. See ${installLog} for one-line summary.\n`);
|
|
3313
|
+
process.exit(1);
|
|
3314
|
+
}
|
|
3315
|
+
console.log(" admin-enumerate gate passed.");
|
|
3316
|
+
}
|
|
3317
|
+
else {
|
|
3318
|
+
console.log(` [admin-enumerate-gate] SKIP reason=harness-not-on-disk path=${harness}`);
|
|
3319
|
+
}
|
|
3320
|
+
}
|
|
3321
|
+
else {
|
|
3322
|
+
console.log(" [admin-enumerate-gate] SKIP reason=MAXY_SKIP_ENUMERATE_GATE=1");
|
|
3323
|
+
}
|
|
3279
3324
|
spawnSync("systemctl", ["--user", "stop", unitName], { stdio: "inherit" });
|
|
3280
3325
|
spawnSync("systemctl", ["--user", "daemon-reload"], { stdio: "inherit" });
|
|
3281
3326
|
spawnSync("systemctl", ["--user", "enable", edgeUnitShort], { stdio: "inherit" });
|
package/package.json
CHANGED
|
@@ -81,7 +81,10 @@ function makeStubSession(opts) {
|
|
|
81
81
|
strict_1.default.ok(index_js_1.ACTION_PROVENANCE_LABELS.has(label), `${label} should be in ACTION_PROVENANCE_LABELS`);
|
|
82
82
|
}
|
|
83
83
|
});
|
|
84
|
-
|
|
84
|
+
// Task 580 relaxed missing-provenance from a hard reject to a soft warn.
|
|
85
|
+
// The write now proceeds; a single structured stderr line carries the labels
|
|
86
|
+
// and agent so operators can quantify how often the gap fires.
|
|
87
|
+
(0, node_test_1.default)("writeNodeWithEdges accepts :Person write missing any inbound PRODUCED edge and emits a warn line", async () => {
|
|
85
88
|
const { session } = makeStubSession({
|
|
86
89
|
preCheckLabelsByTarget: new Map([["other-target", ["LocalBusiness"]]]),
|
|
87
90
|
});
|
|
@@ -89,15 +92,32 @@ function makeStubSession(opts) {
|
|
|
89
92
|
// No inbound PRODUCED at all — neither Task nor Conversation nor Message.
|
|
90
93
|
{ type: "PART_OF", direction: "outgoing", targetNodeId: "other-target" },
|
|
91
94
|
];
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
const captured = [];
|
|
96
|
+
const originalWrite = process.stderr.write.bind(process.stderr);
|
|
97
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
98
|
+
process.stderr.write = ((chunk) => {
|
|
99
|
+
captured.push(typeof chunk === "string" ? chunk : String(chunk));
|
|
100
|
+
return true;
|
|
101
|
+
});
|
|
102
|
+
try {
|
|
103
|
+
const res = await (0, index_js_1.writeNodeWithEdges)({
|
|
104
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
105
|
+
session: session,
|
|
106
|
+
labels: ["Person"],
|
|
107
|
+
props: { accountId: TEST_ACCOUNT_ID },
|
|
108
|
+
relationships,
|
|
109
|
+
createdBy: { agent: "maxy-admin", session: "sess-1", tool: "memory-write" },
|
|
110
|
+
expectedAccountId: TEST_ACCOUNT_ID,
|
|
111
|
+
});
|
|
112
|
+
strict_1.default.equal(res.edgesCreated, 1);
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
process.stderr.write = originalWrite;
|
|
116
|
+
}
|
|
117
|
+
const warnLine = captured.find((l) => l.includes("[graph-write] warn reason=missing-provenance"));
|
|
118
|
+
strict_1.default.ok(warnLine, `expected warn line; captured=${JSON.stringify(captured)}`);
|
|
119
|
+
strict_1.default.match(warnLine, /labels=Person/);
|
|
120
|
+
strict_1.default.match(warnLine, /agent=maxy-admin/);
|
|
101
121
|
});
|
|
102
122
|
(0, node_test_1.default)("writeNodeWithEdges accepts :Person write with PRODUCED-from-Task edge", async () => {
|
|
103
123
|
const { session } = makeStubSession({
|
|
@@ -183,10 +203,12 @@ function makeStubSession(opts) {
|
|
|
183
203
|
});
|
|
184
204
|
strict_1.default.equal(res.edgesCreated, 1);
|
|
185
205
|
});
|
|
186
|
-
//
|
|
187
|
-
//
|
|
188
|
-
//
|
|
189
|
-
|
|
206
|
+
// Defence-in-depth: a PRODUCED edge whose source is not in
|
|
207
|
+
// {Task, Conversation, Message} does not satisfy the gate. Under the
|
|
208
|
+
// Task 580 soft semantics the write still proceeds and the warn line fires —
|
|
209
|
+
// the source-label allowlist now governs whether the write counts as
|
|
210
|
+
// provenance-satisfied for the warn check, not whether it lands.
|
|
211
|
+
(0, node_test_1.default)("writeNodeWithEdges accepts :Person write with PRODUCED edge from a non-provenance-source label and emits a warn line", async () => {
|
|
190
212
|
const { session } = makeStubSession({
|
|
191
213
|
preCheckLabelsByTarget: new Map([
|
|
192
214
|
["business-id", ["LocalBusiness"]],
|
|
@@ -195,15 +217,30 @@ function makeStubSession(opts) {
|
|
|
195
217
|
const relationships = [
|
|
196
218
|
{ type: "PRODUCED", direction: "incoming", targetNodeId: "business-id" },
|
|
197
219
|
];
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
220
|
+
const captured = [];
|
|
221
|
+
const originalWrite = process.stderr.write.bind(process.stderr);
|
|
222
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
223
|
+
process.stderr.write = ((chunk) => {
|
|
224
|
+
captured.push(typeof chunk === "string" ? chunk : String(chunk));
|
|
225
|
+
return true;
|
|
226
|
+
});
|
|
227
|
+
try {
|
|
228
|
+
const res = await (0, index_js_1.writeNodeWithEdges)({
|
|
229
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
230
|
+
session: session,
|
|
231
|
+
labels: ["Person"],
|
|
232
|
+
props: { accountId: TEST_ACCOUNT_ID },
|
|
233
|
+
relationships,
|
|
234
|
+
createdBy: { agent: "maxy-admin", session: "sess-1", tool: "memory-write" },
|
|
235
|
+
expectedAccountId: TEST_ACCOUNT_ID,
|
|
236
|
+
});
|
|
237
|
+
strict_1.default.equal(res.edgesCreated, 1);
|
|
238
|
+
}
|
|
239
|
+
finally {
|
|
240
|
+
process.stderr.write = originalWrite;
|
|
241
|
+
}
|
|
242
|
+
const warnLine = captured.find((l) => l.includes("[graph-write] warn reason=missing-provenance"));
|
|
243
|
+
strict_1.default.ok(warnLine, `expected warn line; captured=${JSON.stringify(captured)}`);
|
|
207
244
|
});
|
|
208
245
|
(0, node_test_1.default)("writeNodeWithEdges accepts non-action-provenance label writes without Task edge", async () => {
|
|
209
246
|
const { session } = makeStubSession({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action-provenance-gate.test.js","sourceRoot":"","sources":["../../src/__tests__/action-provenance-gate.test.ts"],"names":[],"mappings":";;;;;AAAA,0DAA6B;AAC7B,gEAAwC;AACxC,0CAIqB;AAErB,iEAAiE;AACjE,uEAAuE;AACvE,qEAAqE;AACrE,+DAA+D;AAC/D,MAAM,eAAe,GAAG,sCAAsC,CAAC;AAU/D,SAAS,eAAe,CAAC,IAGxB;IACC,MAAM,KAAK,GAA0D,EAAE,CAAC;IACxE,MAAM,EAAE,GAAW;QACjB,KAAK,CAAC,GAAG,CAAC,MAAc,EAAE,SAAkC,EAAE;YAC5D,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YAC/B,IAAI,MAAM,CAAC,QAAQ,CAAC,gDAAgD,CAAC,EAAE,CAAC;gBACtE,MAAM,GAAG,GAAI,MAAM,CAAC,GAAgB,IAAI,EAAE,CAAC;gBAC3C,MAAM,OAAO,GAAG,GAAG;qBAChB,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;qBACnD,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;oBACZ,GAAG,CAAC,KAAa;wBACf,IAAI,KAAK,KAAK,IAAI;4BAAE,OAAO,EAAE,CAAC;wBAC9B,IAAI,KAAK,KAAK,QAAQ;4BAAE,OAAO,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;wBACzE,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,EAAE,CAAC,CAAC;oBAC5C,CAAC;iBACF,CAAC,CAAC,CAAC;gBACN,OAAO,EAAE,OAAO,EAAE,CAAC;YACrB,CAAC;YACD,IAAI,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;gBAClC,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,GAAG,CAAC,KAAa;gCACf,IAAI,KAAK,KAAK,QAAQ;oCAAE,OAAO,gBAAgB,CAAC;gCAChD,IAAI,KAAK,KAAK,YAAY;oCAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;gCAC9C,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,EAAE,CAAC,CAAC;4BAC5C,CAAC;yBACF;qBACF;iBACF,CAAC;YACJ,CAAC;YACD,IAAI,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;gBACvE,OAAO;oBACL,OAAO,EAAE,EAAE;oBACX,OAAO,EAAE;wBACP,QAAQ,EAAE;4BACR,OAAO;gCACL,OAAO,EAAE,oBAAoB,EAAE,IAAI,CAAC,mBAAmB,IAAI,CAAC,EAAE,CAAC;4BACjE,CAAC;yBACF;qBACF;iBACF,CAAC;YACJ,CAAC;YACD,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QACzB,CAAC;KACF,CAAC;IACF,MAAM,OAAO,GAAG;QACd,KAAK,CAAC,YAAY,CAAI,IAAgC;YACpD,OAAO,MAAM,IAAI,CAAC,EAAE,CAAC,CAAC;QACxB,CAAC;KACF,CAAC;IACF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC5B,CAAC;AAED,IAAA,mBAAI,EAAC,sDAAsD,EAAE,GAAG,EAAE;IAChE,KAAK,MAAM,KAAK,IAAI;QAClB,QAAQ;QACR,aAAa;QACb,WAAW;QACX,cAAc;QACd,eAAe;QACf,kBAAkB;QAClB,oBAAoB;KACrB,EAAE,CAAC;QACF,gBAAM,CAAC,EAAE,CACP,mCAAwB,CAAC,GAAG,CAAC,KAAK,CAAC,EACnC,GAAG,KAAK,wCAAwC,CACjD,CAAC;IACJ,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAA,mBAAI,EAAC,
|
|
1
|
+
{"version":3,"file":"action-provenance-gate.test.js","sourceRoot":"","sources":["../../src/__tests__/action-provenance-gate.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -35,7 +35,10 @@ export * from "./conversation-provenance.js";
|
|
|
35
35
|
* hourly [graph-health] signal):
|
|
36
36
|
* - zero relationships → `[graph-write] reject reason=zero-relationships`
|
|
37
37
|
* - unresolved target id → `[graph-write] reject reason=unresolved-target`
|
|
38
|
-
* - missing provenance → `[graph-write]
|
|
38
|
+
* - missing provenance → `[graph-write] warn reason=missing-provenance`
|
|
39
|
+
* (Task 580 — soft warn; write proceeds. Composer-spawned admin sessions
|
|
40
|
+
* inherit a bare env that never carries SESSION_NODE_ID, so the prior
|
|
41
|
+
* hard reject was failing every direct admin write to a gated label.)
|
|
39
42
|
* - removed-feature write → `[graph-write] reject reason=removed-feature`
|
|
40
43
|
* (`:ReviewAlert` and `:Event {actionTool:"review-digest-compose"}` are
|
|
41
44
|
* deleted features; the gate catches doctrine-compliant writers
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,YAAY,CAAC;AAK3B,cAAc,8BAA8B,CAAC;AAE7C
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,YAAY,CAAC;AAK3B,cAAc,8BAA8B,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAEH;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,wBAAwB,EAAE,WAAW,CAAC,MAAM,CAQvD,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,EAAE,WAAW,CAAC,MAAM,CAIvD,CAAC;AAiBH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,UAAU,GAAG,UAAU,CAAC;IACnC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6FAA6F;IAC7F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uFAAuF;IACvF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,4EAA4E;IAC5E,aAAa,EAAE,iBAAiB,EAAE,CAAC;IACnC,SAAS,EAAE,SAAS,CAAC;IACrB;;;;;;;;;;OAUG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,uDAAuD;AACvD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,SAAS,EAAE,SAAS,GACnB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzB;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,eAAe,CAAC,CAqN1B"}
|
|
@@ -60,7 +60,10 @@ __exportStar(require("./conversation-provenance.js"), exports);
|
|
|
60
60
|
* hourly [graph-health] signal):
|
|
61
61
|
* - zero relationships → `[graph-write] reject reason=zero-relationships`
|
|
62
62
|
* - unresolved target id → `[graph-write] reject reason=unresolved-target`
|
|
63
|
-
* - missing provenance → `[graph-write]
|
|
63
|
+
* - missing provenance → `[graph-write] warn reason=missing-provenance`
|
|
64
|
+
* (Task 580 — soft warn; write proceeds. Composer-spawned admin sessions
|
|
65
|
+
* inherit a bare env that never carries SESSION_NODE_ID, so the prior
|
|
66
|
+
* hard reject was failing every direct admin write to a gated label.)
|
|
64
67
|
* - removed-feature write → `[graph-write] reject reason=removed-feature`
|
|
65
68
|
* (`:ReviewAlert` and `:Event {actionTool:"review-digest-compose"}` are
|
|
66
69
|
* deleted features; the gate catches doctrine-compliant writers
|
|
@@ -221,11 +224,20 @@ async function writeNodeWithEdges(params) {
|
|
|
221
224
|
})
|
|
222
225
|
.filter((m) => m !== null);
|
|
223
226
|
if (matched.length === 0) {
|
|
224
|
-
|
|
225
|
-
|
|
227
|
+
// Task 580 relaxed this from a hard reject to a soft warn. The
|
|
228
|
+
// composer-spawned admin path (PRD §6.4) inherits the per-account
|
|
229
|
+
// claude-rc daemon's bare env and never receives SESSION_NODE_ID,
|
|
230
|
+
// so the throw was failing every direct admin contact-create /
|
|
231
|
+
// memory-write for a gated label. Operators retain visibility via
|
|
232
|
+
// this single structured warn line; the audit-stage
|
|
233
|
+
// missing-provenance-warning at audit.ts continues to fire
|
|
234
|
+
// independently for idempotent MERGEs that didn't stamp.
|
|
235
|
+
process.stderr.write(`[graph-write] warn reason=missing-provenance labels=${labelCsv} agent=${agentLabel}\n`);
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
provenanceSourceId = matched[0].rel.targetNodeId;
|
|
239
|
+
provenanceSourceLabel = matched[0].sourceLabel;
|
|
226
240
|
}
|
|
227
|
-
provenanceSourceId = matched[0].rel.targetNodeId;
|
|
228
|
-
provenanceSourceLabel = matched[0].sourceLabel;
|
|
229
241
|
}
|
|
230
242
|
let nodeRes;
|
|
231
243
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -94,7 +94,10 @@ test("ACTION_PROVENANCE_LABELS includes the documented set", () => {
|
|
|
94
94
|
}
|
|
95
95
|
});
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
// Task 580 relaxed missing-provenance from a hard reject to a soft warn.
|
|
98
|
+
// The write now proceeds; a single structured stderr line carries the labels
|
|
99
|
+
// and agent so operators can quantify how often the gap fires.
|
|
100
|
+
test("writeNodeWithEdges accepts :Person write missing any inbound PRODUCED edge and emits a warn line", async () => {
|
|
98
101
|
const { session } = makeStubSession({
|
|
99
102
|
preCheckLabelsByTarget: new Map([["other-target", ["LocalBusiness"]]]),
|
|
100
103
|
});
|
|
@@ -102,19 +105,31 @@ test("writeNodeWithEdges rejects :Person write missing any inbound PRODUCED edge
|
|
|
102
105
|
// No inbound PRODUCED at all — neither Task nor Conversation nor Message.
|
|
103
106
|
{ type: "PART_OF", direction: "outgoing", targetNodeId: "other-target" },
|
|
104
107
|
];
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
108
|
+
const captured: string[] = [];
|
|
109
|
+
const originalWrite = process.stderr.write.bind(process.stderr);
|
|
110
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
111
|
+
process.stderr.write = ((chunk: any) => {
|
|
112
|
+
captured.push(typeof chunk === "string" ? chunk : String(chunk));
|
|
113
|
+
return true;
|
|
114
|
+
}) as typeof process.stderr.write;
|
|
115
|
+
try {
|
|
116
|
+
const res = await writeNodeWithEdges({
|
|
117
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
118
|
+
session: session as any,
|
|
119
|
+
labels: ["Person"],
|
|
120
|
+
props: { accountId: TEST_ACCOUNT_ID },
|
|
121
|
+
relationships,
|
|
122
|
+
createdBy: { agent: "maxy-admin", session: "sess-1", tool: "memory-write" },
|
|
123
|
+
expectedAccountId: TEST_ACCOUNT_ID,
|
|
124
|
+
});
|
|
125
|
+
assert.equal(res.edgesCreated, 1);
|
|
126
|
+
} finally {
|
|
127
|
+
process.stderr.write = originalWrite;
|
|
128
|
+
}
|
|
129
|
+
const warnLine = captured.find((l) => l.includes("[graph-write] warn reason=missing-provenance"));
|
|
130
|
+
assert.ok(warnLine, `expected warn line; captured=${JSON.stringify(captured)}`);
|
|
131
|
+
assert.match(warnLine!, /labels=Person/);
|
|
132
|
+
assert.match(warnLine!, /agent=maxy-admin/);
|
|
118
133
|
});
|
|
119
134
|
|
|
120
135
|
test("writeNodeWithEdges accepts :Person write with PRODUCED-from-Task edge", async () => {
|
|
@@ -205,10 +220,12 @@ test("writeNodeWithEdges accepts :Person write with PRODUCED-from-Message edge",
|
|
|
205
220
|
assert.equal(res.edgesCreated, 1);
|
|
206
221
|
});
|
|
207
222
|
|
|
208
|
-
//
|
|
209
|
-
//
|
|
210
|
-
//
|
|
211
|
-
|
|
223
|
+
// Defence-in-depth: a PRODUCED edge whose source is not in
|
|
224
|
+
// {Task, Conversation, Message} does not satisfy the gate. Under the
|
|
225
|
+
// Task 580 soft semantics the write still proceeds and the warn line fires —
|
|
226
|
+
// the source-label allowlist now governs whether the write counts as
|
|
227
|
+
// provenance-satisfied for the warn check, not whether it lands.
|
|
228
|
+
test("writeNodeWithEdges accepts :Person write with PRODUCED edge from a non-provenance-source label and emits a warn line", async () => {
|
|
212
229
|
const { session } = makeStubSession({
|
|
213
230
|
preCheckLabelsByTarget: new Map([
|
|
214
231
|
["business-id", ["LocalBusiness"]],
|
|
@@ -217,19 +234,29 @@ test("writeNodeWithEdges rejects :Person write with PRODUCED edge from a non-pro
|
|
|
217
234
|
const relationships: GraphRelationship[] = [
|
|
218
235
|
{ type: "PRODUCED", direction: "incoming", targetNodeId: "business-id" },
|
|
219
236
|
];
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
237
|
+
const captured: string[] = [];
|
|
238
|
+
const originalWrite = process.stderr.write.bind(process.stderr);
|
|
239
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
240
|
+
process.stderr.write = ((chunk: any) => {
|
|
241
|
+
captured.push(typeof chunk === "string" ? chunk : String(chunk));
|
|
242
|
+
return true;
|
|
243
|
+
}) as typeof process.stderr.write;
|
|
244
|
+
try {
|
|
245
|
+
const res = await writeNodeWithEdges({
|
|
246
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
247
|
+
session: session as any,
|
|
248
|
+
labels: ["Person"],
|
|
249
|
+
props: { accountId: TEST_ACCOUNT_ID },
|
|
250
|
+
relationships,
|
|
251
|
+
createdBy: { agent: "maxy-admin", session: "sess-1", tool: "memory-write" },
|
|
252
|
+
expectedAccountId: TEST_ACCOUNT_ID,
|
|
253
|
+
});
|
|
254
|
+
assert.equal(res.edgesCreated, 1);
|
|
255
|
+
} finally {
|
|
256
|
+
process.stderr.write = originalWrite;
|
|
257
|
+
}
|
|
258
|
+
const warnLine = captured.find((l) => l.includes("[graph-write] warn reason=missing-provenance"));
|
|
259
|
+
assert.ok(warnLine, `expected warn line; captured=${JSON.stringify(captured)}`);
|
|
233
260
|
});
|
|
234
261
|
|
|
235
262
|
test("writeNodeWithEdges accepts non-action-provenance label writes without Task edge", async () => {
|
|
@@ -43,7 +43,10 @@ export * from "./conversation-provenance.js";
|
|
|
43
43
|
* hourly [graph-health] signal):
|
|
44
44
|
* - zero relationships → `[graph-write] reject reason=zero-relationships`
|
|
45
45
|
* - unresolved target id → `[graph-write] reject reason=unresolved-target`
|
|
46
|
-
* - missing provenance → `[graph-write]
|
|
46
|
+
* - missing provenance → `[graph-write] warn reason=missing-provenance`
|
|
47
|
+
* (Task 580 — soft warn; write proceeds. Composer-spawned admin sessions
|
|
48
|
+
* inherit a bare env that never carries SESSION_NODE_ID, so the prior
|
|
49
|
+
* hard reject was failing every direct admin write to a gated label.)
|
|
47
50
|
* - removed-feature write → `[graph-write] reject reason=removed-feature`
|
|
48
51
|
* (`:ReviewAlert` and `:Event {actionTool:"review-digest-compose"}` are
|
|
49
52
|
* deleted features; the gate catches doctrine-compliant writers
|
|
@@ -296,15 +299,21 @@ export async function writeNodeWithEdges(
|
|
|
296
299
|
})
|
|
297
300
|
.filter((m): m is { rel: GraphRelationship; sourceLabel: string } => m !== null);
|
|
298
301
|
if (matched.length === 0) {
|
|
302
|
+
// Task 580 relaxed this from a hard reject to a soft warn. The
|
|
303
|
+
// composer-spawned admin path (PRD §6.4) inherits the per-account
|
|
304
|
+
// claude-rc daemon's bare env and never receives SESSION_NODE_ID,
|
|
305
|
+
// so the throw was failing every direct admin contact-create /
|
|
306
|
+
// memory-write for a gated label. Operators retain visibility via
|
|
307
|
+
// this single structured warn line; the audit-stage
|
|
308
|
+
// missing-provenance-warning at audit.ts continues to fire
|
|
309
|
+
// independently for idempotent MERGEs that didn't stamp.
|
|
299
310
|
process.stderr.write(
|
|
300
|
-
`[graph-write]
|
|
301
|
-
);
|
|
302
|
-
throw new Error(
|
|
303
|
-
`missing-provenance: write to ${labelCsv} requires an inbound :PRODUCED edge from a :Task, :Conversation, or :Message (createdBy.agent='${agentLabel}'). Either pass producedByTaskId on the write (autonomous workflows: call work-create at the start of the flow and thread the returned taskId), or rely on the MCP wrapper's SESSION_NODE_ID env-stamp injection (direct admin asks).`
|
|
311
|
+
`[graph-write] warn reason=missing-provenance labels=${labelCsv} agent=${agentLabel}\n`
|
|
304
312
|
);
|
|
313
|
+
} else {
|
|
314
|
+
provenanceSourceId = matched[0].rel.targetNodeId;
|
|
315
|
+
provenanceSourceLabel = matched[0].sourceLabel;
|
|
305
316
|
}
|
|
306
|
-
provenanceSourceId = matched[0].rel.targetNodeId;
|
|
307
|
-
provenanceSourceLabel = matched[0].sourceLabel;
|
|
308
317
|
}
|
|
309
318
|
|
|
310
319
|
let nodeRes;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# admin-can-enumerate.test.sh
|
|
3
|
+
#
|
|
4
|
+
# Acceptance gate for Task 579. Verifies that a fresh admin session
|
|
5
|
+
# locates a file under <accountDir>/sites/ on the FIRST enumeration
|
|
6
|
+
# attempt — no slug guessing, no `EISDIR`, no false-empty 200s, no
|
|
7
|
+
# "Log directory does not exist" against a path that resolves
|
|
8
|
+
# elsewhere. The gate runs from the installer post-install step against
|
|
9
|
+
# the freshly-deployed payload, before systemd services are restarted
|
|
10
|
+
# into it. A non-zero exit aborts the deploy and the old payload keeps
|
|
11
|
+
# running.
|
|
12
|
+
#
|
|
13
|
+
# Required environment:
|
|
14
|
+
# CLAUDE_CONFIG_DIR per-brand .claude directory (e.g. ~/.realagent-code/.claude)
|
|
15
|
+
# INSTALL_DIR the brand install root (e.g. ~/realagent-code)
|
|
16
|
+
#
|
|
17
|
+
# Exit codes:
|
|
18
|
+
# 0 pass — admin enumerated and emitted the seeded path within budget
|
|
19
|
+
# 1 fail — one or more assertions tripped (see stderr for the line)
|
|
20
|
+
# 2 setup error — could not seed test account or could not invoke claude
|
|
21
|
+
|
|
22
|
+
set -euo pipefail
|
|
23
|
+
|
|
24
|
+
CONFIG_DIR="${CLAUDE_CONFIG_DIR:?CLAUDE_CONFIG_DIR not set}"
|
|
25
|
+
INSTALL_DIR="${INSTALL_DIR:?INSTALL_DIR not set}"
|
|
26
|
+
|
|
27
|
+
if ! command -v claude >/dev/null 2>&1; then
|
|
28
|
+
echo "[admin-enumerate-gate] setup-error reason=claude-not-on-path" >&2
|
|
29
|
+
exit 2
|
|
30
|
+
fi
|
|
31
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
32
|
+
echo "[admin-enumerate-gate] setup-error reason=jq-not-on-path" >&2
|
|
33
|
+
exit 2
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
ACCOUNTS_DIR="$INSTALL_DIR/data/accounts"
|
|
37
|
+
TEST_ACCT_ID="enumerate-gate-$$"
|
|
38
|
+
TEST_ACCT_DIR="$ACCOUNTS_DIR/$TEST_ACCT_ID"
|
|
39
|
+
JSONL_OUT=$(mktemp)
|
|
40
|
+
EXIT=0
|
|
41
|
+
|
|
42
|
+
cleanup() {
|
|
43
|
+
rm -rf "$TEST_ACCT_DIR"
|
|
44
|
+
if [ "$EXIT" -eq 0 ]; then
|
|
45
|
+
rm -f "$JSONL_OUT"
|
|
46
|
+
else
|
|
47
|
+
echo "[admin-enumerate-gate] evidence-jsonl=$JSONL_OUT" >&2
|
|
48
|
+
fi
|
|
49
|
+
}
|
|
50
|
+
trap cleanup EXIT
|
|
51
|
+
|
|
52
|
+
# Seed: one target site + 5 decoys. Target index.html is the file the
|
|
53
|
+
# agent must locate and emit the absolute path for.
|
|
54
|
+
mkdir -p "$TEST_ACCT_DIR/sites/exp-uk-got-talent"
|
|
55
|
+
echo "<html><body>eXp Has Got Talent</body></html>" > "$TEST_ACCT_DIR/sites/exp-uk-got-talent/index.html"
|
|
56
|
+
for decoy in alpha-corp-careers beta-properties gamma-events delta-news epsilon-portal; do
|
|
57
|
+
mkdir -p "$TEST_ACCT_DIR/sites/$decoy"
|
|
58
|
+
echo "<html>decoy</html>" > "$TEST_ACCT_DIR/sites/$decoy/index.html"
|
|
59
|
+
done
|
|
60
|
+
|
|
61
|
+
TARGET_PATH="$TEST_ACCT_DIR/sites/exp-uk-got-talent/index.html"
|
|
62
|
+
|
|
63
|
+
PROMPT="find the eXp Has Got Talent site in this account and print the absolute path to its index.html"
|
|
64
|
+
|
|
65
|
+
# Spawn claude headless against the test account. ACCOUNT_ID + the
|
|
66
|
+
# MAXY_SESSION_ROLE/PLATFORM_ROOT env are what the platform MCPs read
|
|
67
|
+
# to scope themselves; PLATFORM_ROOT resolves the on-disk payload that
|
|
68
|
+
# was just deployed. JSONL goes to a file we parse below.
|
|
69
|
+
ACCOUNT_ID="$TEST_ACCT_ID" \
|
|
70
|
+
MAXY_SESSION_ROLE="admin" \
|
|
71
|
+
PLATFORM_ROOT="$INSTALL_DIR/platform" \
|
|
72
|
+
CLAUDE_CONFIG_DIR="$CONFIG_DIR" \
|
|
73
|
+
claude -p "$PROMPT" --output-format=stream-json --verbose \
|
|
74
|
+
> "$JSONL_OUT" 2>&1 \
|
|
75
|
+
|| { echo "[admin-enumerate-gate] setup-error reason=claude-spawn-failed exit=$?" >&2; EXIT=2; exit 2; }
|
|
76
|
+
|
|
77
|
+
fail() {
|
|
78
|
+
echo "[admin-enumerate-gate] FAIL $1" >&2
|
|
79
|
+
EXIT=1
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
# Assertion 1: the target path appears verbatim in some assistant turn
|
|
83
|
+
# or tool-use input. Either as the agent's final message or as an arg
|
|
84
|
+
# passed to a tool.
|
|
85
|
+
if ! grep -F -q "$TARGET_PATH" "$JSONL_OUT"; then
|
|
86
|
+
fail "correct-path-not-emitted target=$TARGET_PATH"
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
# Assertion 2: zero forbidden error patterns from the surfaces this
|
|
90
|
+
# task fixed.
|
|
91
|
+
FORBIDDEN_HITS=$(grep -E -c "EISDIR|Log directory does not exist|Plugin file not found|page has no readable text content" "$JSONL_OUT" || true)
|
|
92
|
+
if [ "${FORBIDDEN_HITS:-0}" -gt 0 ]; then
|
|
93
|
+
fail "forbidden-error-patterns=$FORBIDDEN_HITS"
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
# Assertion 3: total tool-use calls from the user prompt to the
|
|
97
|
+
# correct-path emission are at most 3. The earlier failing run issued
|
|
98
|
+
# ~15.
|
|
99
|
+
TOOL_USE_COUNT=$(jq -r 'select(.type=="assistant") | .message.content[]? | select(.type=="tool_use") | .name' < "$JSONL_OUT" 2>/dev/null | wc -l | tr -d ' ' || echo 0)
|
|
100
|
+
if [ "${TOOL_USE_COUNT:-0}" -gt 3 ]; then
|
|
101
|
+
fail "tool-use-budget-exceeded count=$TOOL_USE_COUNT cap=3"
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
# Assertion 4: the FIRST disk-listing tool call returns an enumeration
|
|
105
|
+
# of <accountDir>/sites/. "Disk-listing" means LS, Glob, or Bash with
|
|
106
|
+
# `ls`. We accept any of those as the first relevant call; what we
|
|
107
|
+
# reject is a Read against a directory path.
|
|
108
|
+
FIRST_DIR_TOOL=$(jq -r 'select(.type=="assistant") | .message.content[]? | select(.type=="tool_use") | {name, input} | @json' < "$JSONL_OUT" 2>/dev/null \
|
|
109
|
+
| jq -r 'select(.name=="LS" or .name=="Glob" or (.name=="Bash" and (.input.command // "" | test("\\bls\\b")))) | .name' \
|
|
110
|
+
| head -1)
|
|
111
|
+
if [ -z "$FIRST_DIR_TOOL" ]; then
|
|
112
|
+
fail "no-disk-listing-tool-call-emitted"
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
# Assertion 5: no Read tool call against a path under <accountDir>/sites/
|
|
116
|
+
# that is a directory (would have produced EISDIR pre-fix; should not
|
|
117
|
+
# even be attempted now).
|
|
118
|
+
BAD_READ=$(jq -r 'select(.type=="assistant") | .message.content[]? | select(.type=="tool_use" and .name=="Read") | .input.file_path // ""' < "$JSONL_OUT" 2>/dev/null \
|
|
119
|
+
| while read -r p; do
|
|
120
|
+
[ -n "$p" ] && [ -d "$p" ] && echo "$p"
|
|
121
|
+
done | head -1)
|
|
122
|
+
if [ -n "$BAD_READ" ]; then
|
|
123
|
+
fail "read-against-directory path=$BAD_READ"
|
|
124
|
+
fi
|
|
125
|
+
|
|
126
|
+
if [ "$EXIT" -eq 0 ]; then
|
|
127
|
+
echo "[admin-enumerate-gate] PASS target=$TARGET_PATH tool-use-count=$TOOL_USE_COUNT first-dir-tool=$FIRST_DIR_TOOL"
|
|
128
|
+
fi
|
|
129
|
+
exit "$EXIT"
|