#!/usr/bin/env node const assert = require("assert"); const fs = require("fs"); const path = require("path"); const repo = path.resolve(__dirname, ".."); const inventoryPath = path.join(repo, "website_mvp_inventory.md"); if (!fs.existsSync(inventoryPath)) { if (fs.existsSync(path.join(repo, "DISASMER_PUBLIC_TREE.json"))) { console.log( "Website inventory contract smoke skipped: website_mvp_inventory.md is filtered from this public tree" ); process.exit(0); } throw new Error("website_mvp_inventory.md is missing"); } const source = fs.readFileSync(inventoryPath, "utf8"); function expect(name, pattern) { assert.match(source, pattern, `missing website inventory evidence: ${name}`); } function criterionLines() { return source .split(/\r?\n/) .filter((line) => /^- \[[ x]\] \*\*/.test(line)); } expect("header", /^# Disasmer Minimal Website Inventory/m); expect( "acceptance-style status", /\*\*Status:\*\* hosted website addendum to `acceptance_criteria\.md`, `acceptance_criteria_phase2\.md`, and `cli_acceptance_criteria\.md`/ ); expect( "hosted signup exception", /except hosted Authentik account creation/ ); expect( "no duplicate work note", /does not automatically mean new product code, a new feature, or even actual implementation work is required/ ); expect( "barebones no CSS", /barebones functional HTML with no CSS/ ); expect( "future hosted business scope", /Billing-related features, including paid checkout, paid-plan management, upgrade flows, hosted support tooling, a full hosted admin console, broad moderation workflows/ ); expect( "billing is not MVP website work", /Do not build billing\/upgrade flows into the minimal website for this MVP/ ); assert.doesNotMatch(source, /community-tier/, "use `community tier`, not `community-tier`"); const lines = criterionLines(); assert(lines.length > 0, "website inventory must contain status-prefixed checklist items"); for (const line of lines) { assert.match( line, /^- \[[ x]\] \*\*(Passed|Partial|Open|Postponed)(?: \([^)]+\))?:\*\*/, `website inventory item lacks an explicit status prefix: ${line}` ); } for (const [name, pattern] of [ ["CLI login command", /`disasmer login \[--browser\] \[--coordinator \]`/], ["CLI auth status command", /`disasmer auth status`/], ["CLI key command", /`disasmer key add --public-key `/], ["CLI project init command", /`disasmer project init`/], ["CLI node enroll command", /`disasmer node enroll --coordinator --ttl-seconds `/], ["CLI process status command", /`disasmer process status`/], ["CLI task list command", /`disasmer task list`/], ["CLI DAP command", /`disasmer dap`/], ["CLI quota command", /`disasmer quota status`/], ["CLI admin status command", /`disasmer admin status`/], ]) { expect(name, pattern); } for (const [name, pattern] of [ ["website default project is open", /- \[ \] \*\*Open:\*\* land in their default project\./], ["website node attach is open", /- \[ \] \*\*Open:\*\* copy a node attach command\./], ["website process view is open", /- \[ \] \*\*Open:\*\* see the single current virtual process\./], ["website logs are open", /- \[ \] \*\*Open:\*\* see recent bounded logs\./], ["website artifact download is open", /- \[ \] \*\*Open:\*\* securely download an available best-effort retained artifact\./], ["website keys are partial through CLI", /- \[ \] \*\*Partial:\*\* manage\/revoke public keys or know the CLI command to do so\./], ]) { expect(name, pattern); } console.log("Website inventory contract smoke passed");