Gap Analysis Validation — Cross-Document Gap Audit
Date: 2026-11-09 Audience: Platform architects and release engineers Purpose: Validate all gaps mentioned across the D- and S- documents against AGENTS.md mandates, prioritize by criticality, and document the mandate violation for each.
Validation Method
Each gap was extracted from the document set and cross-referenced against the AGENTS.md mandatory architectural mandates. A gap is flagged if it:
- Violates a explicit mandate, OR
- Blocks production readiness, OR
- Represents a previously-deferred item with no clear unblocking path
Categorization by AGENTS.md Mandate
| Mandate | Description | Violating Gaps |
|---|---|---|
| Mandate 1: Zero bespoke tables | NEVER create module-specific tables (e.g. materra_, kazi_). All entities must map to canonical primitives. | Gaps 1, 13, 14 |
| Mandate 2: Declarative-first | Lookups, thresholds, scenarios, templates must NOT be hardcoded in procedural code. Must read from NATS KV at runtime. | Gaps 2, 3, 16, 17 |
| Mandate 3: Fail-closed | Infrastructure errors must return 502/503/422 or throw. Never return synthetic "OPTIMAL"/"APPROVED"/"deterministic_*" fallback. | Gaps 3, 6 |
| Mandate 4: No runtime filesystem reads | Runtime services MUST NEVER use fs.readFile or filesystem paths to read .json lookups or .yaml templates. Only the offline seeder reads from disk. | Gaps 2, 3 |
| Mandate 5: Kestra + Camel for workflow | No FSMs on SurrealDB. Orchestrate via Kestra (:8180) and Apache Camel (:8181) backed by NATS JetStream KV. | Gaps 17 (partial) |
| Mandate 6: Zero silent fallbacks | Any external service call must fail closed. NEVER catch and return synthetic success. | Gaps 3, 6 |
| Mandate 7: Zero synthetic adapter payloads | API routes MUST NEVER invent dummy coordinates, suppliers, org IDs, or fake routes. | Gaps 7, 12 |
| Mandate 8: No fake tests / no code-to-smoke | Tests asserting magic numbers from non-engines are "fake tests." Never write backend code to satisfy them. | Gaps 8 (implied) |
| Mandate 9: Real-infrastructure citation | Before implementing, cite exact real service/port/contract schema. If service doesn't exist, STOP and ask user. | Gaps 17 |
| Mandate 10: No un-production-ready hardcoded metrics | UI cards/dashboards must never display static hardcoded numbers. Must be backed by live data or honest empty states. | Gaps 7, 12 |
Catalog of Validated Gaps
Critical Priority (mandate-violating, blocks production)
GAP-01: Zero bespoke tables violation — kazi and Materra tables not mapped to canonical primitives
- Source: D-13 (KaziSasa): "Zero-bespoke law as stated: all human capital... records map 100% into canonical
claim,truth_node, andintegration_entity(Stratum 12 / Stratum 356), with zerokazi_*tables." Also D-01 §9: "A new vertical that needs a new plane must stop and ask before forking structure." - Mandate violation: Mandate 1 (zero bespoke tables)
- Criticality: BLOCKING — if unaddressed, any new vertical creates forked data models that violate the compose-first rule and make federation/audit non-uniform.
- Current state:
apps/agent-bff/src/kazisasa-bff-routes.jsis a "thin compat shim" with no data-plane logic.datasets/lookups/lookup.kazi*anddatasets/scenarios/returned no files.docs/kazireturned no files. - Unblocking action: Map all KaziSasa entities (health, templates, scenarios, requisitions, solve, insurance-bind, equipment-reserve, intel/stream, vault, leases) to canonical
claimtypes andintegration_entity. Delete anykazi_*tables if they exist. Ensure all routes go through canonical planes.
GAP-02: Runtime filesystem reads — lookups/templates read from disk at runtime
- Source: D-03 §2: "No filesystem reads at runtime. Services read declarative values from the message-bus key-value groups. Files on disk are read only by the offline seeder." Also D-09: "Runtime services must never read lookup/template files from the filesystem."
- Mandate violation: Mandate 4 (no runtime filesystem reads)
- Criticality: BLOCKING — if services read from disk at runtime, it breaks portability, causes failures when disk is unavailable, and violates the declarative-first mandate. The platform must read from NATS JetStream KV buckets (
SOVEREIGN_LOOKUPS,SOVEREIGN_TEMPLATES) at runtime. - Current state: Multiple modules may be reading
.json/.yamlfiles from disk instead of from NATS KV at runtime. The seed scriptscripts/seed-nats-kv-declarative.mjsexists to load these into KV at deploy time, but runtime code may not be using the KV buckets. - Unblocking action: Audit all runtime services (BFFs, engines) to ensure they read configuration/lookups/templates from NATS KV buckets at runtime, not from disk paths. Replace any
fs.readFile/path-based reads with NATS KV bucket reads. Ensure the seeder is the only path that reads from disk.
GAP-03: Fail-closed violations — infrastructure errors returning synthetic success
- Source: D-01 §0 thesis: "When an engine is unavailable the platform fails closed with a typed error and never returns a synthetic success." D-15: "Fail closed. Infrastructure failures return an error or refusal — never a synthetic success object."
- Mandate violation: Mandates 3 and 6 (fail-closed, zero silent fallbacks)
- Criticality: BLOCKING — if any endpoint catches infrastructure errors and returns synthetic success instead of failing closed, it violates the core security and integrity mandates. This has been a specific historical bug (e.g., the
environmentId: environmentId || nullissue in kutuma-api that returned null environment IDs causing 422s). - Current state: Multiple documented cases where infrastructure failures were caught and synthetic values returned (e.g., the LaunchDarkly
withLDProviderwith empty clientSideID, thegetSignedTokenfalling back tonullenvironmentId). - Unblocking action: Audit all infrastructure service calls (SurrealDB, NATS, Solver Gateway, Camel) to ensure errors are NOT caught and synthetic fallbacks returned. Replace
catch -> mock/defaultpatterns with proper error propagation. Every infrastructure call must either succeed or throw/return an error status (402, 422, 502, 503).
GAP-04: Zero synthetic adapter payloads — hardcoded metrics/coordinates in UI/dashboards
- Source: D-01 §7 (money side): "A soft or composed capability never reports a live gate as met merely because the configuration exists." D-15: "No hardcoded card values. Dashboards render live data or an honest empty state."
- Mandate violation: Mandates 7 and 12 (zero synthetic adapter payloads, no hardcoded metrics)
- Criticality: HIGH — dashboards/cards displaying fake numbers destroy trust in the platform. The S-04 week review noted "honest empty states" as the correct approach.
- Current state: The AGENTS.md docs explicitly warn against "fake
98.4%, fakeKES 18,500, fake12 active workers, fake status chips." Some endpoints may still be returning synthetic metrics. - Unblocking action: Audit all UI cards, dashboard panels, and metric displays to ensure they pull from live backend APIs or database queries. Replace any hardcoded numbers with either live data or honest empty states/skeleton loaders. Implement the
invent_refuse_liverefusal pattern where live data is unavailable.
GAP-05: No fake tests / don't code to satisfy smoke-screen tests
- Source: D-01 §0: "If an existing
.spec.tsor test script asserts magic numbers (32.4m, 17.6m, total_allocated_kg: 18500) that do not come from a real infrastructure engine, STOP and flag the test as a fake test." D-15: "Fake-test prohibition. Tests asserting magic numbers from non-existent engines are fakes; never code to satisfy them — flag them." - Mandate violation: Mandate 8 (no fake tests)
- Criticality: HIGH — if developers write code to produce hardcoded magic numbers just to make tests pass, the platform accumulates technical debt and loses integrity.
- Current state: The D-11 spec index mentions cover tests that assert parity between live routes and documented paths. Some tests may have magic numbers that don't come from real engines.
- Unblocking action: Review all test files for magic numbers not derived from real engine output. Flag any as fake tests. Rewrite tests to either use real engine data or assert structural contracts rather than specific values. Never write backend code or seed fake lookup numbers just to produce a test's hardcoded magic numbers.
High Priority (blocking critical functionality)
GAP-06: Trusted timestamping on finalize (FCT-18 deferred)
- Source: D-08 FCT-18: "Trusted timestamp on finalise. DEFERRED." D-08 soft cell semantics: "Live production apply behind live and policy gates, with runbook."
- Mandate violation: Related to Mandate 3 (fail-closed) and the config track's need for audit integrity.
- Criticality: HIGH — without trusted timestamps, the signed receipt chain for config track finalize cannot provide non-repudiation. This is a deferred item blocking production rollout of config changes with full audit trails.
- Current state: Card is marked DEFERRED; no trusted timestamp infrastructure exists.
- Unblocking action: Investigate timestamp-authority integration options. If no external timestamp authority is available, design an internal deterministic timestamp mechanism bound to the receipt claim. Unblock when a timestamp-authority customer arrives or an internal mechanism is designed.
GAP-07: Live money movement / FINMON-16 gating
- Source: D-06 FINMON-16: "Live estate desk: real invoicing plus real wallet credits plus settlement events. Gated on operations: production keys plus human approval plus the ledger; no soft path reaches settlement." S-02: "Live money movement opens until the finance gate lifts — needs finance keys + human approval + payments ledger."
- Mandate violation: Related to Mandate 3 (fail-closed for financial operations) and Mandate 10 (no hardcoded card/metric values).
- Criticality: HIGH — live money movement is gated behind operations approval. The soft path exists (FINMON-01 through FINMON-20 are all "DONE" status), but the live desk remains gated. This is the boundary between soft monetisation and live billing.
- Current state: FINMON-16 is "GATED" status. The soft path (subscriptions, splits, entitlements, wallet credits in soft form) is fully done. Live movement needs finance keys, human approval, and the payments ledger.
- Unblocking action: Document the exact gating conditions. Create a runbook for when the finance gate lifts. Ensure the soft path is fully functional and independently verifiable while the live gate remains closed. Backfill
members.environmentIdin MongoDB for each org's first environment as a prerequisite.
GAP-08: Emergency-call location format deferred
- Source: S-02: "Blocker: emergency-call location format is deferred until a public-safety answering point (emergency call center) is the buyer." D-13: "The optional location pack for public-safety jurisdictions is deferred until a public-safety customer exists."
- Mandate violation: Related to Mandate 9 (real-infrastructure citation) — this needs a real customer before designing.
- Criticality: MEDIUM — this is a customer-driven blocker, not a technical debt issue. The design cannot proceed without a public-safety customer.
- Current state: Deferred indefinitely until a PSAP customer arrives.
- Unblocking action: Monitor for PSAP customer engagement. When one arrives, design the emergency-call location format as a pack configuration in the scenarios plane. Until then, document the deferration and ensure no code depends on this feature.
GAP-09: Six-stage promotion lifecycle from draft through live to retired
- Source: D-01 §§gaps: "the six-stage promotion lifecycle from draft through live to retired has dual control documented but no single running workflow for every fragment."
- Mandate violation: Related to Mandate 5 (Kestra + Camel for workflow orchestration) — the lifecycle stages need a workflow engine backing.
- Criticality: MEDIUM — the lifecycle logic exists in dual control (draft → commit → project pattern per D-08 FCT-18), but there's no single running workflow that covers all fragments. This means some claim types may not have their lifecycle fully automated.
- Current state: The dual-control flow (draft → quorum → commit → compare-and-swap → project) is documented and implemented for split profiles (D-08). But the six-stage promotion (draft through live to retired) has no running workflow for every fragment.
- Unblocking action: Design the six-stage workflow in Kestra or Camel, backed by the scenarios plane. Ensure every claim type fragment has a complete lifecycle workflow. Test the workflow end-to-end.
GAP-10: Break-glass elevation does not open proof or file corrective action
- Source: D-01 §§gaps: "break-glass elevation does not yet open proof or file corrective action and stays bounded by short time-to-live and expiring roles."
- Mandate violation: Related to Mandate 6 (fail-closed) and Mandate 9 (real-infrastructure citation for break-glass patterns).
- Criticality: MEDIUM — break-glass scenarios are emergency overrides. The system should either (a) open proof recording when break-glass is invoked, or (b) file corrective action automatically. Currently neither exists.
- Current state: Break-glass elevation exists but does not trigger proof recording or corrective action filing. It's bounded by short TTL and expiring roles only.
- Unblocking action: Design a break-glass workflow that (a) records a proof event when invoked, (b) files a corrective action claim, (c) bounds the TTL and role expiry. Implement and test.
GAP-11: Customer-held seal, certification, and signing root not enforced
- Source: D-01 §§gaps: "the customer-held seal, customer certification, and customer-held signing root are not yet enforced."
- Mandate violation: Related to Mandate 9 (real-infrastructure citation) and Mandate 7 (no synthetic adapter payloads — customer-held crypto keys are real infrastructure).
- Criticality: MEDIUM — these are cryptographic infrastructure elements that, if not enforced, could allow undetected tampering. But their absence doesn't block core platform function.
- Current state: Not yet deployed. The design stopped at the mandate boundary and asked the user.
- Unblocking action: Either (a) design and deploy the customer-held seal/certification/signing root infrastructure, or (b) explicitly document that these are out of scope for this release and the platform operates without them. Stop and ask the user if neither is acceptable.
GAP-12: Cross-cutting lint for honesty invariants not enforced per-module
- Source: D-15: "Invariants are enforced per-module (each response carries
invent_refuse_live/live_gate_metwhere relevant); there is no cross-cutting lint that catches a future module missing them." - Mandate violation: Related to Mandate 10 (no un-production-ready hardcoded card/metric values) and Mandate 12 (consistent observability).
- Criticality: MEDIUM — each module carries the refusal/met flags, but without cross-cutting lint, a new module could ship without them and the non-compliance would go undetected.
- Current state: Per-module enforcement exists but no lint rule ensures new modules comply.
- Unblocking action: Create an ESLint-like cross-cutting rule that checks all module responses carry the required
invent_refuse_liveandlive_gate_metflags (where applicable). Integrate into the CI pipeline. Document the invariant for all new modules.
GAP-13: Thin Kazi coverage — missing lookup and scenario packs
- Source: D-13: "Thin coverage:
datasets/lookups/lookup.kazi*and kazi scenario packs underdatasets/scenarios/listed via glob returned no files; no kazi lookup or scenario pack content was verified in the read set." - Mandate violation: Related to Mandate 2 (declarative-first — packs should be declarative, not missing) and Mandate 1 (zero bespoke tables).
- Criticality: HIGH — KaziSasa is a major vertical (V8 in the commercial catalog). If its lookup tables and scenario packs are missing, the vertical cannot function properly.
- Current state: The verify-kazi-headless-api.mjs script exists and runs 9/9 gates, but the lookup and scenario pack files are not present in the read set. The shim routes through ERPNext REST via Camel, but the declarative packs may be incomplete.
- Unblocking action: Create the missing
datasets/lookups/lookup.kazi*files. Create kazi scenario packs underdatasets/scenarios/. Ensure the verify-kazi-headless-api.mjs script can run fully against real infrastructure. Map all KaziSasa endpoints to canonical claim types.
GAP-14: MARS schema fork — large database/schema/mars/ violation
- Source: D-13: "MARS must be a configuration of Sovereign OS, not a parallel product database"; "violation recorded: large
database/schema/mars/, EMT tables,killbill_mars_*." - Mandate violation: Mandate 1 (zero bespoke tables) — the most fundamental mandate.
- Criticality: BLOCKING — if MARS has grown its own schema fork (
database/schema/mars/withEMT tables,killbill_mars_*), this directly violates the zero-bespoke-tables mandate and creates a second data model that fractures the platform. - Current state: A violation has been "recorded" but not resolved. The MARS-CFG backlog has many TODO items.
- Unblocking action: Audit
database/schema/mars/and identify allmars_andkillbill_mars_tables. Migrate any expressively mappable entities to the canonical primitives (claim,truth_node/truth_edge,resource,integration_entity). Delete or rename tables that violate the mandate. Ensure MARS operates as a configuration pack on shared engines, not a parallel database. Update the MARS-CFG backlog accordingly.
GAP-15: Optional location pack for public-safety jurisdictions deferred
- Source: D-07: "The optional location pack for public-safety jurisdictions is deferred until a public-safety customer exists." D-13: Same mention.
- Mandate violation: Related to Mandate 9 (real-infrastructure citation) — design cannot proceed without a customer.
- Criticality: MEDIUM — customer-driven deferration. The design waits on a customer before proceeding.
- Current state: Deferred. The location pack would add geospatial capability for public-safety use cases.
- Unblocking action: Monitor for public-safety customer engagement. When one arrives, design the location pack as a declarative configuration in the scenarios plane with geospatial NATS subject routing. Until then, document the deferration.
GAP-16: Integrator docs journey ladder unchecked in sourcing acceptance
- Source: D-07: "The integrator docs journey ladder plus event list plus disclosure modes remain unchecked in the sourcing acceptance."
- Mandate violation: Related to Mandate 2 (declarative-first — journey ladders should be declarative configs) and Mandate 4 (no runtime filesystem reads).
- Criticality: MEDIUM — journey ladders are the path an integrator follows. If they're unchecked, integrators may follow incorrect paths.
- Current state: Unchecked. The journey ladder should be a declarative config in the scenarios plane or NATS KV.
- Unblocking action: Design the journey ladder as declarative configuration. Check it against actual integrator flows. Ensure it's maintained as code, not hardcoded.
GAP-17: Wage-floor Option A / Option B semantics not verified against real solver
- Source: D-13: "Wage-floor Option A / Option B semantics and the
branch_and_bound 1.4.0solver capability are asserted in AGENTS.md only; theprocurement.basket_split@1decision-request contract and a live:3070solve were not executed in this read." - Mandate violation: Related to Mandate 9 (real-infrastructure citation) — need to cite the real solver-gateway :3070 contract.
- Criticality: HIGH — the wage floor semantics directly affect how claims/procurement claims are resolved. If the semantics are wrong or undefined, the solver cannot make correct allocations.
- Current state: Option A (default max wage floor resolution across facets) and Option B (strict wage parity conflict detection with HTTP 422) are asserted in AGENTS.md only. The
procurement.basket_split@1contract and live :3070 solve were not verified. - Unblocking action: Execute the verification suite
scripts/verify-kazi-solver-gateway.mjs(5/5 gates) against the real solver gateway :3070. Document the wage-floor Option A and Option B semantics from the solver gateway response. Ensure theprocurement.basket_split@1decision-request contract is satisfied. If the solver gateway cannot satisfy the contract, stop and ask the user before proceeding.
GAP-18: Verifier suites not fully executed against real infrastructure
- Source: D-13: "Verification suites named in AGENTS.md:
scripts/verify-kazi-headless-api.mjs(9/9),scripts/verify-kazi-solver-gateway.mjs(5/5 against real :3070),scripts/verify-novu-kv-templates.mjs(3/3),scripts/verify-ai-prompts-kv.mjs(4/4)" — but the read did not execute these. - Mandate violation: Related to Mandate 9 (real-infrastructure citation) — gaps exist because verifiers weren't run.
- Criticality: HIGH — the verification suites are the gate against which the platform's real infrastructure is validated. If they weren't executed, the gaps they would reveal are unknown.
- Current state: The scripts exist and the gate counts are documented, but they weren't executed in this read session.
- Unblocking action: Execute all four verification suites against real infrastructure:
scripts/verify-kazi-headless-api.mjs→ 9/9 gatesscripts/verify-kazi-solver-gateway.mjs→ 5/5 against real :3070scripts/verify-novu-kv-templates.mjs→ 3/3scripts/verify-ai-prompts-kv.mjs→ 4/4
Document the results and address any failures.
Priority Summary
| Priority | Gap ID | Mandate Violated | Blocking? | Effort |
|---|---|---|---|---|
| CRITICAL | GAP-01 | Mandate 1 (zero bespoke tables) | YES | High |
| CRITICAL | GAP-02 | Mandate 4 (no runtime FS reads) | YES | High |
| CRITICAL | GAP-03 | Mandates 3, 6 (fail-closed) | YES | High |
| CRITICAL | GAP-04 | Mandates 7, 12 (no synthetic payloads) | YES | Medium |
| CRITICAL | GAP-05 | Mandate 8 (no fake tests) | YES | Medium |
| HIGH | GAP-06 | Config track audit integrity | YES | Medium |
| HIGH | GAP-07 | Live money movement gating | YES | Medium |
| HIGH | GAP-13 | Kazi vertical completeness | YES | High |
| HIGH | GAP-14 | MARS schema fork (zero-bespoke) | YES | Very High |
| HIGH | GAP-18 | Verifier suites not executed | YES | Medium |
| MEDIUM | GAP-08 | Emergency-call location | NO (customer-driven) | Low |
| MEDIUM | GAP-09 | Six-stage promotion lifecycle | NO | High |
| MEDIUM | GAP-10 | Break-glass elevation | NO | Medium |
| MEDIUM | GAP-11 | Customer-held crypto roots | NO | Medium |
| MEDIUM | GAP-12 | Cross-cutting lint for invariants | NO | Low |
| MEDIUM | GAP-15 | Location pack for public-safety | NO (customer-driven) | Low |
| LOW | GAP-16 | Journey ladder unchecked | NO | Low |
| LOW | GAP-17 | Wage-floor semantics | NO (needs solver verification) | High |
Next Step: Begin remediation with CRITICAL gaps, starting with GAP-01 (zero bespoke tables) and GAP-03 (fail-closed), as these are the most foundational mandates.