Skip to content

feat: wire defineContract invariant check() functions into runtime enforcement #75

Description

@stackbilt-admin

Problem

The `defineContract` invariants defined in all four contract files are pure declarative objects — they are not imported or called by any runtime route handler or service layer. This means:

  • `AgendaItemContract.invariants` (e.g. `resolved_has_timestamp`) — not enforced at write time
  • `CCTaskContract.invariants` (e.g. `proposed_task_needs_approval`, `completed_has_timestamp`) — not enforced at write time
  • `GoalContract.invariants` (e.g. `completed_has_timestamp`) — not enforced at write time
  • `MemoryEntryContract.invariants` (e.g. `refuted_entry_not_canonical`, `high_confidence_for_canonical`) — not enforced at write time

Contracts currently serve as governance/specification artifacts only. Tests exist to verify the invariant `check()` functions themselves (added in OTDD sweep on `auto/feature/issue-72`), but production operations can violate them without any error.

Note: `executor-router.contract.ts` invariants (I1–I6) are structural validators called explicitly by tests — they are in a better state, but still not called automatically at route dispatch time.

Proposed solution

Add a thin service-layer guard that runs all applicable invariant `check()` functions before committing D1 writes. Options:

Option A — Inline at each route handler: Call `Contract.invariants.filter(i => i.appliesTo.includes(op)).forEach(i => { const r = i.check(entity); if (r !== true) throw new Error(r); })` before each D1 mutation.

Option B — Generic `enforceInvariants(contract, operation, entity)` helper: A single reusable function that accepts a contract, the operation name, and the entity object; iterates `appliesTo` filtering; throws a structured error on violation. Route handlers call this once per mutation.

Option C — Middleware/hook layer: If routes consistently go through a service object, enforce at that boundary rather than in individual route handlers.

Option B is recommended — minimal abstraction, easy to test, applies uniformly across all `defineContract` domains.

Acceptance criteria

  • A helper (or equivalent inline check) enforces invariants before D1 writes for all four `defineContract` domains
  • A route-level integration test confirms that a violating payload returns an appropriate error (not a silent DB write)
  • State machine transition guards (`AND status = 'active'` pattern already applied to `resolveAgendaItem`) are consistently applied to all terminal-state operations across all domains
  • No regression in the 1767-test suite

Context

Discovered during OTDD sweep (aegis-oss branch `auto/feature/issue-72`). The `resolveAgendaItem` terminal-state guard was already fixed in that branch as a direct implementation bug. This issue tracks the broader systematic gap.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions