KB-6CC7

Module Contract Standard v1 — minimum standard for a lawful module (DRAFT)

13 min read Revision 1
laws-newmodule-contractstandardv1draftforbidden-patterns2026-06-12

Module Contract Standard v1

Status: DRAFT — not enacted. Defines the minimum standard for a lawful module under the modular architecture (HP v4.7 DRAFT, Điều M-1..M-6). Schemas here are normative once enacted; until then they are the working v1 proposal. Date: 2026-06-12.

Design lineage (deliberate reuse, not invention): FIX7 manifest.json (authority strings, denial flags, hash pins, mutation ledger, packet_tree = sha256(HASH_MANIFEST.txt)), O11 patch-as-information-unit (patch.meta.yaml, trust ladder, reject-unread on missing meta), Đ41 §2A task ledger + S0–S5 DB classes, TKT base policies (bad-input probes, evidence ceiling, no PASS-token leakage), Đ30/Đ31 contract files (owner/tier/enabled/grace), Đ44 Family Registry/SCMR (envelope + conformance), Đ35 paired-DOT doctrine.

All five artifacts are data (JSON/YAML), machine-validated by a fail-closed checker. Prose may accompany them; prose never substitutes. NT14 test applies: each artifact must answer — where is the data, who acts, when does it run, what thresholds, how is it checked, what happens on failure.


1. MODULE_CONTRACT.v1 — what the module promises

contract_id:            <module_id>.contract            # immutable
contract_version:       MAJOR.MINOR                     # MAJOR = breaking (Class C), MINOR = compatible (Class B)
module_id:              <snake_case, = family_code>     # namespace prefix for all module-local IDs
operations:                                             # exposed surface — the ONLY legal entry points
  - op_id:              <module_id>.<op_name>
    kind:               pg_function | rest_endpoint | dot_pair | event | view
    input_schema:       <JSON Schema ref + sha256>
    output_schema:      <JSON Schema ref + sha256>
    errors:             [<error_code>: <semantics>]
    idempotency:        idempotent | at_least_once | exactly_once_keyed
    timeout_ms:         <int>
    fallback:           degrade | queue | fail          # consumer-visible failure behavior
invariants:                                             # machine-checkable promises (SQL/check refs)
  - inv_id, statement, check_ref
authority_contract:                                     # what this module may NEVER do (deny-list, fail-closed)
  denied:               [production_write, ddl, secrets_read, approval_author,
                         kernel_registry_write, other_module_internals, ...]
  granted_scopes:       [<explicit narrow grants, each with grantor + expiry>]
mutation_contract:                                      # the ONLY state this module writes
  writes:
    - target:           <physical_target_ref>           # pg.<db>.<schema>.<table> | kb.<path> | qdrant.<collection>
      via:              <op_id | dot_code>              # never direct/ad-hoc
      dot_pair:         <DOT-XXX primary / DOT-YYY checker>   # NT12 within scope
rollback_contract:
  unit:                 per_change                      # every promoted change reversible on its own
  method:               reverse_patch | compensating_op | snapshot_restore
  proof_required:       staging                         # PROVEN_IN_STAGING before promotion (kernel doctrine)
  max_rollback_time:    <duration>
evidence_contract:
  test_result_required: true                            # MODULE_TEST_RESULT.v1 per promotion
  bad_input_min_classes: 8                              # see §6
  evidence_ceiling:     L0..L3                          # TKT levels; L4+ claims forbidden
compatibility:
  provides:             <contract_version>
  consumes:             [{module_id, contract_version_pin: ">=X.Y <X+1"}]
  deprecation_policy:   <window + migration note required for Class C>
promotion_policy:
  classes_allowed:      [A, B, C]                       # D/E never originate in a module lane
  level_map:            {A: 1, B: 2, C: 3}              # minimum pipeline level per class
contract_hash:          sha256(<canonical serialization>)

2. MODULE_MANIFEST.v1 — what the module is

manifest_version:       1
module_id:              <id>
module_version:         <semver>
status:                 proposed | active | deprecated | retired
owner:                  {seat: <Đ37 agency/person>, contact: <ref>}
contract_pointer:       <kb path or pg ref>
contract_hash:          <sha256>
module_registry_pointer: <pg.<db>.<schema> | kb.<path>>      # the module's own registry slice
module_registry_hash:   <tree/content hash>                   # drift-checked (paired DOT)
declared_surfaces:                                            # diffable boundary — classifier input
  repo_paths:           [modules/<module_id>/**]
  kb_paths:             [knowledge/<...>/**]
  pg_objects:           [<tables/functions/views owned>]
  dot_codes:            [DOT-...]
  routes:               [/...]
dependencies:           [{module_id, contract_version_pin}]   # contracts only, never internals
sandbox:
  db_access_class_max:  S2                                    # Đ41 ceiling for module lanes
  deny_charter_ref:     <path>                                # O11-style, fail-closed
promotion_state:        L0 | L1 | L2 | L3 | L4
compatibility_state:    compatible | degraded | incompatible  # computed, not declared
aggregates:                                                   # published rollups for global pivots/Đ43
  counts:               {<kind>: <int>, ...}
  last_published_at:    <ts>
envelope_hash:          sha256(HASH_MANIFEST.txt)             # FIX7 packet_tree convention

The global registry stores exactly this envelope (plus kernel bookkeeping). Internal objects stay in the module registry slice (HP v4.7 Điều M-5.3 globalization test: cross-module / authority-bearing / production-bearing / kernel-bearing only).

3. MODULE_TEST_RESULT.v1 — proof per promotion

module_id / module_version / contract_hash               # binds result to exact contract
suite:
  local_tests:          {total, passed, failed, skipped(reason required)}
  contract_tests:       {schema_validation, invariant_checks, surface_diff_check: PASS|FAIL}
  bad_input_probes:     {classes_covered: [...], total, fail_closed, any_fail_open: false,   # MUST be false
                         detector_correctness_verified: true, pass_token_leak_check: PASS}
  consumer_retests:     [{module_id, pin, result}]        # Class B/C only
evidence_level_claimed: L0 | L1 | L2 | L3                 # ceiling; higher claims auto-FAIL
exit_codes_ref:         <byte-stable exit_codes.json>
result:                 PASS | FAIL | BLOCKED_WITH_EXACT_GAP   # Đ41 vocabulary; no other verdicts
result_hash:            sha256(...)

BLOCKED_WITH_EXACT_GAP is the only legal substitute for missing tests, and it must name the exact gap (Đ41 §2A rule).

4. MODULE_PROMOTION_PACKET.v1 — what crosses a lane gate

A directory/KB subtree following the FIX7 skeleton, minimum members:

File Content
manifest.json MODULE_MANIFEST.v1 snapshot + final_status + explicit denial flags (production_mutation:false, …) + consumed-input hash pins + executed-mutations ledger (before/after sha256 + revision)
MODULE_TEST_RESULT.json §3 artifact
MODULE_ROLLBACK.json §5 artifact incl. staging proof refs
HASH_MANIFEST.txt + packet_tree.sha256 per-file sha256; tree = sha256(HASH_MANIFEST.txt)
commands.sh / RERUN.sh self-verify + fresh-from-source byte-exact reconstruction
class_decision.json classifier output: computed class, inputs (diff summary, contract delta), classifier version+hash
consumer sign-offs Class C only: one signed ack per affected consumer owner

Class A/B anti-ceremony cap (HP v4.7 Điều M-3.4): for Class A, only manifest.json, MODULE_TEST_RESULT.json, and MODULE_ROLLBACK.json (with class_decision.json generated automatically) may be required. Demanding more is itself a violation; expanding the required set is a Class D change.

5. MODULE_ROLLBACK.v1 — local rollback as data

change_ref:             <patch/packet id>
method:                 reverse_patch | compensating_op | snapshot_restore
artifacts:              [<reverse patch / compensating script refs + sha256>]
staging_proof:
  performed_at:         <ts>
  environment:          <mktemp path | sandbox db/schema | sandbox_run_id>
  sequence:             baseline → apply → rollback → byte-exact-to-pin verify
  verdict:              PROVEN_IN_STAGING                  # required before promotion
  validator:            <ref>                              # must gate ROLLBACK_APPLY_DID_NOT_MUTATE
                                                           # and ROLLBACK_NOT_RESTORED_TO_PIN
production_applicability: NOT_APPLICABLE | <per-action grant ref>   # default NOT_APPLICABLE
max_execution_time:     <duration>
cleanup_command:        <one command>                      # Đ41 S2 rule, verified evidence

6. Required capabilities of a lawful module

  1. Input/output adapter: all external interaction through declared operations validating against published schemas; raw access to module internals from outside = violation (both sides).
  2. Isolated namespace: all module-local IDs carry the module_id prefix; no arbitrary global-ID minting; global IDs only via kernel birth/registration paths.
  3. Contract tests: schema validation + invariant checks + surface-diff check, runnable by one command, exit-code stable.
  4. Bad-input tests: mandatory probe suite covering at least these classes — omitted required file, tampered hash, fabricated base/pin, PASS-string injection, schema-invalid input at each adapter, out-of-scope diff (boundary escape), path traversal/symlink escape, unauthorized-surface write attempt. Requirements: 100% fail-closed, any_fail_open=false, detector-correctness (probe fails for the right reason), no success-token leakage in names/output.
  5. Compatibility declaration: provides/consumes pins per §1; computed compatibility_state maintained by the drift-checker DOT pair.
  6. Promotion class discipline: every change carries a computed class_decision.json; the module never self-declares its class.
  7. Paired checker: at least one DOT pair (writer + checker) per mutation target (NT12 in scope); an idle checker is healthy, a missing one is illegal.

7. Forbidden patterns (fail-closed; any occurrence = violation, packet rejected unread)

# Forbidden pattern Why / enforcement
F1 Direct global-registry write without adapter (INSERT into Family Registry/collection_registry/dot_tools/birth_registry/normative tables from module code) Kernel registries are written only via kernel paths (birth functions, registered DOTs, APR). Checker: mutation_contract targets ∩ kernel tables = ∅
F2 Direct production surface call (prod PG, Directus admin, deploy, REAL_RUN, QT001, permits, cutover, prod toggles) Modules end at S2. Production = Class E lane with per-action Owner grants. Probe class in §6.4
F3 Dependency on another module's internal files/tables/functions Contracts only. Checker: imports/refs resolved against consumed contracts; anything else fails
F4 Undeclared shared mutable state (shared tables, files, caches not in any mutation_contract) Two manifests claiming the same write target without a bus contract = both degraded; writes to undeclared targets = reject
F5 Arbitrary global object ID creation (minting codes/addresses outside the module namespace without kernel birth) Identity is kernel authority (Đ0-G). Namespace-prefix check + birth-path audit
F6 Self-authorized authority changes (module editing its own authority_contract, granted_scopes, deny charter, class mapping, or approver routing) Authority changes are Class D minimum, decided outside the module. Contract checker pins authority sections to the last externally-approved hash
F7 Self-declared blast-radius class or evidence level above ceiling (L4+) Classifier output only; TKT overclaim rule — auto-FAIL
F8 Sandbox→prod leakage: prod secrets/roles/network in module env; unverified cleanup; untagged sandbox rows Đ41 S2 + O11 charter; scrubbed-env requirement
F9 PASS-token leakage / probe suites that cannot fail TKT detector-correctness rule; suite with any_fail_open=true is itself a FAIL

8. Minimum lifecycle of a lawful module

proposed (envelope registered, contract v0, maturity M0) → active (contract v1 enacted-for-module, checker pair live in block mode, L1+ promotion passed) → deprecated (no new consumers; existing pins honored through deprecation window) → retired (preservation law: nothing deleted; envelope + slice archived, supersedes edge recorded). A module may not be active without: owner seat, contract hash, drift checker, bad-input suite, rollback method. — End of standard v1.