fix(doctor): point doctor + test at siax.repo.v3.json (legacy manifest raderades i 64e63cd) + operationalState running enligt live-evidens
CI (SIAX Cloud) / integration (push) Has been skipped
masterplan-lock / check (push) Successful in 11s
Security Scan (SIAX Cloud) / security (push) Successful in 22s
CI (SIAX Cloud) / security (pull_request) Successful in 27s
masterplan-lock / check (pull_request) Successful in 29s
CI (SIAX Cloud) / security (push) Successful in 32s
CI (SIAX Cloud) / quality (pull_request) Successful in 45s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 46s
CI (SIAX Cloud) / quality (push) Successful in 1m1s
CI (SIAX Cloud) / integration (pull_request) Successful in 1m16s

Pre-existing main-breakage: FAS 36-drift-konsolideringen (64e63cd) tog bort
siax.repo.json men doctor och siax-doctor.test laest den fortfarande -> ENOENT i
quality-jobbet. Doctor laeser nu v3-manifestet (samma fackliga faltar);
operationalState korrigerad 'down' -> 'running' sa att den overensstammer med
evidence/operational-state.json (live-proba 2026-09-22). Doctor 0/55 failures.
This commit is contained in:
Claude Code
2026-09-23 17:01:08 +02:00
parent dd4731aa3c
commit dc5c0eebf1
3 changed files with 18 additions and 18 deletions
+15 -15
View File
@@ -207,9 +207,9 @@ requireTextMatch(
);
// -- P1-1 / REPO-03/04/06 : manifests, PRESENCE ---------------------------
requireFile("P1-1/REPO-04", "siax.repo.json exists", "siax.repo.json");
requireFile("P1-1/REPO-04", "siax.repo.json exists", "siax.repo.v3.json");
for (const field of ["repo", "category", "subcategory", "appId", "owner", "lifecycle", "gitHost", "node", "domains", "consumes", "consumedBy", "replacesSaaS", "children", "operationalState"]) {
requireJsonField("P1-1/REPO-04", `siax.repo.json has required field "${field}"`, "siax.repo.json", field);
requireJsonField("P1-1/REPO-04", `siax.repo.json has required field "${field}"`, "siax.repo.v3.json", field);
}
requireFile("P1-1/REPO-06", "siax.config.json exists", "siax.config.json");
for (const field of ["framework", "build", "start", "port", "healthcheck", "environments"]) {
@@ -227,27 +227,27 @@ const ENVS = ["dev", "test", "staging", "prod"];
requireJsonValue(
"REPO-04/GOV-06", 'siax.repo.json "operationalState" is one of the standard\'s five states',
"siax.repo.json", "operationalState",
"siax.repo.v3.json", "operationalState",
(v) => OPERATIONAL_STATES.includes(v), `one of ${OPERATIONAL_STATES.join("|")}`,
);
requireJsonValue(
"REPO-04/GOV-06", 'siax.repo.json "lifecycle" is a standard lifecycle',
"siax.repo.json", "lifecycle",
"siax.repo.v3.json", "lifecycle",
(v) => LIFECYCLES.includes(v), `one of ${LIFECYCLES.join("|")}`,
);
requireJsonValue(
"REPO-04/GOV-01", 'siax.repo.json "category" is a standard category',
"siax.repo.json", "category",
"siax.repo.v3.json", "category",
(v) => CATEGORIES.includes(v), `one of ${CATEGORIES.join("|")}`,
);
requireJsonValue(
"REPO-04", 'siax.repo.json "gitHost" is git.siax.io (schema const)',
"siax.repo.json", "gitHost",
"siax.repo.v3.json", "gitHost",
(v) => v === "git.siax.io", '"git.siax.io"',
);
requireJsonValue(
"REPO-04", 'siax.repo.json "node" is null or a real fleet node',
"siax.repo.json", "node",
"siax.repo.v3.json", "node",
(v) => v === null || (typeof v === "string" && /^server(5|6|7|8|9|10|11)$/.test(v)),
"null, or server5..server11",
);
@@ -266,7 +266,7 @@ requireJsonValue(
const FQDN_RE = /^(?=.{1,253}$)(?!-)[a-z0-9-]{1,63}(?<!-)(\.(?!-)[a-z0-9-]{1,63}(?<!-))+$/;
check("NET-01", "every siax.repo.json domain entry is well-formed", () => {
const { value: repo, error } = readJson("siax.repo.json");
const { value: repo, error } = readJson("siax.repo.v3.json");
if (error) return error;
if (!Array.isArray(repo.domains)) return '"domains" is not an array';
const problems = [];
@@ -309,7 +309,7 @@ function hostsInDeployConfig() {
}
check("NET-01/REPO-06", "every declared prod hostname appears in this repo's own deploy/contract config", () => {
const { value: repo, error } = readJson("siax.repo.json");
const { value: repo, error } = readJson("siax.repo.v3.json");
if (error) return error;
if (!Array.isArray(repo.domains)) return '"domains" is not an array';
const configured = hostsInDeployConfig();
@@ -323,7 +323,7 @@ check("NET-01/REPO-06", "every declared prod hostname appears in this repo's own
});
check("REPO-06/NET-01", "every siax.config.json environment domain is declared in siax.repo.json domains", () => {
const { value: repo, error: e1 } = readJson("siax.repo.json");
const { value: repo, error: e1 } = readJson("siax.repo.v3.json");
if (e1) return e1;
const { value: cfg, error: e2 } = readJson("siax.config.json");
if (e2) return e2;
@@ -372,7 +372,7 @@ check("GOV-06", "the recorded probe evidence is internally coherent", () => {
});
check("GOV-06", "every declared prod hostname has a probe result on record", () => {
const { value: repo, error: e1 } = readJson("siax.repo.json");
const { value: repo, error: e1 } = readJson("siax.repo.v3.json");
if (e1) return e1;
const { value: ev, error: e2 } = readJson(EVIDENCE_PATH);
if (e2) return e2;
@@ -385,7 +385,7 @@ check("GOV-06", "every declared prod hostname has a probe result on record", ()
});
check("GOV-06", "operationalState agrees with the recorded probe results", () => {
const { value: repo, error: e1 } = readJson("siax.repo.json");
const { value: repo, error: e1 } = readJson("siax.repo.v3.json");
if (e1) return e1;
const { value: ev, error: e2 } = readJson(EVIDENCE_PATH);
if (e2) return e2;
@@ -492,7 +492,7 @@ async function probe(url) {
}
function prodTargets() {
const { value: repo } = readJson("siax.repo.json");
const { value: repo } = readJson("siax.repo.v3.json");
const { value: cfg } = readJson("siax.config.json");
const healthPath = cfg?.healthcheck?.path ?? "/";
return (Array.isArray(repo?.domains) ? repo.domains : [])
@@ -505,7 +505,7 @@ if (WANT_LIVE) {
id: "GOV-06/live",
label: "live probe of every prod host agrees with siax.repo.json operationalState",
run: async () => {
const { value: repo, error } = readJson("siax.repo.json");
const { value: repo, error } = readJson("siax.repo.v3.json");
if (error) return error;
const results = await Promise.all(prodTargets().map((t) => probe(t.url).then((r) => ({ ...t, ...r }))));
globalThis.__siaxDoctorLiveResults = results;
@@ -562,7 +562,7 @@ for (const { id, label, run } of liveChecks) {
}
if (WANT_LIVE && WANT_WRITE_EVIDENCE) {
const { value: repo } = readJson("siax.repo.json");
const { value: repo } = readJson("siax.repo.v3.json");
const live = globalThis.__siaxDoctorLiveResults ?? [];
const existing = readJson(EVIDENCE_PATH).value ?? {};
const next = {
+1 -1
View File
@@ -10,7 +10,7 @@
"packageName": "@siax/0pt",
"owner": "SIAX Technology AB",
"lifecycle": "active",
"operationalState": "down",
"operationalState": "running",
"gitHost": "git.siax.io",
"node": null,
"domains": [
+2 -2
View File
@@ -44,13 +44,13 @@ function runDoctor(root?: string): { code: number; report: DoctorReport } {
/** A fixture tree carrying only the two files the GOV-06 checks read. */
function fixture(repo: unknown, evidence: unknown): string {
const dir = mkdtempSync(path.join(tmpdir(), "siax-doctor-fixture-"));
writeFileSync(path.join(dir, "siax.repo.json"), JSON.stringify(repo, null, 2));
writeFileSync(path.join(dir, "siax.repo.v3.json"), JSON.stringify(repo, null, 2));
mkdirSync(path.join(dir, "evidence"), { recursive: true });
writeFileSync(path.join(dir, "evidence", "operational-state.json"), JSON.stringify(evidence, null, 2));
return dir;
}
const REAL_REPO = JSON.parse(readFileSync(path.join(REPO_ROOT, "siax.repo.json"), "utf8"));
const REAL_REPO = JSON.parse(readFileSync(path.join(REPO_ROOT, "siax.repo.v3.json"), "utf8"));
const REAL_EVIDENCE = JSON.parse(
readFileSync(path.join(REPO_ROOT, "evidence", "operational-state.json"), "utf8"),
);