{"record":{"id":"efb13e7527c153f3","repo":"ruvnet/ruflo","slug":"cannot-remove-immutable-invariant-id","errorCode":null,"errorMessage":"Cannot remove immutable invariant: ${id}","messagePattern":"Cannot remove immutable invariant: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/guidance/src/meta-governance.ts","lineNumber":328,"sourceCode":"  }\n\n  /**\n   * Add a constitutional invariant\n   */\n  addInvariant(invariant: ConstitutionalInvariant): void {\n    this.invariants.set(invariant.id, invariant);\n  }\n\n  /**\n   * Remove an invariant (only if not immutable)\n   */\n  removeInvariant(id: string): boolean {\n    const invariant = this.invariants.get(id);\n    if (!invariant) {\n      return false;\n    }\n    if (invariant.immutable) {\n      throw new Error(`Cannot remove immutable invariant: ${id}`);\n    }\n    return this.invariants.delete(id);\n  }\n\n  /**\n   * Check all constitutional invariants against current state\n   */\n  checkAllInvariants(state: GovernanceState): InvariantReport {\n    const results: Array<{ invariant: ConstitutionalInvariant; result: InvariantCheckResult }> = [];\n    let allHold = true;\n\n    for (const invariant of this.invariants.values()) {\n      const result = invariant.check(state);\n      results.push({ invariant, result });\n      if (!result.holds) {\n        allHold = false;\n      }\n    }","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/guidance/src/meta-governance.ts#L310-L346","documentation":"MetaGovernor.removeInvariant(id) throws when the targeted constitutional invariant was registered with immutable: true. This is deliberate tamper protection: immutable invariants are the constitution's floor and the normal API offers no flag, override, or force option to remove them. Unknown IDs return false instead of throwing.","triggerScenarios":"Calling removeInvariant() on a core/default invariant flagged immutable; calling it on an invariant you yourself added with immutable: true; cleanup code that tries to sweep all invariants via getInvariants() without checking the flag.","commonSituations":"Governance tests that add invariants then try to tear them down; runtime code attempting to loosen constitutional constraints after deployment; refactors that assume all invariants are removable.","solutions":["Do not remove it — express the change as a new invariant via addInvariant that supersedes the old rule","Inspect governor.getInvariants() first and skip entries with immutable: true","If you own the invariant definition and genuinely need removability, construct the MetaGovernor with that invariant registered as immutable: false from the start","Reserve removeInvariant for non-immutable, operational invariants only"],"exampleFix":"// before\ngovernor.removeInvariant('no-unverified-write'); // immutable -> throws\n// after\nconst inv = governor.getInvariants().find(i => i.id === 'no-unverified-write');\nif (inv?.immutable) {\n  governor.addInvariant({ ...inv, id: 'no-unverified-write-v2', description: 'Relaxed rule' });\n} else {\n  governor.removeInvariant('no-unverified-write');\n}","handlingStrategy":"type-guard","validationCode":"const target = governor.getInvariants().find(i => i.id === id);\nif (!target) return false; // removeInvariant returns false for unknown ids\nif (target.immutable) {\n  throw new Error(`Invariant ${id} is immutable; supersede it with addInvariant instead`);\n}\nreturn governor.removeInvariant(id);","typeGuard":"function isRemovableInvariant(governor: MetaGovernor, id: string): boolean {\n  const inv = governor.getInvariants().find(i => i.id === id);\n  return inv !== undefined && inv.immutable === false;\n}","tryCatchPattern":null,"preventionTips":["Model constitutional changes as new superseding invariants, not removals","Register operational invariants with immutable: false if teardown must be possible","Audit getInvariants() for immutable entries before writing cleanup code"],"tags":["guidance","meta-governance","invariant","immutability","constitution"],"backgroundTag":"immutable-constraint-violation","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}