{"record":{"id":"bced7e9c4818c282","repo":"Yeachan-Heo/oh-my-codex","slug":"final-architecture-invariant-gate-requires-archite","errorCode":null,"errorMessage":"Final architecture-invariant gate requires architectureInvariantGate.status=\"passed\"; record blocker-resolution work for unproved invariants.","messagePattern":"Final architecture-invariant gate requires architectureInvariantGate\\.status=\"passed\"; record blocker-resolution work for unproved invariants\\.","errorType":"validation","errorClass":"UltragoalError","httpStatus":null,"severity":"error","filePath":"src/ultragoal/artifacts.ts","lineNumber":1637,"sourceCode":"    }\n  }\n  return uniqueRequiredArchitectureInvariants(invariants);\n}\n\nasync function collectRequiredArchitectureInvariants(cwd: string): Promise<RequiredArchitectureInvariant[]> {\n  const briefInvariants = extractArchitectureInvariantsFromBrief(await readFile(ultragoalBriefPath(cwd), 'utf-8'));\n  const steeringInvariants = extractArchitectureInvariantsFromAcceptedSteering(await readSteeringLedgerEntries(cwd));\n  return uniqueRequiredArchitectureInvariants([...briefInvariants, ...steeringInvariants]);\n}\n\n\nfunction validateArchitectureInvariantGate(gate: Partial<UltragoalQualityGate>, requiredInvariants: readonly RequiredArchitectureInvariant[]): void {\n  const invariantGate = gate.architectureInvariantGate;\n  if (!invariantGate || typeof invariantGate !== 'object') {\n    throw new UltragoalError('Final quality gate is missing architectureInvariantGate evidence; include derived architecture/domain invariants, source artifacts, implementation/test/review evidence, or record final blockers for unproved invariants.');\n  }\n  if (invariantGate.status !== 'passed') {\n    throw new UltragoalError('Final architecture-invariant gate requires architectureInvariantGate.status=\"passed\"; record blocker-resolution work for unproved invariants.');\n  }\n  if (!Array.isArray(invariantGate.sourceArtifacts)) {\n    throw new UltragoalError('Final architecture-invariant gate requires architectureInvariantGate.sourceArtifacts.');\n  }\n  const sourceArtifacts = invariantGate.sourceArtifacts.map((source) => assertNonEmpty(source, 'architectureInvariantGate.sourceArtifacts[]'));\n  for (const required of requiredInvariants) {\n    if (!sourceArtifacts.some((source) => sourceReferencesArtifact(source, required.sourceArtifact))) {\n      throw new UltragoalError(`Final architecture-invariant gate sourceArtifacts must include required invariant source artifact: ${required.sourceArtifact}`);\n    }\n  }\n  assertNonEmpty(invariantGate.evidence, 'architectureInvariantGate.evidence');\n  if (!Array.isArray(invariantGate.invariants)) {\n    throw new UltragoalError('Final architecture-invariant gate requires architectureInvariantGate.invariants.');\n  }\n  const provided = new Map<string, UltragoalArchitectureInvariantEvidence[]>();\n  for (const invariant of invariantGate.invariants) {\n    if (!invariant || typeof invariant !== 'object') throw new UltragoalError('Final architecture-invariant gate invariants must be objects.');\n    const record = invariant as Partial<UltragoalArchitectureInvariantEvidence> & { blockers?: unknown };","sourceCodeStart":1619,"sourceCodeEnd":1655,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/ultragoal/artifacts.ts#L1619-L1655","documentation":"The architectureInvariantGate was provided but its status is not 'passed'. The final gate treats unproved invariants as unresolved: you must either prove them (status='passed' with supporting evidence) or do blocker-resolution work first.","triggerScenarios":"Submitting a final gate with architectureInvariantGate.status set to 'blocked', 'pending', or omitted, while still attempting to finalize the plan.","commonSituations":"Marking invariants as blocked during a mid-flight check and forgetting to flip status before finalizing; automation copying a draft gate snapshot; misunderstanding that recorded blockers are acceptable mid-plan but not at finalization.","solutions":["Resolve the outstanding invariants and set architectureInvariantGate.status = 'passed'","Complete the blocker-resolution work recorded in the gate, then update status and evidence","If the plan genuinely cannot pass, keep it unfinalized (or reopen it) rather than forcing a non-passed final gate","Add a pre-finalize assertion in your pipeline that gate.architectureInvariantGate?.status === 'passed'"],"exampleFix":"// before\narchitectureInvariantGate: { status: 'blocked', sourceArtifacts: ['docs/i.md'], evidence: 'x', invariants: [] }\n\n// after\narchitectureInvariantGate: { status: 'passed', sourceArtifacts: ['docs/i.md'], evidence: 'invariants proved via tests + review', invariants: [] }","handlingStrategy":"validation","validationCode":"if (gate.architectureInvariantGate?.status !== 'passed') throw new Error('resolve invariant blockers before finalizing');","typeGuard":"function invariantGatePassed(gate: UltragoalQualityGate): boolean { return gate.architectureInvariantGate?.status === 'passed'; }","tryCatchPattern":null,"preventionTips":["Run a pre-finalize assertion that all gate sections have status 'passed'","Treat 'blocked' as a stop signal: do blocker-resolution work first","Don't reuse draft gate snapshots in finalization"],"tags":["ultragoal","quality-gate","status-not-passed","finalize"],"backgroundTag":"gate-status-check-failed","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}