diff --git a/.github/workflows/integrity.yml b/.github/workflows/integrity.yml index b8219ff..805abaf 100644 --- a/.github/workflows/integrity.yml +++ b/.github/workflows/integrity.yml @@ -1,12 +1,29 @@ name: Riverbraid Verification Gate -on: [push, workflow_dispatch] + +on: + push: + branches: [main] + pull_request: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + jobs: verify: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 - - name: Substrate Audit - run: | - echo "--- STARTING INTEGRITY CHECK ---" - node -v - echo "✅ Substrate Stationary" + - name: Checkout Repository + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 + + - name: Setup Node.js + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 + with: + node-version: '24.11.1' + + - name: Execute repository-local verifier + run: npm test + + - name: Validate runtime-binding source status + run: node tests/runtime-binding-status.mjs diff --git a/RUNTIME_BINDING_STATUS.json b/RUNTIME_BINDING_STATUS.json new file mode 100644 index 0000000..93eb8c0 --- /dev/null +++ b/RUNTIME_BINDING_STATUS.json @@ -0,0 +1,65 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "record_id": "RB-HARNESS-GOLD-RUNTIME-BINDING-STATUS-001", + "version": "1.0.0-candidate", + "as_of": "2026-07-27", + "repository": "Riverbraid/Riverbraid-Harness-Gold", + "status": "BLOCKED_BY_SOURCE_CONTRACT", + "assessed_entrypoints": [ + "runtime-binding.js", + "src/runtime-binding.js" + ], + "intended_gpg_contract": { + "executable": "gpg", + "arguments": ["--verify", "SIGNATURE_PATH", "ANCHOR_PATH"], + "ci_skip_permitted": false, + "invalid_signature_must_fail_closed": true, + "missing_signature_or_anchor_must_fail_closed": true + }, + "observed_blockers": [ + { + "code": "MISSING_VERIFY_SWARM_IMPLEMENTATION", + "path": "bin/verify-swarm.cjs", + "effect": "Both runtime-binding entrypoints require verifySwarm and getCurrentRoot from a file that is not present on the observed default branch." + }, + { + "code": "MISSING_SHIELD_IMPLEMENTATION", + "path": "riverbraid-shield.js", + "effect": "Both runtime-binding entrypoints require a shield module that is not present on the observed default branch." + }, + { + "code": "MODULE_FORMAT_MISMATCH", + "path": "runtime-binding.js", + "effect": "The package declares type=module while this .js entrypoint uses CommonJS require and module.exports syntax." + }, + { + "code": "MODULE_FORMAT_MISMATCH", + "path": "src/runtime-binding.js", + "effect": "The package declares type=module while this .js entrypoint uses CommonJS require and module.exports syntax." + } + ], + "gpg_execution_evidence": "NOT_ASSESSED", + "repository_verifier_relationship": "SEPARATE_LOCAL_STATIONARITY_SURFACE", + "claim_effect": "The repository-local verifier may execute independently, but the runtime GPG binding cannot be described as executable or verified from the observed source state.", + "required_repair_sequence": [ + "Recover or implement the exact verify-swarm dependency under an attributable specification.", + "Recover or implement the exact shield dependency under an attributable specification.", + "Reconcile runtime-binding module format with the package type and declared consumers.", + "Add direct valid-signature, invalid-signature, missing-input, and CI=true GPG tests using an isolated keyring.", + "Execute the tests on an exact source identity and preserve the result before reclassifying this record." + ], + "nonclaims": [ + "This record does not establish compromise.", + "This record does not establish that the intended missing dependencies are known.", + "This record does not verify GPG behavior.", + "This record does not establish production readiness, security hardening, external audit, or absence of defects.", + "A green repository-local verifier does not close the runtime-binding fault." + ], + "review_triggers": [ + "bin/verify-swarm.cjs is added or restored", + "riverbraid-shield.js is added or restored", + "runtime-binding module format changes", + "a declared runtime consumer is identified", + "direct GPG execution evidence is produced" + ] +} diff --git a/tests/runtime-binding-status.mjs b/tests/runtime-binding-status.mjs new file mode 100644 index 0000000..23486b1 --- /dev/null +++ b/tests/runtime-binding-status.mjs @@ -0,0 +1,51 @@ +import assert from "node:assert/strict"; +import fs from "node:fs"; + +const status = JSON.parse(fs.readFileSync("RUNTIME_BINDING_STATUS.json", "utf8")); +const pkg = JSON.parse(fs.readFileSync("package.json", "utf8")); + +const entrypoints = ["runtime-binding.js", "src/runtime-binding.js"]; +const missingDependencies = ["bin/verify-swarm.cjs", "riverbraid-shield.js"].filter( + (file) => !fs.existsSync(file) +); + +const moduleFormatMismatches = []; +for (const file of entrypoints) { + assert.equal(fs.existsSync(file), true, `${file} must exist`); + const source = fs.readFileSync(file, "utf8"); + const usesCommonJs = source.includes("require(") || source.includes("module.exports"); + if (pkg.type === "module" && usesCommonJs && file.endsWith(".js")) { + moduleFormatMismatches.push(file); + } +} + +const observedBlockerCodes = new Set(status.observed_blockers.map((item) => item.code)); + +if (missingDependencies.length > 0) { + assert.equal(observedBlockerCodes.has("MISSING_VERIFY_SWARM_IMPLEMENTATION"), true); + assert.equal(observedBlockerCodes.has("MISSING_SHIELD_IMPLEMENTATION"), true); +} + +if (moduleFormatMismatches.length > 0) { + assert.equal(observedBlockerCodes.has("MODULE_FORMAT_MISMATCH"), true); +} + +const isBlocked = missingDependencies.length > 0 || moduleFormatMismatches.length > 0; + +if (isBlocked) { + assert.equal(status.status, "BLOCKED_BY_SOURCE_CONTRACT"); + assert.equal(status.gpg_execution_evidence, "NOT_ASSESSED"); + console.log(JSON.stringify({ + status: "RUNTIME_BINDING_BLOCKED_STATE_CONFIRMED", + missing_dependencies: missingDependencies, + module_format_mismatches: moduleFormatMismatches, + gpg_execution_evidence: status.gpg_execution_evidence + }, null, 2)); +} else { + assert.notEqual( + status.status, + "BLOCKED_BY_SOURCE_CONTRACT", + "The status record must be reviewed when all observed source blockers are removed." + ); + console.log("RUNTIME_BINDING_SOURCE_BLOCKERS_REMOVED_REVIEW_REQUIRED"); +}