Skip to content

V2 IQ / OQ / PQ Templates

V2 expresses the three FDA GAMP 5 qualification stages — Installation, Operational, Performance — as M⁸ ruliology game templates. Every external-chain payload plays IQ then OQ then PQ through the substrate's one path. A stage that closes is CALORIE; a stage that does not close spills with a diagnostic naming the missing invariants — never a substrate verdict.

Installation Qualification

GAME: IQ
INGEST     rule = source wallet hosts the proposed payload
INVARIANT  walletResidentSubstrate, addressClassified,
           schemeRecognized, admissibilitySafety, closure
REDUCE     -> vQbit (installation closure)
PROJECT    C4 -> S4
TERMINAL   READ pass_with_rationale

Invariants

  • walletResidentSubstrate — the V225 row for sourceWalletID is present in substrate_imported_external_wallets with observation_only=0 and operator_listed=1. Read via FranklinCellSurface.shared.readViaPool.
  • addressClassified — both sourceAddress and destinationAddress parse via WalletAddressClassifier and map to the expected asset-class family.
  • schemeRecognized — the asset-class raw string is a valid ExternalChainAssetClass case (in the substrate's allow-list).
  • admissibilitySafety — for IQ, the substrate-residence integrity. Installed only when walletResidentSubstrate is true. Missing → reduce spills.

Terminal

public struct IQTerminal: Sendable, Codable, Hashable {
    public let passed: Bool
    public let rationale: String
}

Operational Qualification

GAME: OQ
INGEST     rule = blueprint composes + sovereign endpoint pinned
INVARIANT  blueprintCanonical, sovereignEndpointPinned,
           routingPathBound, admissibilitySafety, closure
REDUCE     -> vQbit (operational closure)
PROJECT    C4 -> S4
TERMINAL   READ pass_with_routing_descriptor

Invariants

  • blueprintCanonical — the substrate's signing-input prefix string is computed and the witness hash (SHA-256 of the prefix) is non-empty.
  • sovereignEndpointPinned — the routing endpoint ID was resolved via SovereignMeshEndpointsRegistry; operator UI selection is substrate-honestly refused (per v1 doctrine, the substrate picks).
  • routingPathBound — the canonical routing-path descriptor is recoverable from (endpoint_id, asset_class).
  • admissibilitySafety — for OQ, the sovereign-endpoint integrity. Installed only when sovereignEndpointPinned is true.

Terminal

public struct OQTerminal: Sendable, Codable, Hashable {
    public let passed: Bool
    public let sovereignEndpointID: String
    public let routingPathCanonical: String
    public let blueprintWitnessHashSHA256: String
    public let rationale: String
}

Performance Qualification

GAME: PQ
INGEST     rule = boundary conditions embedded in payload geometry
INVARIANT  outputMinimum, slippageMinimum, htlcTimelockBound,
           cryptographicBoundsEmbedded, admissibilitySafety, closure
REDUCE     -> vQbit (performance closure)
PROJECT    C4 -> S4
TERMINAL   READ pass_with_bounds_canonical

Invariants

  • outputMinimum — the output amount (in native units) meets the asset's substrate-natural floor (Bitcoin: 546-sat dust threshold; EVM: value-floor against gas, etc.). Per-engine helper computes this.
  • slippageMinimum — embedded for routed transfers (DEX router contracts, AMM minOut). Trivially satisfied at INGEST for non-routed transfers (the input declares it true).
  • htlcTimelockBound — embedded for atomic / cross-chain transfers. Trivially satisfied at INGEST for non-atomic transfers.
  • cryptographicBoundsEmbedded — the canonical boundary descriptor materialises in the payload geometry (the consensus layer physically rejects out-of-bounds execution).
  • admissibilitySafety — for PQ, the cryptographic-bounds embedding integrity. Installed only when cryptographicBoundsEmbedded is true.

Terminal

public struct PQTerminal: Sendable, Codable, Hashable {
    public let passed: Bool
    public let cryptographicBoundsCanonical: String
    public let rationale: String
}

How a stage closes vs spills

The substrate's reduceCore enforces structurally:

guard installed.contains(.admissibilitySafety) else {
    return holder.with(vQbit: .spilling(diagnostic: ...))
}
guard installed.contains(.closure) else {
    return holder.with(vQbit: .spilling(diagnostic: ...))
}
return holder.with(vQbit: .collapsed(dimension: installed.count, signature: ...))

If the per-stage template's invariantsToInstall(for:) omits .admissibilitySafety because the runtime evidence didn't satisfy the load-bearing constraint, the holder spills. The diagnostic carries:

  • invariantsInstalled — what the template did install
  • invariantsMissing.admissibilitySafety (and any other catalog invariants that didn't make the cut)
  • scopeNote — a re-expression hint

The shell-facing CLI prints this directly. Never "REFUSED," never "CANNOT," never "OVER BUDGET."

Playing the full chain

V2 chain engines compose all three ingest inputs and call playQualificationChain:

let result = try await engine.playQualificationChain(
    sourceWalletID: ...,
    sourceAddress: ...,
    destinationAddress: ...,
    amountNativeUnitCanonical: ...,
    proposedFeeNativeUnitCanonical: ...,
    endpointIDFromRegistry: ...,
    endpointIsPinned: ...)

if result.allClosed {
    // signAndBroadcast is unlocked
} else {
    // surface the per-stage spill diagnostic
}

result.allClosed is true iff each of result.iq.terminal, result.oq.terminal, result.pq.terminal is .calorie. Otherwise the stage payload is nil and the substrate's CURE terminal indicates the game spilled.

CLI

gaiaftcl wallet qualify-v2 \
    --wallet-id <V225 id> \
    --source <address> \
    --destination <address> \
    --amount <num/den canonical> \
    --fee <num/den canonical> \
    --asset bitcoin_legacy_p2pkh

Output:

═══ gaiaftcl wallet qualify-v2 (substrate-routed) ═══
  wallet-id    = extwlt-...
  source       = 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
  destination  = 1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2
  amount       = 100000/1
  fee          = 1000/1
  asset_class  = bitcoin_legacy_p2pkh

─── IQ ───
  terminal: CALORIE (game closed)
  payload : passed=true rationale=IQ closed for wallet=extwlt-... — installation invariants satisfied: [addressClassified, admissibilitySafety, closure, schemeRecognized, walletResidentSubstrate].

─── OQ ───
  terminal: CALORIE (game closed)
  payload : endpoint=sovereign-mesh:pinned-bitcoin-node path=sovereign-mesh:pinned-bitcoin-node:bitcoin-utxo witness=...

─── PQ ───
  terminal: CALORIE (game closed)
  payload : bounds=btc_v2_bounds;dust_floor_sat=546;witness=...

ALL THREE STAGES CLOSED — substrate-routed v2 qualification CALORIE.

When a stage spills the per-stage block reads terminal: GAME SPILLS — re-express and the summary line names which stages need re-expression.


Federation-cosigned

This page's source is sealed in the GaiaFTCL federation manifest — page SHA-256 d8ad9f242177e5c6…, manifest witness 3d999b305397d96c…, signed 2026-07-17T15:45:53Z by cell gaiaftcl-mac-cell. Verify with gaiaftcl wiki sign --all and compare wiki-all-signatures.json.