Add public CLI-first acceptance gate
This commit is contained in:
parent
afaf918973
commit
4b323224b2
6 changed files with 143 additions and 7 deletions
73
scripts/acceptance-cli-first.sh
Executable file
73
scripts/acceptance-cli-first.sh
Executable file
|
|
@ -0,0 +1,73 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
repo="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "$repo"
|
||||
|
||||
if [[ "${DISASMER_PUBLIC_RELEASE_DRYRUN_E2E:-}" == "1" ]]; then
|
||||
echo "CLI-first acceptance does not run final public-release e2e; unset DISASMER_PUBLIC_RELEASE_DRYRUN_E2E" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${DISASMER_PUBLIC_RELEASE_DRYRUN_FINAL:-}" == "1" ]]; then
|
||||
echo "CLI-first acceptance does not run final public-release evidence; unset DISASMER_PUBLIC_RELEASE_DRYRUN_FINAL" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
node scripts/acceptance-report.js cli-first
|
||||
node scripts/cli-first-contract-smoke.js
|
||||
node scripts/acceptance-report-smoke.js
|
||||
node scripts/acceptance-doc-contract-smoke.js
|
||||
node scripts/acceptance-environment-contract-smoke.js
|
||||
node scripts/acceptance-evidence-contract-smoke.js
|
||||
node scripts/public-private-boundary-smoke.js
|
||||
node scripts/release-blocker-smoke.js
|
||||
node scripts/resource-metering-contract-smoke.js
|
||||
node scripts/hostile-input-contract-smoke.js
|
||||
node scripts/tenant-isolation-contract-smoke.js
|
||||
node scripts/public-story-contract-smoke.js
|
||||
node scripts/public-release-dryrun-contract-smoke.js
|
||||
node scripts/public-browser-login-contract-smoke.js
|
||||
node scripts/self-hosted-coordinator-smoke.js
|
||||
node scripts/public-local-demo-matrix-smoke.js
|
||||
scripts/release-source-scan.sh
|
||||
|
||||
if [[ "${DISASMER_CLI_FIRST_PREPARE_PUBLIC_RELEASE:-1}" == "1" ]]; then
|
||||
node scripts/prepare-public-release-dryrun.js
|
||||
fi
|
||||
|
||||
cargo fmt --all --check
|
||||
cargo test --workspace
|
||||
cargo build --workspace --bins
|
||||
|
||||
node scripts/docs-smoke.js
|
||||
node scripts/cli-output-mode-smoke.js
|
||||
node scripts/cli-login-smoke.js
|
||||
node scripts/cli-error-exit-smoke.js
|
||||
node scripts/cli-browser-login-flow-smoke.js
|
||||
node scripts/cli-install-smoke.js
|
||||
node scripts/user-session-token-boundary-smoke.js
|
||||
node scripts/sdk-spawn-runtime-smoke.js
|
||||
node scripts/node-lifecycle-contract-smoke.js
|
||||
node scripts/wasmtime-node-smoke.js
|
||||
node scripts/podman-backend-smoke.js
|
||||
node scripts/vscode-extension-smoke.js
|
||||
node scripts/vscode-f5-smoke.js
|
||||
node scripts/node-attach-smoke.js
|
||||
node scripts/local-services-smoke.js
|
||||
node scripts/cancellation-smoke.js
|
||||
node scripts/cli-local-run-smoke.js
|
||||
node scripts/artifact-download-smoke.js
|
||||
node scripts/artifact-export-smoke.js
|
||||
node scripts/operator-panel-smoke.js
|
||||
node scripts/source-preparation-smoke.js
|
||||
node scripts/scheduler-placement-smoke.js
|
||||
node scripts/windows-best-effort-smoke.js
|
||||
node scripts/windows-validation-contract-smoke.js
|
||||
node scripts/quic-smoke.js
|
||||
node scripts/dap-smoke.js
|
||||
node scripts/flagship-demo-smoke.js
|
||||
|
||||
if [[ "${DISASMER_CLI_FIRST_INCLUDE_PRIVATE:-0}" == "1" ]]; then
|
||||
scripts/acceptance-private.sh
|
||||
fi
|
||||
|
|
@ -35,10 +35,12 @@ function assertNoOpenCriteria(source, name) {
|
|||
|
||||
const phase2 = read("acceptance_criteria_phase2.md");
|
||||
const base = read("acceptance_criteria.md");
|
||||
const cliFirst = read("cli_acceptance_criteria.md");
|
||||
const docsSmoke = read("scripts/docs-smoke.js");
|
||||
const releaseBlockerSmoke = read("scripts/release-blocker-smoke.js");
|
||||
const publicAcceptance = read("scripts/acceptance-public.sh");
|
||||
const privateAcceptance = read("scripts/acceptance-private.sh");
|
||||
const cliFirstAcceptance = read("scripts/acceptance-cli-first.sh");
|
||||
const publicSplit = read("scripts/verify-public-split.sh");
|
||||
|
||||
assert.match(
|
||||
|
|
@ -60,12 +62,13 @@ assert.match(
|
|||
for (const [source, name] of [
|
||||
[base, "acceptance_criteria.md"],
|
||||
[phase2, "acceptance_criteria_phase2.md"],
|
||||
[cliFirst, "cli_acceptance_criteria.md"],
|
||||
]) {
|
||||
assertEveryCriterionHasStatus(source, name);
|
||||
assertNoOpenCriteria(source, name);
|
||||
}
|
||||
|
||||
for (const file of ["MVP.md", "acceptance_criteria.md", "acceptance_criteria_phase2.md"]) {
|
||||
for (const file of ["MVP.md", "acceptance_criteria.md", "acceptance_criteria_phase2.md", "cli_acceptance_criteria.md"]) {
|
||||
assert(
|
||||
docsSmoke.includes(`"${file}"`),
|
||||
`docs smoke must include ${file} as user-facing acceptance context`
|
||||
|
|
@ -100,6 +103,7 @@ for (const [source, name] of [
|
|||
for (const [scriptName, script] of [
|
||||
["public acceptance", publicAcceptance],
|
||||
["private acceptance", privateAcceptance],
|
||||
["CLI-first acceptance", cliFirstAcceptance],
|
||||
["public split", publicSplit],
|
||||
]) {
|
||||
assert(
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ function expect(source, name, pattern) {
|
|||
const criteria = read("cli_acceptance_criteria.md");
|
||||
const cli = read("crates/disasmer-cli/src/main.rs");
|
||||
const coordinator = read("crates/disasmer-coordinator/src/service.rs");
|
||||
const cliFirstAcceptance = read("scripts/acceptance-cli-first.sh");
|
||||
const outputModeSmoke = read("scripts/cli-output-mode-smoke.js");
|
||||
const errorExitSmoke = read("scripts/cli-error-exit-smoke.js");
|
||||
|
||||
|
|
@ -71,10 +72,64 @@ for (const line of lines) {
|
|||
const openCriteria = lines.filter((line) => /\*\*Open(?::| \()/.test(line));
|
||||
assert.deepStrictEqual(
|
||||
openCriteria,
|
||||
[
|
||||
"- [ ] **Open:** Every criterion in this document is validated end-to-end or with integration-style coverage, preferably against a realistic NixOS deployment that can pretend to be live hosted infrastructure.",
|
||||
],
|
||||
"only the full CLI-first verification gate should remain Open while command/API facts are Partial"
|
||||
[],
|
||||
"CLI-first criteria should not leave Open items once the non-e2e gate exists; remaining unfinished facts stay Partial"
|
||||
);
|
||||
|
||||
expect(
|
||||
criteria,
|
||||
"CLI-first non-e2e gate wording",
|
||||
/scripts\/acceptance-cli-first\.sh[\s\S]*final public-release e2e remains intentionally excluded/
|
||||
);
|
||||
expect(
|
||||
cliFirstAcceptance,
|
||||
"CLI-first acceptance report",
|
||||
/node scripts\/acceptance-report\.js cli-first/
|
||||
);
|
||||
expect(
|
||||
cliFirstAcceptance,
|
||||
"CLI-first acceptance refuses final e2e",
|
||||
/DISASMER_PUBLIC_RELEASE_DRYRUN_E2E[\s\S]*does not run final public-release e2e/
|
||||
);
|
||||
expect(
|
||||
cliFirstAcceptance,
|
||||
"CLI-first acceptance refuses final evidence",
|
||||
/DISASMER_PUBLIC_RELEASE_DRYRUN_FINAL[\s\S]*does not run final public-release evidence/
|
||||
);
|
||||
expect(
|
||||
cliFirstAcceptance,
|
||||
"CLI-first acceptance composes public API contracts",
|
||||
/node scripts\/cli-output-mode-smoke\.js[\s\S]*node scripts\/cli-login-smoke\.js[\s\S]*node scripts\/cli-error-exit-smoke\.js[\s\S]*node scripts\/cli-browser-login-flow-smoke\.js/
|
||||
);
|
||||
expect(
|
||||
cliFirstAcceptance,
|
||||
"CLI-first acceptance composes service boundary checks",
|
||||
/node scripts\/local-services-smoke\.js[\s\S]*node scripts\/cli-local-run-smoke\.js/
|
||||
);
|
||||
expect(
|
||||
cliFirstAcceptance,
|
||||
"CLI-first acceptance composes self-hosted checks",
|
||||
/node scripts\/self-hosted-coordinator-smoke\.js/
|
||||
);
|
||||
expect(
|
||||
cliFirstAcceptance,
|
||||
"CLI-first acceptance composes debug and artifact checks",
|
||||
/node scripts\/vscode-f5-smoke\.js[\s\S]*node scripts\/artifact-download-smoke\.js[\s\S]*node scripts\/artifact-export-smoke\.js/
|
||||
);
|
||||
expect(
|
||||
cliFirstAcceptance,
|
||||
"CLI-first acceptance composes DAP checks",
|
||||
/node scripts\/dap-smoke\.js/
|
||||
);
|
||||
expect(
|
||||
cliFirstAcceptance,
|
||||
"CLI-first acceptance can include private hosted gate",
|
||||
/DISASMER_CLI_FIRST_INCLUDE_PRIVATE[\s\S]*scripts\/acceptance-private\.sh/
|
||||
);
|
||||
assert.doesNotMatch(
|
||||
cliFirstAcceptance,
|
||||
/node scripts\/public-release-dryrun-e2e\.js|node scripts\/public-release-dryrun-final-evidence\.js/,
|
||||
"CLI-first non-e2e gate must not invoke final public release e2e or final evidence verifier"
|
||||
);
|
||||
|
||||
for (const [name, pattern] of [
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ function runCli(args, env = {}) {
|
|||
assert.strictEqual(report.plan.entry, "build");
|
||||
assert.deepStrictEqual(report.plan.session, {
|
||||
AgentPublicKey: {
|
||||
agent: "agent",
|
||||
public_key_fingerprint: sha256(agentPublicKey),
|
||||
browser_interaction_required: false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ const userFacingDocs = [
|
|||
"MVP.md",
|
||||
"acceptance_criteria.md",
|
||||
"acceptance_criteria_phase2.md",
|
||||
"cli_acceptance_criteria.md",
|
||||
].map((file) => [file, fs.readFileSync(path.join(repo, file), "utf8")]);
|
||||
const publicAcceptance = fs.readFileSync(
|
||||
path.join(repo, "scripts/acceptance-public.sh"),
|
||||
|
|
@ -48,6 +49,8 @@ const requiredReadmePatterns = [
|
|||
["artifact download smoke", /node scripts\/artifact-download-smoke\.js/],
|
||||
["artifact export smoke", /node scripts\/artifact-export-smoke\.js/],
|
||||
["acceptance report smoke", /node scripts\/acceptance-report-smoke\.js/],
|
||||
["CLI-first acceptance gate", /scripts\/acceptance-cli-first\.sh/],
|
||||
["CLI-first acceptance before e2e", /CLI-first non-e2e gate before any final public-release e2e attempt/],
|
||||
["public private boundary smoke", /node scripts\/public-private-boundary-smoke\.js/],
|
||||
["release blocker smoke", /node scripts\/release-blocker-smoke\.js/],
|
||||
["explicit export", /attached receiver node or user-provided\s+storage integration/],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue