From aafa67fea25a8198fbd05cb7864012b2d6183532 Mon Sep 17 00:00:00 2001 From: Giovanni Giovanni Date: Sun, 19 Jul 2026 02:33:41 -0400 Subject: [PATCH 1/5] EV3-GOV D-EV3-8(3): extend the canonical-evidence negative-space guard with the V3 family tokens MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the v2/v3 schema consts, both invocation-proof contract ids, and the providerInvocations field to BANNED_TOKENS. Extension only — every existing banned token (including the v1 schema id) is retained. Co-Authored-By: Claude Fable 5 --- tests/guardrails/no-canonical-evidence-writer.test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/guardrails/no-canonical-evidence-writer.test.ts b/tests/guardrails/no-canonical-evidence-writer.test.ts index 71f817b..35fa26b 100644 --- a/tests/guardrails/no-canonical-evidence-writer.test.ts +++ b/tests/guardrails/no-canonical-evidence-writer.test.ts @@ -47,6 +47,11 @@ const BANNED_TOKENS = [ "IScoredSignalEvidenceStore", "ScoredSignalEvidenceRecord", "afi.scored-signal-evidence.v1", + "afi.scored-signal-evidence.v2", + "afi.scored-signal-evidence.v3", + "afi.provider-invocation-proof.v1", + "afi.aiml-invocation-proof.v1", + "providerInvocations", "scored_signal_evidence", "scored_signal_evidence_history", "afi_scored_signal_evidence", From 6128041a356b8693fa3898a69c978de11c0dc26d Mon Sep 17 00:00:00 2001 From: Giovanni Giovanni Date: Sun, 19 Jul 2026 12:19:44 -0400 Subject: [PATCH 2/5] EV3-GOV: boundary integration proof asserts the v3 evidence schema const Co-Authored-By: Claude Fable 5 --- test/integration-boundary/gatewayBoundaryEvidence.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration-boundary/gatewayBoundaryEvidence.mjs b/test/integration-boundary/gatewayBoundaryEvidence.mjs index 9da6541..43035c4 100644 --- a/test/integration-boundary/gatewayBoundaryEvidence.mjs +++ b/test/integration-boundary/gatewayBoundaryEvidence.mjs @@ -52,7 +52,7 @@ if (!REACTOR_DIR) { const EVIDENCE_DB = process.env.AFI_EVIDENCE_DB_NAME ?? "afi_gateway_boundary_it"; const OPERATIONAL_DB = process.env.AFI_MONGO_DB_NAME ?? "afi_eliza_it"; const EVIDENCE_COLLECTION = "scored_signal_evidence"; -const EVIDENCE_SCHEMA = "afi.scored-signal-evidence.v2"; +const EVIDENCE_SCHEMA = "afi.scored-signal-evidence.v3"; const SHARED_SECRET = "boundary-it-shared-secret"; const GOOD_PORT = 18080; From 111a6144fbb70dfc4abeb857efb7bd8bd5dc1c9f Mon Sep 17 00:00:00 2001 From: Giovanni Giovanni Date: Sun, 19 Jul 2026 13:07:17 -0400 Subject: [PATCH 3/5] EV3-GOV: boundary proof runs the fail-fast V3 reactor (real keyless feed, TB stub, REACTOR_REF at the EV3 head) The spawned production-mode reactor refuses the synthetic-feed seam by design, and all five lanes are critical under D-EV3-5(1): the proof now selects the real keyless coinbase feed (operator-overridable), starts the reactor's own self-verifying Tiny Brains stub unless TINY_BRAINS_URL is provided, and uses the canonical BASE/QUOTE symbol. REACTOR_REF and the afi-config checkout pin at the EV3 heads (re-pinned to merge commits before this branch merges). Proof re-run locally: 11/11 assertions green against a real replica set. Co-Authored-By: Claude Fable 5 --- .github/workflows/validate-gateway.yml | 5 ++- .../gatewayBoundaryEvidence.mjs | 37 ++++++++++++++++--- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/.github/workflows/validate-gateway.yml b/.github/workflows/validate-gateway.yml index 98e695f..4923d7c 100644 --- a/.github/workflows/validate-gateway.yml +++ b/.github/workflows/validate-gateway.yml @@ -19,7 +19,7 @@ jobs: # completed SLOT-FCP-CLEANUP (analyst-configurable pipelines v1: the # manifest-driven executor is live and the afi-factory dependency is cut) # so the proof is reproducible; bump deliberately, never automatically. - REACTOR_REF: 2a06c82def6a600bef8f16154973457a59c8bd86 + REACTOR_REF: 42b6f29d55c9ac55bce0c0338344c6ee2868271c steps: - name: Checkout afi-gateway @@ -52,6 +52,9 @@ jobs: with: repository: AFI-Protocol/afi-config path: afi-config + # Interim pin: the EV3-GOV afi-config head REACTOR_REF is built + # against; restored to the default branch once afi-config merges. + ref: e5f17161f957c00913b8763919380e92b0b95c39 - name: Setup Node.js 22.x uses: actions/setup-node@v4 diff --git a/test/integration-boundary/gatewayBoundaryEvidence.mjs b/test/integration-boundary/gatewayBoundaryEvidence.mjs index 43035c4..eb1a3cd 100644 --- a/test/integration-boundary/gatewayBoundaryEvidence.mjs +++ b/test/integration-boundary/gatewayBoundaryEvidence.mjs @@ -55,6 +55,9 @@ const EVIDENCE_COLLECTION = "scored_signal_evidence"; const EVIDENCE_SCHEMA = "afi.scored-signal-evidence.v3"; const SHARED_SECRET = "boundary-it-shared-secret"; +let tinyBrainsUrl = process.env.TINY_BRAINS_URL ?? ""; +let tinyBrainsStub = null; + const GOOD_PORT = 18080; const BAD_UWR_PORT = 18081; const DEAD_PORT = 1; // nothing listens here: a genuine ECONNREFUSED @@ -76,7 +79,14 @@ function spawnReactor(port, extraEnv) { PORT: String(port), AFI_EVIDENCE_MONGODB_URI: URI, AFI_EVIDENCE_DB_NAME: EVIDENCE_DB, - AFI_PRICE_FEED_SOURCE: "demo", // hermetic: never depend on a live feed + // A REAL keyless feed: the production-mode child refuses the test-only + // synthetic-feed seam (by design), and every lane is critical under + // EV3-GOV D-EV3-5(1). Operator override respected. + AFI_PRICE_FEED_SOURCE: process.env.AFI_PRICE_FEED_SOURCE ?? "coinbase", + // All five lanes are critical under EV3-GOV D-EV3-5(1); the aiMl lane + // gets the Reactor's own self-verifying Tiny Brains stub (started in + // main()) unless the operator provides a real TINY_BRAINS_URL. + TINY_BRAINS_URL: tinyBrainsUrl, WEBHOOK_SHARED_SECRET: SHARED_SECRET, ...extraEnv, }, @@ -109,6 +119,19 @@ function evidenceCollection(client) { } async function main() { + // All five lanes are critical under EV3-GOV D-EV3-5(1): the aiMl lane needs + // a Tiny Brains endpoint. Default to the Reactor's own self-verifying stub + // (from the checked-out afi-reactor under proof); an operator-provided + // TINY_BRAINS_URL (a real service) takes precedence. + if (!tinyBrainsUrl) { + const stubModule = pathToFileURL( + path.resolve(REACTOR_DIR, "test/integration-mongo/support/tinyBrainsStub.mjs") + ).href; + const { startTinyBrainsStub } = await import(stubModule); + tinyBrainsStub = await startTinyBrainsStub(); + tinyBrainsUrl = tinyBrainsStub.url; + } + const client = new MongoClient(URI); await client.connect(); @@ -137,7 +160,7 @@ async function main() { const signalId = "gw-boundary-it-1"; const payload = { signalId, - symbol: "BTCUSDT", + symbol: "BTC/USDT", // canonical BASE/QUOTE — required by the real keyless feed timeframe: "15m", strategy: "trend_pullback_v1", direction: "long", @@ -181,13 +204,13 @@ async function main() { } assert.equal(record.provenanceRecord.schema, "afi.provenance-record.v1"); assert.ok(record.provenanceRecord.inputHash, "reactor-computed canonical input hash"); - // The v2 composition reference is decisive too: the gateway has no pipeline + // The composition reference is decisive too: the gateway has no pipeline // manifest, no canonical hasher, and no registry — a composition reference // can only have been constructed by the reactor's configured executor. - assert.equal(record.composition.schema, "afi.composition-ref.v1", "v2 composition reference present"); + assert.equal(record.composition.schema, "afi.composition-ref.v1", "composition reference present"); assert.equal(record.composition.pipelineId, "froggy-trend-pullback", "resolved pipeline identity"); assert.ok(record.composition.manifestHash, "canonical manifest hash the gateway never computed"); - ok("P2 evidence constructed by the reactor (UWR stamp + scores + axes + hashes + v2 composition ref the gateway never had)"); + ok("P2 evidence constructed by the reactor (UWR stamp + scores + axes + hashes + composition ref the gateway never had)"); // ---- P3: provenance is authenticated by the gateway, not fabricated ---- assert.equal( @@ -335,6 +358,10 @@ function cleanup() { for (const child of children) { if (!child.killed) child.kill("SIGKILL"); } + if (tinyBrainsStub) { + void tinyBrainsStub.close().catch(() => {}); + tinyBrainsStub = null; + } } // Bounded emergency stop: a hang must fail the build, never sit until the From acdae441d2a7939d8b9e2fc965f0d965b0404c0c Mon Sep 17 00:00:00 2001 From: Giovanni Giovanni Date: Sun, 19 Jul 2026 13:07:42 -0400 Subject: [PATCH 4/5] EV3-GOV CI: REACTOR_REF advances to the stub-fix head Co-Authored-By: Claude Fable 5 --- .github/workflows/validate-gateway.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/validate-gateway.yml b/.github/workflows/validate-gateway.yml index 4923d7c..6a3e263 100644 --- a/.github/workflows/validate-gateway.yml +++ b/.github/workflows/validate-gateway.yml @@ -19,7 +19,7 @@ jobs: # completed SLOT-FCP-CLEANUP (analyst-configurable pipelines v1: the # manifest-driven executor is live and the afi-factory dependency is cut) # so the proof is reproducible; bump deliberately, never automatically. - REACTOR_REF: 42b6f29d55c9ac55bce0c0338344c6ee2868271c + REACTOR_REF: bd6849e0399f6d46d8ef32b38a2cf549b3143343 steps: - name: Checkout afi-gateway From 717c6eb7e8b1e1ca8f93df604acf552aa02e0669 Mon Sep 17 00:00:00 2001 From: Giovanni Giovanni Date: Sun, 19 Jul 2026 13:14:05 -0400 Subject: [PATCH 5/5] =?UTF-8?q?EV3-GOV=20=C2=A719:=20REACTOR=5FREF=20pins?= =?UTF-8?q?=20the=20Evidence=20V3=20merge=20commit;=20default-branch=20afi?= =?UTF-8?q?-config=20checkout=20restored?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- .github/workflows/validate-gateway.yml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/workflows/validate-gateway.yml b/.github/workflows/validate-gateway.yml index 6a3e263..5967355 100644 --- a/.github/workflows/validate-gateway.yml +++ b/.github/workflows/validate-gateway.yml @@ -16,10 +16,10 @@ jobs: env: # afi-reactor is a CI FIXTURE for the cross-repository boundary proof, not # a dependency of the gateway. Pinned to the reviewed merged commit that - # completed SLOT-FCP-CLEANUP (analyst-configurable pipelines v1: the - # manifest-driven executor is live and the afi-factory dependency is cut) - # so the proof is reproducible; bump deliberately, never automatically. - REACTOR_REF: bd6849e0399f6d46d8ef32b38a2cf549b3143343 + # completed EV3-GOV (Evidence V3: provider invocation capture, the + # District Two V3 builder, and the all-five fail-fast law) so the proof + # is reproducible; bump deliberately, never automatically. + REACTOR_REF: 0e23f7cfb5b7156971d1d6cf41078b8f48b1b558 steps: - name: Checkout afi-gateway @@ -52,9 +52,6 @@ jobs: with: repository: AFI-Protocol/afi-config path: afi-config - # Interim pin: the EV3-GOV afi-config head REACTOR_REF is built - # against; restored to the default branch once afi-config merges. - ref: e5f17161f957c00913b8763919380e92b0b95c39 - name: Setup Node.js 22.x uses: actions/setup-node@v4