{ "schemaVersion": 1, "activationCommit": "f65e9ea656ec466e12640bf6ab5d46fe07ff160c", "gateRoots": ["gates"], "governingClaimFiles": ["docs/remediation/MISSION.md", "docs/remediation/GATE-CLAIMS.md"], "coverageBoundary": { "included": [ "root typecheck, lint, and format scripts", "RM-01 checkout preflight", "Mosaic CI queue guard", "root Husky pre-commit and pre-push hooks" ], "excluded": [ "framework quality scripts other than ci-queue-wait.sh", "package-local test and build scripts", "template hooks and generated Husky dispatcher files", "deployment and release scripts" ], "trackedBy": "RM-54" }, "criteria": [ { "id": "RM02-CHECK-RIGHT", "originalText": "Every registered check is observed red for its own stated reason before its green counts.", "currentText": "Every registered check is observed red for its own stated reason before its green counts.", "claimType": "integrity", "source": "docs/remediation/MISSION.md#first-class-principle-pre-registration", "meaningChanges": [] }, { "id": "RM02-SET-COVERS", "originalText": "Every acceptance criterion is bound to the specific case that exercises it.", "currentText": "Every acceptance criterion is bound to the specific case that exercises it.", "claimType": "integrity", "source": "docs/remediation/TASKS.md#d-17", "meaningChanges": [] }, { "id": "RM02-MODELED-CONSISTENCY", "originalText": "No two declared finite scenarios require mutually unsatisfiable outcomes.", "currentText": "No two declared finite scenarios require mutually unsatisfiable outcomes; arbitrary English consistency is outside this model.", "claimType": "integrity", "source": "docs/remediation/TASKS.md#d-18", "meaningChanges": [ { "originalText": "No two criteria conflict.", "restatement": "No two declared finite scenarios require mutually unsatisfiable outcomes; arbitrary English consistency is outside this model.", "reason": "Semantic satisfiability of arbitrary natural language is undecidable at this layer.", "finding": "D-18", "task": "RM-54/RM-55", "date": "2026-08-01" } ] }, { "id": "RM02-MEANING-PROVENANCE", "originalText": "A restated criterion retains original text, restatement, and reason.", "currentText": "A restated criterion retains original text, restatement, and reason.", "claimType": "integrity", "source": "docs/remediation/TASKS.md#d-18", "meaningChanges": [] }, { "id": "RM02-PROSE-CONTROL", "originalText": "Security and integrity claims in governing prose require a bound negative control.", "currentText": "Marked security and integrity claims in designated governing prose require a bound negative control; RM-54 audits marker completeness.", "claimType": "security", "source": "docs/remediation/TASKS.md#d-20", "meaningChanges": [ { "originalText": "Security and integrity claims in governing prose require a bound negative control.", "restatement": "Marked security and integrity claims in designated governing prose require a bound negative control; RM-54 audits marker completeness.", "reason": "A local verifier cannot safely infer every semantic claim in arbitrary English.", "finding": "D-20", "task": "RM-54", "date": "2026-08-01" } ] }, { "id": "RM02-CURRENT-TREE-BOUNDARY", "originalText": "assert that every merged commit passed every required gate, evaluated AGAINST THAT COMMIT'S OWN TREE — not against current main.", "currentText": "PR CI performs unprivileged, fail-closed current-tree verification only; isolated per-commit replay is deferred to RM-60's protected post-merge/main authority as detection with quarantine/revert, not pre-merge prevention.", "claimType": "security", "source": "docs/PRD.md#rm02-req-10-meaning-change-provenance", "meaningChanges": [ { "originalText": "assert that every merged commit passed every required gate, evaluated AGAINST THAT COMMIT'S OWN TREE — not against current main.", "restatement": "PR CI performs unprivileged, fail-closed current-tree verification only; isolated per-commit replay is deferred to a protected post-merge/main authority as detection with quarantine/revert, not pre-merge prevention.", "reason": "PR-controlled code would otherwise receive and could directly use the namespace capability intended to contain it; the pre-execution trust boundary is absent at the repository layer.", "finding": "D-25", "task": "RM-60/RM-59", "date": "2026-08-01" } ] }, { "id": "QUALITY-TYPECHECK", "originalText": "The root typecheck rejects a TypeScript type error.", "currentText": "The root typecheck rejects a TypeScript type error.", "claimType": "quality", "source": "package.json#scripts.typecheck", "meaningChanges": [] }, { "id": "QUALITY-LINT", "originalText": "The root lint gate rejects invalid TypeScript syntax.", "currentText": "The root lint gate rejects invalid TypeScript syntax.", "claimType": "quality", "source": "package.json#scripts.lint", "meaningChanges": [] }, { "id": "QUALITY-FORMAT", "originalText": "The root format gate rejects an unformatted tracked-format input.", "currentText": "The root format gate rejects an unformatted tracked-format input.", "claimType": "quality", "source": "package.json#scripts.format:check", "meaningChanges": [] }, { "id": "CHECKOUT-PREFLIGHT", "originalText": "The RM-01 preflight rejects stale or independently mutated generated state within its documented threat model.", "currentText": "The RM-01 preflight rejects stale or independently mutated generated state, but not a same-UID consistent rewrite; RM-59 owns the external trust anchor.", "claimType": "integrity", "source": "scripts/preflight.mjs", "meaningChanges": [ { "originalText": "The generated-state manifest turns integrity from a claim into a property.", "restatement": "The preflight detects accidental, independent, stale, and foreign-residue mutation, but not a same-UID consistent rewrite.", "reason": "D-19 established CWE-345 self-authentication and D-20 recorded the empirical disproof.", "finding": "D-19/D-20", "task": "RM-59", "date": "2026-07-31" } ] }, { "id": "QUEUE-GUARD", "originalText": "The queue guard distinguishes ready, pending, indeterminate, and failed CI states without silently accepting indeterminate or failed states.", "currentText": "The queue guard is measured against its current behavior while required-versus-actual deltas remain owned by RM-03.", "claimType": "integrity", "source": "packages/mosaic/framework/tools/git/ci-queue-wait.sh", "meaningChanges": [ { "originalText": "The required queue guard blocks unsafe push and merge states.", "restatement": "The registry measures current fail-open states and reports each as DEFECT until RM-03 changes the gate and registry together.", "reason": "D-6/D-10 observed unknown, no-status, malformed, terminal-failure, and wrong-branch behavior.", "finding": "D-6/D-10", "task": "RM-03", "date": "2026-08-01" } ] }, { "id": "HOOK-PRE-COMMIT", "originalText": "The pre-commit hook propagates lint-staged failure.", "currentText": "The pre-commit hook propagates lint-staged failure.", "claimType": "workflow", "source": ".husky/pre-commit", "meaningChanges": [] }, { "id": "HOOK-PRE-PUSH", "originalText": "The pre-push hook propagates each required gate failure.", "currentText": "The pre-push hook propagates each required gate failure.", "claimType": "workflow", "source": ".husky/pre-push", "meaningChanges": [] }, { "id": "GATE-SOURCE-DEPLOYMENT", "originalText": "A registered gate with a deployed counterpart verifies the artifact that actually enforces.", "currentText": "A registered gate with a deployed counterpart requires byte equality and a deployed-copy drift negative control.", "claimType": "integrity", "source": "docs/PRD.md#rm-02-gate-registry-and-negative-control-verifier-1029", "meaningChanges": [ { "originalText": "The registry verifies repository gate sources.", "restatement": "The registry also verifies byte identity with each declared deployed counterpart.", "reason": "A source-only check can certify a file that is not the installed enforcing artifact.", "finding": "D-1/P-ACTIVATION-001", "task": "RM-02", "date": "2026-08-01" } ] } ], "proseClaims": [ { "id": "OBSERVE-PROPERTY", "criterionId": "RM02-CHECK-RIGHT" }, { "id": "PREREGISTRATION-BOUNDARY", "criterionId": "RM02-SET-COVERS" }, { "id": "ARTIFACT-INTEGRITY-BOUNDARY", "criterionId": "GATE-SOURCE-DEPLOYMENT" }, { "id": "IMPOSSIBLE-LAYER-BOUNDARY", "criterionId": "CHECKOUT-PREFLIGHT" }, { "id": "PROSE-IS-A-CLAIM", "criterionId": "RM02-PROSE-CONTROL" }, { "id": "GENERATED-STATE-SCOPE", "criterionId": "CHECKOUT-PREFLIGHT" }, { "id": "EXECUTION-TRUST-BOUNDARY", "criterionId": "RM02-CURRENT-TREE-BOUNDARY" }, { "id": "CRITERION-RESTATEMENT", "criterionId": "RM02-MEANING-PROVENANCE" } ], "compatibilityScenarios": [ { "id": "QUALITY-AND-PREFLIGHT", "construction": "clean-current-tree", "caseRefs": [ "quality-typecheck/clean-tree", "quality-lint/clean-tree", "quality-format/clean-tree", "checkout-preflight/clean-tree" ], "invocation": [ "sh", "-c", "pnpm typecheck && pnpm lint && pnpm format:check && node scripts/preflight.mjs" ], "expected": { "exitCode": 0, "outputPattern": "checkout preflight passed" } }, { "id": "HOOK-CHAIN", "construction": "hook-propagation-model", "caseRefs": ["hook-pre-commit/lint-staged-failure", "hook-pre-push/typecheck-failure"], "invocation": [ "sh", "-c", "sh .husky/pre-commit; pre_commit=$?; sh .husky/pre-push; pre_push=$?; test \"$pre_commit\" = 19 && test \"$pre_push\" = 19" ], "expected": { "exitCode": 0, "outputPattern": "FAKE_NPX_EXIT=19[\\s\\S]*FAKE_PNPM_FAILURE=typecheck" } } ], "mergeAssertions": { "mode": "unprivileged-current-tree-pr-verification", "deferredReplayOwner": "RM-60", "trustDependencies": ["RM-25", "RM-59", "RM-60"], "providerEvidence": "assert retained current-tree terminal-success records for prior commits; report absent, expired, or current-running evidence without inference", "postMergeResponse": "protected isolated replay is detection, not prevention; quarantine and revert on failure" }, "gates": [ { "id": "quality-typecheck", "source": "package.json", "invocation": ["pnpm", "typecheck"], "deployment": { "kind": "none", "reason": "The package script in this checkout is the invoked artifact." }, "inertMutation": { "file": "package.json", "find": "\"typecheck\": \"pnpm preflight && turbo run typecheck\"", "replace": "\"typecheck\": \"exit 0\"", "caseId": "type-error", "expected": { "exitCode": 0, "notOutputPattern": "__gate_typecheck__\\.ts" } }, "cases": [ { "id": "clean-tree", "criterionIds": ["QUALITY-TYPECHECK", "RM02-MODELED-CONSISTENCY"], "mustFail": false, "required": { "exitCode": 0 }, "actual": { "exitCode": 0 }, "reasonPattern": "" }, { "id": "type-error", "criterionIds": ["QUALITY-TYPECHECK", "RM02-CHECK-RIGHT", "RM02-SET-COVERS"], "mustFail": true, "required": { "exitCode": 2, "outputPattern": "Type 'number' is not assignable to type 'string'" }, "actual": { "exitCode": 2, "outputPattern": "Type 'number' is not assignable to type 'string'" }, "reasonPattern": "__gate_typecheck__\\.ts", "environment": { "TURBO_FORCE": "true" }, "fixture": { "writeFiles": [ { "path": "packages/types/src/__gate_typecheck__.ts", "content": "export const gateTypeError: string = 42;\n" } ] } } ] }, { "id": "quality-lint", "source": "package.json", "invocation": ["pnpm", "lint"], "deployment": { "kind": "none", "reason": "The package script in this checkout is the invoked artifact." }, "inertMutation": { "file": "package.json", "find": "\"lint\": \"turbo run lint\"", "replace": "\"lint\": \"exit 0\"", "caseId": "invalid-syntax", "expected": { "exitCode": 0, "notOutputPattern": "__gate_lint__\\.ts" } }, "cases": [ { "id": "clean-tree", "criterionIds": ["QUALITY-LINT", "RM02-MODELED-CONSISTENCY"], "mustFail": false, "required": { "exitCode": 0 }, "actual": { "exitCode": 0 }, "reasonPattern": "" }, { "id": "invalid-syntax", "criterionIds": ["QUALITY-LINT", "RM02-CHECK-RIGHT", "RM02-SET-COVERS"], "mustFail": true, "required": { "exitCode": 1, "outputPattern": "Parsing error" }, "actual": { "exitCode": 1, "outputPattern": "Parsing error" }, "reasonPattern": "__gate_lint__\\.ts", "environment": { "TURBO_FORCE": "true" }, "fixture": { "writeFiles": [ { "path": "packages/types/src/__gate_lint__.ts", "content": "export const = ;\n" } ] } } ] }, { "id": "quality-format", "source": "package.json", "invocation": ["pnpm", "format:check"], "deployment": { "kind": "none", "reason": "The package script in this checkout is the invoked artifact." }, "inertMutation": { "file": "package.json", "find": "\"format:check\": \"prettier --check \\\"**/*.{ts,tsx,js,jsx,json,md}\\\"\"", "replace": "\"format:check\": \"exit 0\"", "caseId": "unformatted-json", "expected": { "exitCode": 0, "notOutputPattern": "__gate_format__\\.json" } }, "cases": [ { "id": "clean-tree", "criterionIds": ["QUALITY-FORMAT", "RM02-MODELED-CONSISTENCY"], "mustFail": false, "required": { "exitCode": 0 }, "actual": { "exitCode": 0 }, "reasonPattern": "" }, { "id": "unformatted-json", "criterionIds": ["QUALITY-FORMAT", "RM02-CHECK-RIGHT", "RM02-SET-COVERS"], "mustFail": true, "required": { "exitCode": 1, "outputPattern": "__gate_format__\\.json" }, "actual": { "exitCode": 1, "outputPattern": "__gate_format__\\.json" }, "reasonPattern": "Code style issues found", "fixture": { "writeFiles": [ { "path": "gates/__gate_format__.json", "content": "{\"bad\":true,\"spacing\":[1,2,3]}\n" } ] } } ] }, { "id": "checkout-preflight", "source": "scripts/preflight.mjs", "invocation": ["node", "scripts/preflight.mjs"], "deployment": { "kind": "none", "reason": "The checkout source is the directly invoked runtime artifact." }, "inertMutation": { "file": "scripts/preflight.mjs", "find": "code: GENERATED_STATE_EXIT,\n message: `MOSAIC_PREFLIGHT_GENERATED_STATE: web build is in progress", "replace": "code: 0,\n message: `MOSAIC_PREFLIGHT_GENERATED_STATE: web build is in progress", "caseId": "stale-build-lock", "expected": { "exitCode": 0, "outputPattern": "MOSAIC_PREFLIGHT_GENERATED_STATE" } }, "cases": [ { "id": "clean-tree", "criterionIds": ["CHECKOUT-PREFLIGHT", "RM02-MODELED-CONSISTENCY"], "mustFail": false, "required": { "exitCode": 0, "outputPattern": "checkout preflight passed" }, "actual": { "exitCode": 0, "outputPattern": "checkout preflight passed" }, "reasonPattern": "" }, { "id": "stale-build-lock", "criterionIds": [ "CHECKOUT-PREFLIGHT", "RM02-CHECK-RIGHT", "RM02-SET-COVERS", "RM02-MEANING-PROVENANCE", "RM02-PROSE-CONTROL" ], "mustFail": true, "required": { "exitCode": 43, "outputPattern": "web build is in progress or interrupted" }, "actual": { "exitCode": 43, "outputPattern": "web build is in progress or interrupted" }, "reasonPattern": "MOSAIC_PREFLIGHT_GENERATED_STATE", "fixture": { "writeFiles": [ { "path": ".mosaic-test-work/web-build.lock", "content": "negative control\n" } ] } }, { "id": "privileged-pr-gate", "criterionIds": ["RM02-CURRENT-TREE-BOUNDARY"], "mustFail": true, "invocation": ["node", "--test", "scripts/gate-wiring.test.mjs"], "required": { "exitCode": 1, "outputPattern": "privileged" }, "actual": { "exitCode": 1, "outputPattern": "privileged" }, "reasonPattern": "privileged", "fixture": { "copyPaths": [".woodpecker/ci.yml", "scripts/gate-wiring.test.mjs", "package.json"], "replaceFiles": [ { "path": ".woodpecker/ci.yml", "find": " gate-verify:\n image: *node_image\n", "replace": " gate-verify:\n image: *node_image\n privileged: true\n" } ] } } ] }, { "id": "ci-queue-wait", "source": "packages/mosaic/framework/tools/git/ci-queue-wait.sh", "invocation": [ "bash", "packages/mosaic/framework/tools/git/ci-queue-wait.sh", "--purpose", "push", "-B", "gate-fixture", "-t", "1", "-i", "0" ], "deployment": { "kind": "file", "source": "packages/mosaic/framework/tools/git/ci-queue-wait.sh", "path": "${HOME}/.config/mosaic/tools/git/ci-queue-wait.sh", "observedSha256": "19cda2f7009c536eb4da9a8df0e7a62f3db0277c9a577bdae5db003f4da3f3cb", "unavailableOwner": "RM-04" }, "inertMutation": { "file": "packages/mosaic/framework/tools/git/ci-queue-wait.sh", "find": "echo \"Unknown option: $1\" >&2\n usage >&2\n exit 1", "replace": "echo \"Unknown option: $1\" >&2\n usage >&2\n exit 0", "caseId": "unknown-option", "sandboxFiles": ["packages/mosaic/framework/tools/git"], "expected": { "exitCode": 0, "outputPattern": "Unknown option: --definitely-unknown" } }, "cases": [ { "id": "terminal-success", "criterionIds": ["QUEUE-GUARD", "GATE-SOURCE-DEPLOYMENT"], "mustFail": false, "required": { "exitCode": 0, "outputPattern": "state=terminal-success.*branch=gate-fixture" }, "actual": { "exitCode": 0, "outputPattern": "state=unknown.*branch=gate-fixture" }, "reasonPattern": "", "environment": { "PATH": "${ROOT}/gate-bin:${PATH}", "GITEA_TOKEN": "gate-fixture-token", "GATE_STATUS_JSON": "{\"state\":\"success\",\"statuses\":[]}" }, "fixture": { "copyPaths": ["packages/mosaic/framework/tools/git"], "writeFiles": [ { "path": ".git/config", "content": "[core]\n\trepositoryformatversion = 0\n\tbare = false\n[remote \"origin\"]\n\turl = https://git.mosaicstack.dev/mosaicstack/stack.git\n" }, { "path": ".git/HEAD", "content": "ref: refs/heads/main\n" }, { "path": ".git/objects/.keep", "content": "" }, { "path": ".git/refs/heads/.keep", "content": "" }, { "path": "gate-bin/curl", "mode": 493, "content": "#!/bin/sh\ncase \"$*\" in\n *'/branches/'*) printf '{\"commit\":{\"id\":\"gate-sha\"}}\\n200' ;;\n *'/commits/'*) printf '%s' \"$GATE_STATUS_JSON\" ;;\nesac\n" } ] }, "defect": { "owner": "RM-03", "reason": "The status classifier consumes its Python program from stdin, so piped provider JSON is not read and even terminal success becomes unknown." } }, { "id": "no-status-required", "criterionIds": ["QUEUE-GUARD", "RM02-CHECK-RIGHT", "RM02-SET-COVERS"], "mustFail": true, "required": { "exitCode": 1, "outputPattern": "No CI status contexts" }, "actual": { "exitCode": 0, "outputPattern": "state=unknown" }, "reasonPattern": "state=unknown", "invocation": [ "bash", "packages/mosaic/framework/tools/git/ci-queue-wait.sh", "--purpose", "push", "-B", "gate-fixture", "--require-status", "-t", "1", "-i", "0" ], "environment": { "PATH": "${ROOT}/gate-bin:${PATH}", "GITEA_TOKEN": "gate-fixture-token", "GATE_STATUS_JSON": "{\"statuses\":[]}" }, "fixture": { "copyPaths": ["packages/mosaic/framework/tools/git"], "writeFiles": [ { "path": ".git/config", "content": "[core]\n\trepositoryformatversion = 0\n\tbare = false\n[remote \"origin\"]\n\turl = https://git.mosaicstack.dev/mosaicstack/stack.git\n" }, { "path": ".git/HEAD", "content": "ref: refs/heads/main\n" }, { "path": ".git/objects/.keep", "content": "" }, { "path": ".git/refs/heads/.keep", "content": "" }, { "path": "gate-bin/curl", "mode": 493, "content": "#!/bin/sh\ncase \"$*\" in\n *'/branches/'*) printf '{\"commit\":{\"id\":\"gate-sha\"}}\\n200' ;;\n *'/commits/'*) printf '%s' \"$GATE_STATUS_JSON\" ;;\nesac\n" } ] }, "defect": { "owner": "RM-03", "reason": "The status classifier does not read the provider payload, so --require-status never reaches no-status." } }, { "id": "unknown-state", "criterionIds": ["QUEUE-GUARD", "RM02-SET-COVERS"], "mustFail": true, "required": { "exitCode": 1, "outputPattern": "state=unknown" }, "actual": { "exitCode": 0, "outputPattern": "state=unknown" }, "defect": { "owner": "RM-03", "reason": "Unknown state currently exits zero (D-6/D-10)." }, "reasonPattern": "state=unknown", "environment": { "PATH": "${ROOT}/gate-bin:${PATH}", "GITEA_TOKEN": "gate-fixture-token", "GATE_STATUS_JSON": "{\"state\":\"mystery\",\"statuses\":[]}" }, "fixture": { "copyPaths": ["packages/mosaic/framework/tools/git"], "writeFiles": [ { "path": ".git/config", "content": "[core]\n\trepositoryformatversion = 0\n\tbare = false\n[remote \"origin\"]\n\turl = https://git.mosaicstack.dev/mosaicstack/stack.git\n" }, { "path": ".git/HEAD", "content": "ref: refs/heads/main\n" }, { "path": ".git/objects/.keep", "content": "" }, { "path": ".git/refs/heads/.keep", "content": "" }, { "path": "gate-bin/curl", "mode": 493, "content": "#!/bin/sh\ncase \"$*\" in\n *'/branches/'*) printf '{\"commit\":{\"id\":\"gate-sha\"}}\\n200' ;;\n *'/commits/'*) printf '%s' \"$GATE_STATUS_JSON\" ;;\nesac\n" } ] } }, { "id": "malformed-status", "criterionIds": ["QUEUE-GUARD"], "mustFail": true, "required": { "exitCode": 1, "outputPattern": "state=unknown" }, "actual": { "exitCode": 0, "outputPattern": "state=unknown" }, "defect": { "owner": "RM-03", "reason": "Malformed provider payload currently becomes unknown and exits zero." }, "reasonPattern": "state=unknown", "environment": { "PATH": "${ROOT}/gate-bin:${PATH}", "GITEA_TOKEN": "gate-fixture-token", "GATE_STATUS_JSON": "not-json" }, "fixture": { "copyPaths": ["packages/mosaic/framework/tools/git"], "writeFiles": [ { "path": ".git/config", "content": "[core]\n\trepositoryformatversion = 0\n\tbare = false\n[remote \"origin\"]\n\turl = https://git.mosaicstack.dev/mosaicstack/stack.git\n" }, { "path": ".git/HEAD", "content": "ref: refs/heads/main\n" }, { "path": ".git/objects/.keep", "content": "" }, { "path": ".git/refs/heads/.keep", "content": "" }, { "path": "gate-bin/curl", "mode": 493, "content": "#!/bin/sh\ncase \"$*\" in\n *'/branches/'*) printf '{\"commit\":{\"id\":\"gate-sha\"}}\\n200' ;;\n *'/commits/'*) printf '%s' \"$GATE_STATUS_JSON\" ;;\nesac\n" } ] } }, { "id": "terminal-failure", "criterionIds": ["QUEUE-GUARD"], "mustFail": true, "required": { "exitCode": 1, "outputPattern": "state=terminal-failure" }, "actual": { "exitCode": 0, "outputPattern": "state=unknown" }, "defect": { "owner": "RM-03", "reason": "The classifier does not read the provider payload; terminal failure becomes unknown and exits zero." }, "reasonPattern": "state=unknown", "environment": { "PATH": "${ROOT}/gate-bin:${PATH}", "GITEA_TOKEN": "gate-fixture-token", "GATE_STATUS_JSON": "{\"state\":\"failure\",\"statuses\":[]}" }, "fixture": { "copyPaths": ["packages/mosaic/framework/tools/git"], "writeFiles": [ { "path": ".git/config", "content": "[core]\n\trepositoryformatversion = 0\n\tbare = false\n[remote \"origin\"]\n\turl = https://git.mosaicstack.dev/mosaicstack/stack.git\n" }, { "path": ".git/HEAD", "content": "ref: refs/heads/main\n" }, { "path": ".git/objects/.keep", "content": "" }, { "path": ".git/refs/heads/.keep", "content": "" }, { "path": "gate-bin/curl", "mode": 493, "content": "#!/bin/sh\ncase \"$*\" in\n *'/branches/'*) printf '{\"commit\":{\"id\":\"gate-sha\"}}\\n200' ;;\n *'/commits/'*) printf '%s' \"$GATE_STATUS_JSON\" ;;\nesac\n" } ] } }, { "id": "push-defaults-to-main", "criterionIds": ["QUEUE-GUARD"], "mustFail": true, "required": { "exitCode": 0, "outputPattern": "branch=feat/rm-02-gate-registry" }, "actual": { "exitCode": 0, "outputPattern": "branch=main" }, "defect": { "owner": "RM-03", "reason": "Push purpose defaults to main instead of the acted-on branch." }, "reasonPattern": "purpose=push.*branch=main", "invocation": [ "bash", "packages/mosaic/framework/tools/git/ci-queue-wait.sh", "--purpose", "push", "-t", "1", "-i", "0" ], "environment": { "PATH": "${ROOT}/gate-bin:${PATH}", "GITEA_TOKEN": "gate-fixture-token", "GATE_STATUS_JSON": "{\"state\":\"success\",\"statuses\":[]}" }, "fixture": { "copyPaths": ["packages/mosaic/framework/tools/git"], "writeFiles": [ { "path": ".git/config", "content": "[core]\n\trepositoryformatversion = 0\n\tbare = false\n[remote \"origin\"]\n\turl = https://git.mosaicstack.dev/mosaicstack/stack.git\n" }, { "path": ".git/HEAD", "content": "ref: refs/heads/main\n" }, { "path": ".git/objects/.keep", "content": "" }, { "path": ".git/refs/heads/.keep", "content": "" }, { "path": "gate-bin/curl", "mode": 493, "content": "#!/bin/sh\ncase \"$*\" in\n *'/branches/'*) printf '{\"commit\":{\"id\":\"gate-sha\"}}\\n200' ;;\n *'/commits/'*) printf '%s' \"$GATE_STATUS_JSON\" ;;\nesac\n" } ] } }, { "id": "unknown-option", "criterionIds": ["QUEUE-GUARD", "RM02-CHECK-RIGHT", "GATE-SOURCE-DEPLOYMENT"], "mustFail": true, "invocation": [ "bash", "packages/mosaic/framework/tools/git/ci-queue-wait.sh", "--definitely-unknown" ], "required": { "exitCode": 1, "outputPattern": "Unknown option" }, "actual": { "exitCode": 1, "outputPattern": "Unknown option" }, "reasonPattern": "--definitely-unknown", "fixture": { "copyPaths": ["packages/mosaic/framework/tools/git"], "writeFiles": [] } } ] }, { "id": "hook-pre-commit", "source": ".husky/pre-commit", "invocation": ["sh", ".husky/pre-commit"], "deployment": { "kind": "none", "reason": "Husky dispatches the repository .husky/pre-commit file directly; no copied counterpart exists." }, "inertMutation": { "file": ".husky/pre-commit", "find": "npx lint-staged", "replace": "exit 0", "caseId": "lint-staged-failure", "sandboxFiles": [".husky/pre-commit"], "expected": { "exitCode": 0, "notOutputPattern": "FAKE_NPX_EXIT=19" } }, "cases": [ { "id": "clean-staged-input", "criterionIds": ["HOOK-PRE-COMMIT"], "mustFail": false, "required": { "exitCode": 0 }, "actual": { "exitCode": 0 }, "reasonPattern": "", "environment": { "PATH": "${ROOT}/gate-bin:${PATH}", "FAKE_EXIT": "0" }, "fixture": { "copyPaths": [".husky/pre-commit"], "writeFiles": [ { "path": "gate-bin/npx", "mode": 493, "content": "#!/bin/sh\necho FAKE_NPX_EXIT=$FAKE_EXIT >&2\nexit \"$FAKE_EXIT\"\n" } ] } }, { "id": "lint-staged-failure", "criterionIds": [ "HOOK-PRE-COMMIT", "RM02-CHECK-RIGHT", "RM02-SET-COVERS", "RM02-MODELED-CONSISTENCY" ], "mustFail": true, "required": { "exitCode": 19, "outputPattern": "FAKE_NPX_EXIT=19" }, "actual": { "exitCode": 19, "outputPattern": "FAKE_NPX_EXIT=19" }, "reasonPattern": "FAKE_NPX_EXIT=19", "environment": { "PATH": "${ROOT}/gate-bin:${PATH}", "FAKE_EXIT": "19" }, "fixture": { "copyPaths": [".husky/pre-commit"], "writeFiles": [ { "path": "gate-bin/npx", "mode": 493, "content": "#!/bin/sh\necho FAKE_NPX_EXIT=$FAKE_EXIT >&2\nexit \"$FAKE_EXIT\"\n" } ] } } ] }, { "id": "hook-pre-push", "source": ".husky/pre-push", "invocation": ["sh", ".husky/pre-push"], "deployment": { "kind": "none", "reason": "Husky dispatches the repository .husky/pre-push file directly; no copied counterpart exists." }, "inertMutation": { "file": ".husky/pre-push", "find": "pnpm preflight && pnpm typecheck && pnpm lint && pnpm format:check", "replace": "exit 0", "caseId": "typecheck-failure", "sandboxFiles": [".husky/pre-push"], "expected": { "exitCode": 0, "notOutputPattern": "FAKE_PNPM_FAILURE=typecheck" } }, "cases": [ { "id": "all-subgates-succeed", "criterionIds": ["HOOK-PRE-PUSH"], "mustFail": false, "required": { "exitCode": 0 }, "actual": { "exitCode": 0 }, "reasonPattern": "", "environment": { "PATH": "${ROOT}/gate-bin:${PATH}", "FAIL_PNPM_COMMAND": "none" }, "fixture": { "copyPaths": [".husky/pre-push"], "writeFiles": [ { "path": "gate-bin/pnpm", "mode": 493, "content": "#!/bin/sh\nif [ \"$1\" = \"$FAIL_PNPM_COMMAND\" ]; then echo FAKE_PNPM_FAILURE=$1 >&2; exit 19; fi\nexit 0\n" } ] } }, { "id": "typecheck-failure", "criterionIds": [ "HOOK-PRE-PUSH", "RM02-CHECK-RIGHT", "RM02-SET-COVERS", "RM02-MODELED-CONSISTENCY" ], "mustFail": true, "required": { "exitCode": 19, "outputPattern": "FAKE_PNPM_FAILURE=typecheck" }, "actual": { "exitCode": 19, "outputPattern": "FAKE_PNPM_FAILURE=typecheck" }, "reasonPattern": "FAKE_PNPM_FAILURE=typecheck", "environment": { "PATH": "${ROOT}/gate-bin:${PATH}", "FAIL_PNPM_COMMAND": "typecheck" }, "fixture": { "copyPaths": [".husky/pre-push"], "writeFiles": [ { "path": "gate-bin/pnpm", "mode": 493, "content": "#!/bin/sh\nif [ \"$1\" = \"$FAIL_PNPM_COMMAND\" ]; then echo FAKE_PNPM_FAILURE=$1 >&2; exit 19; fi\nexit 0\n" } ] } } ] } ] }