Initial curated projectbrain source from 8a7b1e0651dbdab97d744cbd2e653ab3970ac6c5
This commit is contained in:
commit
5aa3e8d685
700 files changed
+132801
No files matched your search
@@ -0,0 +1,183 @@
|
||||
import { spawnSync } from "node:child_process";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
const baseUrl = process.env.PROJECTBRAIN_SMOKE_URL ?? "http://127.0.0.1:5173";
|
||||
const projectId = process.env.PROJECTBRAIN_SMOKE_PROJECT ?? "widefrog";
|
||||
const shouldRunSmokes = process.argv.includes("--run-smokes") || process.env.PROJECTBRAIN_PROOF_RUN_SMOKES === "1";
|
||||
const hasExplicitBaseUrl = Boolean(process.env.PROJECTBRAIN_SMOKE_URL);
|
||||
const shouldWriteReport = process.argv.includes("--write") || process.env.PROJECTBRAIN_PROOF_WRITE === "1";
|
||||
const explicitOutputArg = process.argv.find((arg) => arg.startsWith("--out="));
|
||||
const explicitOutputPath = explicitOutputArg?.slice("--out=".length) || process.env.PROJECTBRAIN_PROOF_OUT;
|
||||
|
||||
const evidenceRows = [
|
||||
{
|
||||
id: "RC63",
|
||||
label: "Release evidence lane click-through",
|
||||
script: "smoke:rc63-release-evidence-lane",
|
||||
proves: "Release evidence routes are reachable from the operator lane.",
|
||||
},
|
||||
{
|
||||
id: "RC60",
|
||||
label: "Review decision receipt recovery",
|
||||
script: "smoke:rc60-review-decision-loop",
|
||||
proves: "Review decisions can be recovered and inspected from history.",
|
||||
},
|
||||
{
|
||||
id: "RC73",
|
||||
label: "Release evidence capture assist",
|
||||
script: "smoke:rc73-release-evidence-capture-assist",
|
||||
proves: "Runtime evidence capture assists the operator instead of leaving proof manual-only.",
|
||||
},
|
||||
{
|
||||
id: "RC88",
|
||||
label: "Release Center cockpit",
|
||||
script: "smoke:rc88-release-center",
|
||||
proves: "Release Center renders the cockpit, archives, quality and operator actions.",
|
||||
},
|
||||
{
|
||||
id: "RC99",
|
||||
label: "Release checklist click-through",
|
||||
script: "smoke:rc99-release-checklist-clickthrough",
|
||||
proves: "Checklist links land on exact target sections and expose return paths.",
|
||||
},
|
||||
];
|
||||
|
||||
const run = (command, args, options = {}) => spawnSync(command, args, {
|
||||
encoding: "utf8",
|
||||
shell: process.platform === "win32",
|
||||
...options,
|
||||
});
|
||||
|
||||
const readPackage = () => {
|
||||
const packageJson = JSON.parse(fs.readFileSync("package.json", "utf8"));
|
||||
return packageJson.scripts ?? {};
|
||||
};
|
||||
|
||||
const getGitCommit = () => {
|
||||
const result = run("git", ["rev-parse", "--short", "HEAD"]);
|
||||
return result.status === 0 ? result.stdout.trim() : "unknown";
|
||||
};
|
||||
|
||||
const createDefaultReportPath = (commit) => {
|
||||
const stamp = new Date().toISOString().replace(/[:.]/g, "-");
|
||||
return `checkpoints/release-proof/projectbrain-release-proof-${commit}-${stamp}.md`;
|
||||
};
|
||||
|
||||
const checkLocalConfiguration = () => {
|
||||
const scripts = readPackage();
|
||||
const missing = [];
|
||||
|
||||
if (!scripts["smoke:release-operator"]) missing.push("smoke:release-operator");
|
||||
if (!scripts["release:proof-report"]) missing.push("release:proof-report");
|
||||
for (const row of evidenceRows) {
|
||||
if (!scripts[row.script]) missing.push(row.script);
|
||||
}
|
||||
|
||||
return missing;
|
||||
};
|
||||
|
||||
const checkLiveHealth = async () => {
|
||||
try {
|
||||
const response = await fetch(`${baseUrl}/api/health`);
|
||||
const body = await response.text();
|
||||
return {
|
||||
ok: response.ok,
|
||||
status: response.status,
|
||||
body: body.slice(0, 220),
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
ok: false,
|
||||
status: "unreachable",
|
||||
body: error instanceof Error ? error.message : String(error),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const runOperatorSmoke = () => {
|
||||
const result = run("pnpm", ["run", "smoke:release-operator"], {
|
||||
stdio: "inherit",
|
||||
env: process.env,
|
||||
});
|
||||
|
||||
return result.status === 0;
|
||||
};
|
||||
|
||||
const formatTable = (rows) => {
|
||||
const header = "| Gate | Smoke | Proof |\n| --- | --- | --- |";
|
||||
const body = rows.map((row) => `| ${row.id} | \`${row.script}\` | ${row.proves} |`).join("\n");
|
||||
return `${header}\n${body}`;
|
||||
};
|
||||
|
||||
const localMissing = checkLocalConfiguration();
|
||||
let smokePassed = null;
|
||||
|
||||
if (shouldRunSmokes) {
|
||||
console.log("Running release operator smoke suite before generating proof report...\n");
|
||||
smokePassed = runOperatorSmoke();
|
||||
}
|
||||
|
||||
const liveHealth = await checkLiveHealth();
|
||||
const gitCommit = getGitCommit();
|
||||
const localConfigOk = localMissing.length === 0;
|
||||
const healthGateOk = liveHealth.ok || !hasExplicitBaseUrl;
|
||||
const verdict = localConfigOk && healthGateOk && (smokePassed !== false)
|
||||
? (smokePassed === true ? "PASS" : "CONFIGURED - SMOKE NOT RUN")
|
||||
: "ATTENTION REQUIRED";
|
||||
const reportPath = explicitOutputPath || createDefaultReportPath(gitCommit);
|
||||
|
||||
const report = [
|
||||
"# ProjectBrain Release Operator Proof Report",
|
||||
"",
|
||||
`Generated: ${new Date().toISOString()}`,
|
||||
`Commit: ${gitCommit}`,
|
||||
`Base URL: ${baseUrl}`,
|
||||
`Project: ${projectId}`,
|
||||
`Verdict: ${verdict}`,
|
||||
"",
|
||||
"## Live Health",
|
||||
"",
|
||||
`- Status: ${liveHealth.status}`,
|
||||
`- Result: ${liveHealth.ok ? "reachable" : hasExplicitBaseUrl ? "not reachable" : "not reachable in local default mode"}`,
|
||||
`- Body: ${liveHealth.body}`,
|
||||
"",
|
||||
"## Proof Coverage",
|
||||
"",
|
||||
formatTable(evidenceRows),
|
||||
"",
|
||||
"## Local Configuration",
|
||||
"",
|
||||
localConfigOk
|
||||
? "- Required release smoke scripts are registered."
|
||||
: `- Missing scripts: ${localMissing.map((name) => `\`${name}\``).join(", ")}`,
|
||||
`- Smoke execution: ${smokePassed === true ? "passed" : smokePassed === false ? "failed" : "not run"}`,
|
||||
"",
|
||||
"## Operator Commands",
|
||||
"",
|
||||
"```bash",
|
||||
"pnpm run release:proof-report",
|
||||
"pnpm run release:proof-report -- --write",
|
||||
"PROJECTBRAIN_PROOF_RUN_SMOKES=1 pnpm run release:proof-report",
|
||||
"PROJECTBRAIN_PROOF_RUN_SMOKES=1 PROJECTBRAIN_PROOF_WRITE=1 pnpm run release:proof-report",
|
||||
"PROJECTBRAIN_SMOKE_URL=http://127.0.0.1:1209 pnpm run smoke:release-operator",
|
||||
"```",
|
||||
"",
|
||||
"## Remaining Manual Gates",
|
||||
"",
|
||||
"- Confirm the intended release commit/tag.",
|
||||
"- Confirm any environment-specific deployment notes.",
|
||||
"- Confirm operator signoff after the smoke suite is green.",
|
||||
].join("\n");
|
||||
|
||||
console.log(report);
|
||||
|
||||
if (shouldWriteReport) {
|
||||
fs.mkdirSync(path.dirname(reportPath), { recursive: true });
|
||||
fs.writeFileSync(reportPath, `${report}\n`, "utf8");
|
||||
console.log(`\nRelease proof report written to ${reportPath}`);
|
||||
}
|
||||
|
||||
if (!localConfigOk || !healthGateOk || smokePassed === false) {
|
||||
process.exitCode = 1;
|
||||
}
|
||||
Reference in new issue
Block a user