@archstone/cli
Advanced tools
+42
-12
@@ -621,3 +621,3 @@ #!/usr/bin/env node | ||
| } | ||
| if (bound && !tool.contract) { | ||
| if (bound && !tool.contract && tool.effect === "read") { | ||
| add({ | ||
@@ -631,2 +631,14 @@ severity: "warning", | ||
| } | ||
| if (bound && !tool.contract && tool.effect !== "read") { | ||
| add({ | ||
| // `advisory`, not `warning`: on a `write`/`irreversible` capability, having no contract | ||
| // fixture is now the CORRECT state, not a gap to close. `warning` would keep asking for | ||
| // the thing this advisory exists to stop recommending. | ||
| severity: "advisory", | ||
| code: "no-contract-non-read", | ||
| capability: tool.id, | ||
| message: `bound and \`${tool.effect}\`, so it records no contract fixture \u2014 and should not`, | ||
| because: "`archstone verify` replays a recorded fixture as a real invocation, so a fixture here would repeat this capability's effect against the live backend on every CI run. `verify` skips it by default for that reason. Where this capability has a `read` counterpart, cover the drift with that instead \u2014 the quote half of a quote \u2192 commit pair hits the same host, auth and serialization at zero risk. Not every write has one, and Archstone cannot tell you which capability it is: nothing in CDL declares that relationship. Only if this binding's `${VAR}` genuinely resolves to a sandbox tenant is recording one worthwhile, replayed with `archstone verify --sandbox`: the flag re-includes the binding, it does not make the backend safe." | ||
| }); | ||
| } | ||
| if (tool.contract?.probeFixture) { | ||
@@ -677,3 +689,9 @@ const fixture = join2(manifestDir, tool.contract.probeFixture); | ||
| message: "is declared `irreversible`", | ||
| because: "No API description states this, so it was a human judgement: an agent must confirm explicitly and must never auto-retry. Re-read it before go-live \u2014 `irreversible` is the difference between looking up a price and charging a card." | ||
| because: ( | ||
| // #125 (ADD-124 D-12) appends the last sentence — code and severity unchanged. Without | ||
| // it, this advisory and the contract advisory above land on the same capability saying | ||
| // opposite things ("never auto-retry" vs "wire it into CI"). Naming `verify`'s default | ||
| // here is what makes the two agree wherever a reader starts. | ||
| "No API description states this, so it was a human judgement: an agent must confirm explicitly and must never auto-retry. Re-read it before go-live \u2014 `irreversible` is the difference between looking up a price and charging a card. `archstone verify` applies the same judgement: it will not replay this capability's fixture against the live backend unless you assert a sandbox with --sandbox." | ||
| ) | ||
| }); | ||
@@ -1043,3 +1061,3 @@ } | ||
| // which is exactly how it came to be missing from the one line a user actually scans. | ||
| "usage: archstone <apply|serve|verify|build|doctor|init|adopt|audit>\n\n archstone <apply|serve|verify|build> <manifest-dir> [--json] [--out path]\n archstone serve --http <manifest-dir> [--port <n>] [--token <value>]\n bearer token: --token <value>, or the ARCHSTONE_HTTP_TOKEN env var (required \u2014 never serves open)\n archstone doctor <manifest-dir> [--json] \u2014 pre-production checks, offline\n archstone init <spec-file> --out <dir> \u2014 start here if you have no manifest yet\n archstone adopt <manifest-dir>\n declare a field the backend started returning; asks before writing, needs a person\n\n archstone audit <file...> [--since <date>] [--format summary|jsonl|csv]\n read your own Execution audit records; nothing is uploaded (audit --help for filters)\n\n archstone --version | --help\n\n" + INIT_USAGE | ||
| "usage: archstone <apply|serve|verify|build|doctor|init|adopt|audit>\n\n archstone <apply|serve|verify|build> <manifest-dir> [--json] [--out path]\n archstone verify <manifest-dir> [--json] [--sandbox]\n --sandbox: also replay `write`/`irreversible` fixtures \u2014 they are skipped by default,\n because a replay is a real invocation. Only for a backend you know is a sandbox tenant.\n archstone serve --http <manifest-dir> [--port <n>] [--token <value>]\n bearer token: --token <value>, or the ARCHSTONE_HTTP_TOKEN env var (required \u2014 never serves open)\n archstone doctor <manifest-dir> [--json] \u2014 pre-production checks, offline\n archstone init <spec-file> --out <dir> \u2014 start here if you have no manifest yet\n archstone adopt <manifest-dir>\n declare a field the backend started returning; asks before writing, needs a person\n\n archstone audit <file...> [--since <date>] [--format summary|jsonl|csv]\n read your own Execution audit records; nothing is uploaded (audit --help for filters)\n\n archstone --version | --help\n\n" + INIT_USAGE | ||
| ); | ||
@@ -1216,3 +1234,5 @@ } | ||
| var HEALTH_ICON = { green: "\u{1F7E2}", yellow: "\u{1F7E1}", red: "\u{1F534}" }; | ||
| async function runVerifyCmd(dir, json) { | ||
| var SKIP_ICON = "\u23ED"; | ||
| var READ_TWIN_TIP = " Where one of these has a `read` capability against the same backend \u2014 the quote half of a\n quote \u2192 commit pair \u2014 verifying that instead hits the same host, auth and serialization,\n catching most infrastructure and schema drift at zero risk. Not every write has one, and\n Archstone cannot tell you which capability it is: nothing in CDL declares that relationship.\n If this backend really is a sandbox tenant, pass --sandbox."; | ||
| async function runVerifyCmd(dir, json, sandbox) { | ||
| const res = load2(dir); | ||
@@ -1231,6 +1251,7 @@ const diags = validateSemantics2(res); | ||
| const registry = new Registry2(compile2(res)); | ||
| const reports = await runVerify(registry.listCapabilities(), dir, registry.ir.resources); | ||
| const { results, skipped } = sandbox ? await runVerify(registry.listCapabilities(), dir, registry.ir.resources, void 0, { includeNonRead: true }) : await runVerify(registry.listCapabilities(), dir, registry.ir.resources); | ||
| const exitCode = results.some((r) => r.status === "red") ? 1 : 0; | ||
| if (json) { | ||
| console.log(JSON.stringify({ results: reports })); | ||
| process.exit(reports.some((r) => r.status === "red") ? 1 : 0); | ||
| console.log(JSON.stringify({ results, skipped, sandbox })); | ||
| process.exit(exitCode); | ||
| } | ||
@@ -1240,11 +1261,19 @@ console.log(` | ||
| `); | ||
| if (reports.length === 0) { | ||
| if (results.length === 0 && skipped.length === 0) { | ||
| console.log(" (no bindings declare a contract: \u2014 nothing to verify)\n"); | ||
| process.exit(0); | ||
| } | ||
| for (const r of reports) { | ||
| for (const r of results) { | ||
| console.log(` ${HEALTH_ICON[r.status]} ${r.capabilityId} \u2014 ${r.detail}`); | ||
| } | ||
| for (const s of skipped) { | ||
| console.log(` ${SKIP_ICON} ${s.capabilityId} \u2014 ${s.detail}`); | ||
| } | ||
| if (skipped.length > 0) { | ||
| console.log(` | ||
| ${skipped.length} binding(s) were NOT verified against the backend.`); | ||
| console.log(READ_TWIN_TIP); | ||
| } | ||
| console.log(""); | ||
| process.exit(reports.some((r) => r.status === "red") ? 1 : 0); | ||
| process.exit(exitCode); | ||
| } | ||
@@ -1282,2 +1311,3 @@ function flagArg(argv, name) { | ||
| const http = argv.includes("--http"); | ||
| const sandbox = argv.includes("--sandbox"); | ||
| const out = flagArg(argv, "--out"); | ||
@@ -1293,3 +1323,3 @@ const port = flagArg(argv, "--port"); | ||
| } | ||
| const positional = argv.filter((a, i) => !consumed.has(i) && a !== "--json" && a !== "--http"); | ||
| const positional = argv.filter((a, i) => !consumed.has(i) && a !== "--json" && a !== "--http" && a !== "--sandbox"); | ||
| const [cmd, dir] = positional; | ||
@@ -1309,3 +1339,3 @@ if (cmd === "apply" && dir) { | ||
| if (cmd === "verify" && dir) { | ||
| await runVerifyCmd(dir, json); | ||
| await runVerifyCmd(dir, json, sandbox); | ||
| return; | ||
@@ -1312,0 +1342,0 @@ } |
+6
-6
| { | ||
| "name": "@archstone/cli", | ||
| "version": "0.14.0", | ||
| "version": "0.15.0", | ||
| "private": false, | ||
@@ -40,7 +40,7 @@ "type": "module", | ||
| "dependencies": { | ||
| "@archstone/compiler": "0.14.0", | ||
| "@archstone/emitter-support": "0.14.0", | ||
| "@archstone/init": "0.14.0", | ||
| "@archstone/runtime": "0.14.0", | ||
| "@archstone/schema": "0.14.0" | ||
| "@archstone/emitter-support": "0.15.0", | ||
| "@archstone/init": "0.15.0", | ||
| "@archstone/compiler": "0.15.0", | ||
| "@archstone/runtime": "0.15.0", | ||
| "@archstone/schema": "0.15.0" | ||
| }, | ||
@@ -47,0 +47,0 @@ "devDependencies": { |
Sorry, the diff of this file is too big to display
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
224756
5.01%1351
2.66%10
11.11%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated
Updated
Updated