From ed1f1a0932c76ba8a2166368e7f0e0fc6cf4d813 Mon Sep 17 00:00:00 2001 From: Garrett Maring Date: Thu, 28 May 2026 20:05:09 -0300 Subject: [PATCH] V42 Gate 8: Prove local staging MVP rehearsal Add source-safe local/staging full MVP rehearsal artifacts, operator receipts, workflow wiring, and protocol tests. Bind Depositing, Reading, Finding Fits, preview/quote, settlement, delivery, AI-reading proof, telemetry/database readback, and mainnet blocking into Gate 8 closure while stabilizing the Gate 7 roadmap predicate. --- .bitcode/v42-ai-reading-demonstration.json | 4 +- .bitcode/v42-local-staging-mvp-rehearsal.json | 824 ++++++++++++++++++ .github/workflows/bitcode-canon-quality.yml | 3 + .github/workflows/bitcode-gate-quality.yml | 3 + BITCODE_SPEC_V42.md | 9 + BITCODE_SPEC_V42_DELTA.md | 2 + BITCODE_SPEC_V42_NOTES.md | 8 + BITCODE_SPEC_V42_PARITY_MATRIX.md | 4 +- README.md | 12 + SPECIFICATIONS_ROADMAP.md | 5 +- package.json | 4 + packages/pipelines/asset-pack/README.md | 10 + packages/protocol/README.md | 13 + .../canonical/v42-ai-reading-demonstration.js | 2 +- .../v42-local-staging-mvp-rehearsal.js | 417 +++++++++ packages/protocol/src/index.d.ts | 10 + packages/protocol/src/index.js | 12 + .../v42-local-staging-mvp-rehearsal.test.js | 57 ++ ...-v42-gate8-local-staging-mvp-rehearsal.mjs | 281 ++++++ ...nerate-v42-local-staging-mvp-rehearsal.mjs | 61 ++ scripts/rehearse-v42-local-staging-mvp.mjs | 325 +++++++ .../pipeline-harness/asset-pack/preflight.ts | 6 + uapi/app/terminal/README.md | 13 + .../terminal/TerminalDepositReadWorkbench.tsx | 75 ++ 24 files changed, 2153 insertions(+), 7 deletions(-) create mode 100644 .bitcode/v42-local-staging-mvp-rehearsal.json create mode 100644 packages/protocol/src/canonical/v42-local-staging-mvp-rehearsal.js create mode 100644 packages/protocol/test/v42-local-staging-mvp-rehearsal.test.js create mode 100644 scripts/check-v42-gate8-local-staging-mvp-rehearsal.mjs create mode 100644 scripts/generate-v42-local-staging-mvp-rehearsal.mjs create mode 100644 scripts/rehearse-v42-local-staging-mvp.mjs diff --git a/.bitcode/v42-ai-reading-demonstration.json b/.bitcode/v42-ai-reading-demonstration.json index 7ad5e0bf..c83b2485 100644 --- a/.bitcode/v42-ai-reading-demonstration.json +++ b/.bitcode/v42-ai-reading-demonstration.json @@ -377,7 +377,7 @@ "passed": true }, { - "id": "roadmap-advanced-to-gate7", + "id": "roadmap-records-gate7-closure", "sourcePath": "SPECIFICATIONS_ROADMAP.md", "passed": true }, @@ -412,5 +412,5 @@ "failedPredicateIds": [] }, "passed": true, - "artifactRoot": "v42-ai-reading-demonstration:611a9f54deb36a9d6506adf5" + "artifactRoot": "v42-ai-reading-demonstration:8d5fb53a20ade8253f106da8" } diff --git a/.bitcode/v42-local-staging-mvp-rehearsal.json b/.bitcode/v42-local-staging-mvp-rehearsal.json new file mode 100644 index 00000000..4d790f02 --- /dev/null +++ b/.bitcode/v42-local-staging-mvp-rehearsal.json @@ -0,0 +1,824 @@ +{ + "artifactId": "v42-local-staging-mvp-rehearsal", + "schemaId": "bitcode.v42.localStagingMvpRehearsal.v1", + "version": "V42", + "currentTarget": "V41", + "sourceSafetyVerdict": "source-safe-v42-local-staging-mvp-rehearsal-metadata", + "laneIds": [ + "local", + "staging-testnet" + ], + "stageIds": [ + "deposit-source", + "request-read", + "review-synthesized-need", + "request-finding-fits", + "review-assetpack-preview", + "buy-assetpack-settle", + "receive-repository-delivery" + ], + "rowIds": [ + "lane:local-full-mvp-rehearsal", + "lane:staging-testnet-full-mvp-rehearsal", + "deposit:source-admission-compensation-readback", + "reading:request-read-state", + "reading:need-review-resynthesis", + "fits:many-candidate-depository-search", + "assetpack:source-safe-preview-quote", + "settlement:btd-rights-delivery", + "demonstration:ai-reading-uplift", + "telemetry:rich-stream-database-readback", + "sync:ledger-database-storage-reconciliation", + "operator:source-safe-rehearsal-receipts", + "boundary:value-bearing-mainnet-blocked", + "proof:artifact-tests-workflows-docs" + ], + "rows": [ + { + "rowId": "lane:local-full-mvp-rehearsal", + "laneId": "local", + "stageId": null, + "purpose": "Bind the local MVP rehearsal to source-safe dry-run receipts, local package checks, and explicit sandbox execution opt-in.", + "sourceRoots": [ + "scripts/rehearse-v42-local-staging-mvp.mjs", + "packages/pipelines/asset-pack/src/reading-local-staging-rehearsal.ts", + "packages/pipelines/asset-pack/src/__tests__/reading-local-staging-rehearsal.test.ts" + ], + "requiredEvidence": [ + "local", + "dryRun", + "BITCODE_V42_REHEARSAL_EXECUTE" + ], + "rowRoot": "v42-local-staging-mvp-rehearsal-row:07e88356683f8569b4523c07", + "sourceSafetyClass": "source_safe_v42_local_staging_mvp_rehearsal_metadata", + "sourceSafeMetadataOnly": true, + "protectedSourcePayloadSerialized": false, + "rawProtectedPromptVisible": false, + "rawInterpolatedPromptVisible": false, + "rawProviderResponseVisible": false, + "unpaidAssetPackSourceVisible": false, + "credentialsSerialized": false, + "walletPrivateMaterialVisible": false, + "privateSettlementPayloadVisible": false, + "liveRehearsalLogPayloadSerialized": false, + "valueBearingMainnetAdmitted": false, + "forbiddenPayloadClasses": [ + "secret-values", + "provider-tokens", + "wallet-private-material", + "protected-source-payloads", + "raw-protected-prompts", + "raw-interpolated-prompts", + "raw-provider-responses", + "unpaid-assetpack-source", + "live-rehearsal-log-payloads", + "value-bearing-mainnet-admission" + ] + }, + { + "rowId": "lane:staging-testnet-full-mvp-rehearsal", + "laneId": "staging-testnet", + "stageId": null, + "purpose": "Bind the staging-testnet MVP rehearsal to real-inference posture, Vercel Sandbox authorization, database streaming, and Supabase readback.", + "sourceRoots": [ + "scripts/rehearse-v42-local-staging-mvp.mjs", + "uapi/app/api/pipeline-harness/asset-pack/preflight.ts", + "uapi/app/api/pipeline-harness/asset-pack/runner.ts" + ], + "requiredEvidence": [ + "staging-testnet", + "BITCODE_ASSET_PACK_REAL_INFERENCE", + "tkpyosihuouusyaxtbau" + ], + "rowRoot": "v42-local-staging-mvp-rehearsal-row:bc7dc738cea89605f4b07176", + "sourceSafetyClass": "source_safe_v42_local_staging_mvp_rehearsal_metadata", + "sourceSafeMetadataOnly": true, + "protectedSourcePayloadSerialized": false, + "rawProtectedPromptVisible": false, + "rawInterpolatedPromptVisible": false, + "rawProviderResponseVisible": false, + "unpaidAssetPackSourceVisible": false, + "credentialsSerialized": false, + "walletPrivateMaterialVisible": false, + "privateSettlementPayloadVisible": false, + "liveRehearsalLogPayloadSerialized": false, + "valueBearingMainnetAdmitted": false, + "forbiddenPayloadClasses": [ + "secret-values", + "provider-tokens", + "wallet-private-material", + "protected-source-payloads", + "raw-protected-prompts", + "raw-interpolated-prompts", + "raw-provider-responses", + "unpaid-assetpack-source", + "live-rehearsal-log-payloads", + "value-bearing-mainnet-admission" + ] + }, + { + "rowId": "deposit:source-admission-compensation-readback", + "laneId": "local-and-staging-testnet", + "stageId": "deposit-source", + "purpose": "Carry Gate 2 Depositing shortest path through rehearsal with source admission proof and later compensation readback.", + "sourceRoots": [ + ".bitcode/v42-depositing-shortest-path.json", + "uapi/app/terminal/TerminalDepositReadWorkbench.tsx" + ], + "requiredEvidence": [ + "DepositorySupplyCompensationPreview", + "depositing-shortest-path", + "compensationPreview" + ], + "rowRoot": "v42-local-staging-mvp-rehearsal-row:b713cd6bf4f4fad63cdc5fe0", + "sourceSafetyClass": "source_safe_v42_local_staging_mvp_rehearsal_metadata", + "sourceSafeMetadataOnly": true, + "protectedSourcePayloadSerialized": false, + "rawProtectedPromptVisible": false, + "rawInterpolatedPromptVisible": false, + "rawProviderResponseVisible": false, + "unpaidAssetPackSourceVisible": false, + "credentialsSerialized": false, + "walletPrivateMaterialVisible": false, + "privateSettlementPayloadVisible": false, + "liveRehearsalLogPayloadSerialized": false, + "valueBearingMainnetAdmitted": false, + "forbiddenPayloadClasses": [ + "secret-values", + "provider-tokens", + "wallet-private-material", + "protected-source-payloads", + "raw-protected-prompts", + "raw-interpolated-prompts", + "raw-provider-responses", + "unpaid-assetpack-source", + "live-rehearsal-log-payloads", + "value-bearing-mainnet-admission" + ] + }, + { + "rowId": "reading:request-read-state", + "laneId": "local-and-staging-testnet", + "stageId": "request-read", + "purpose": "Carry Gate 3 route-owned Reading state through transaction recovery, route hydration, and source-safe repair posture.", + "sourceRoots": [ + ".bitcode/v42-reading-shortest-path-state-machine.json", + "uapi/app/terminal/TerminalDepositReadWorkbench.tsx" + ], + "requiredEvidence": [ + "TerminalEnterpriseReadingRouteState", + "readingStage", + "request-read" + ], + "rowRoot": "v42-local-staging-mvp-rehearsal-row:73096691e098c30b1ca2fed9", + "sourceSafetyClass": "source_safe_v42_local_staging_mvp_rehearsal_metadata", + "sourceSafeMetadataOnly": true, + "protectedSourcePayloadSerialized": false, + "rawProtectedPromptVisible": false, + "rawInterpolatedPromptVisible": false, + "rawProviderResponseVisible": false, + "unpaidAssetPackSourceVisible": false, + "credentialsSerialized": false, + "walletPrivateMaterialVisible": false, + "privateSettlementPayloadVisible": false, + "liveRehearsalLogPayloadSerialized": false, + "valueBearingMainnetAdmitted": false, + "forbiddenPayloadClasses": [ + "secret-values", + "provider-tokens", + "wallet-private-material", + "protected-source-payloads", + "raw-protected-prompts", + "raw-interpolated-prompts", + "raw-provider-responses", + "unpaid-assetpack-source", + "live-rehearsal-log-payloads", + "value-bearing-mainnet-admission" + ] + }, + { + "rowId": "reading:need-review-resynthesis", + "laneId": "local-and-staging-testnet", + "stageId": "review-synthesized-need", + "purpose": "Carry Gate 4 Need synthesis, review, feedback, resynthesis, accepted Need admission, and telemetry receipts through rehearsal.", + "sourceRoots": [ + ".bitcode/v42-readneed-review-resynthesis-product-closure.json", + "packages/pipelines/asset-pack/src/read-need-review-resynthesis.ts" + ], + "requiredEvidence": [ + "ReadNeedReviewResynthesisRuntime", + "accept_read_need", + "accepted Need" + ], + "rowRoot": "v42-local-staging-mvp-rehearsal-row:b0f29af092780b41177b96ef", + "sourceSafetyClass": "source_safe_v42_local_staging_mvp_rehearsal_metadata", + "sourceSafeMetadataOnly": true, + "protectedSourcePayloadSerialized": false, + "rawProtectedPromptVisible": false, + "rawInterpolatedPromptVisible": false, + "rawProviderResponseVisible": false, + "unpaidAssetPackSourceVisible": false, + "credentialsSerialized": false, + "walletPrivateMaterialVisible": false, + "privateSettlementPayloadVisible": false, + "liveRehearsalLogPayloadSerialized": false, + "valueBearingMainnetAdmitted": false, + "forbiddenPayloadClasses": [ + "secret-values", + "provider-tokens", + "wallet-private-material", + "protected-source-payloads", + "raw-protected-prompts", + "raw-interpolated-prompts", + "raw-provider-responses", + "unpaid-assetpack-source", + "live-rehearsal-log-payloads", + "value-bearing-mainnet-admission" + ] + }, + { + "rowId": "fits:many-candidate-depository-search", + "laneId": "local-and-staging-testnet", + "stageId": "request-finding-fits", + "purpose": "Carry Gate 5 Finding Fits across many Depository candidates with query roots, ranking roots, and selected-fit provenance.", + "sourceRoots": [ + ".bitcode/v42-readfitsfinding-preview-quote.json", + "packages/pipelines/asset-pack/src/read-fits-finding-runtime.ts", + "packages/pipelines/asset-pack/src/depository-search.ts" + ], + "requiredEvidence": [ + "ReadFitsFindingRuntime", + "many-channel Depository search", + "selected-fit provenance" + ], + "rowRoot": "v42-local-staging-mvp-rehearsal-row:a291daea0f2aecef13dc356f", + "sourceSafetyClass": "source_safe_v42_local_staging_mvp_rehearsal_metadata", + "sourceSafeMetadataOnly": true, + "protectedSourcePayloadSerialized": false, + "rawProtectedPromptVisible": false, + "rawInterpolatedPromptVisible": false, + "rawProviderResponseVisible": false, + "unpaidAssetPackSourceVisible": false, + "credentialsSerialized": false, + "walletPrivateMaterialVisible": false, + "privateSettlementPayloadVisible": false, + "liveRehearsalLogPayloadSerialized": false, + "valueBearingMainnetAdmitted": false, + "forbiddenPayloadClasses": [ + "secret-values", + "provider-tokens", + "wallet-private-material", + "protected-source-payloads", + "raw-protected-prompts", + "raw-interpolated-prompts", + "raw-provider-responses", + "unpaid-assetpack-source", + "live-rehearsal-log-payloads", + "value-bearing-mainnet-admission" + ] + }, + { + "rowId": "assetpack:source-safe-preview-quote", + "laneId": "local-and-staging-testnet", + "stageId": "review-assetpack-preview", + "purpose": "Carry source-safe AssetPack preview, deterministic quote, disclosure review, and pre-settlement delivery lock through rehearsal.", + "sourceRoots": [ + ".bitcode/v42-readfitsfinding-preview-quote.json", + "packages/pipelines/asset-pack/src/asset-pack-preview-boundary.ts" + ], + "requiredEvidence": [ + "AssetPackPreviewBoundary", + "deterministicQuote", + "sourceSafePreview" + ], + "rowRoot": "v42-local-staging-mvp-rehearsal-row:54ec6cef7444f2c078210abc", + "sourceSafetyClass": "source_safe_v42_local_staging_mvp_rehearsal_metadata", + "sourceSafeMetadataOnly": true, + "protectedSourcePayloadSerialized": false, + "rawProtectedPromptVisible": false, + "rawInterpolatedPromptVisible": false, + "rawProviderResponseVisible": false, + "unpaidAssetPackSourceVisible": false, + "credentialsSerialized": false, + "walletPrivateMaterialVisible": false, + "privateSettlementPayloadVisible": false, + "liveRehearsalLogPayloadSerialized": false, + "valueBearingMainnetAdmitted": false, + "forbiddenPayloadClasses": [ + "secret-values", + "provider-tokens", + "wallet-private-material", + "protected-source-payloads", + "raw-protected-prompts", + "raw-interpolated-prompts", + "raw-provider-responses", + "unpaid-assetpack-source", + "live-rehearsal-log-payloads", + "value-bearing-mainnet-admission" + ] + }, + { + "rowId": "settlement:btd-rights-delivery", + "laneId": "local-and-staging-testnet", + "stageId": "buy-assetpack-settle", + "purpose": "Carry Gate 6 BTC/testnet finality, BTD read-right transfer, source-to-shares compensation, reconciliation, and pull-request delivery.", + "sourceRoots": [ + ".bitcode/v42-settlement-rights-delivery.json", + "packages/pipelines/asset-pack/src/asset-pack-settlement-rights-delivery.ts" + ], + "requiredEvidence": [ + "AssetPackSettlementRightsDeliveryBoundary", + "BtdRightsTransferReceipt", + "source_bearing_pull_request_ready" + ], + "rowRoot": "v42-local-staging-mvp-rehearsal-row:d2da21ce198743a2c0b5d731", + "sourceSafetyClass": "source_safe_v42_local_staging_mvp_rehearsal_metadata", + "sourceSafeMetadataOnly": true, + "protectedSourcePayloadSerialized": false, + "rawProtectedPromptVisible": false, + "rawInterpolatedPromptVisible": false, + "rawProviderResponseVisible": false, + "unpaidAssetPackSourceVisible": false, + "credentialsSerialized": false, + "walletPrivateMaterialVisible": false, + "privateSettlementPayloadVisible": false, + "liveRehearsalLogPayloadSerialized": false, + "valueBearingMainnetAdmitted": false, + "forbiddenPayloadClasses": [ + "secret-values", + "provider-tokens", + "wallet-private-material", + "protected-source-payloads", + "raw-protected-prompts", + "raw-interpolated-prompts", + "raw-provider-responses", + "unpaid-assetpack-source", + "live-rehearsal-log-payloads", + "value-bearing-mainnet-admission" + ] + }, + { + "rowId": "demonstration:ai-reading-uplift", + "laneId": "local-and-staging-testnet", + "stageId": null, + "purpose": "Carry Gate 7 AI-reading value proof into the full MVP rehearsal as the product demonstration of why Reading buys an AssetPack.", + "sourceRoots": [ + ".bitcode/v42-ai-reading-demonstration.json" + ], + "requiredEvidence": [ + "public-data-only", + "assetpack-enhanced-after-rights", + "minimumUpliftBp" + ], + "rowRoot": "v42-local-staging-mvp-rehearsal-row:e0765d3511ad1a514a1dc888", + "sourceSafetyClass": "source_safe_v42_local_staging_mvp_rehearsal_metadata", + "sourceSafeMetadataOnly": true, + "protectedSourcePayloadSerialized": false, + "rawProtectedPromptVisible": false, + "rawInterpolatedPromptVisible": false, + "rawProviderResponseVisible": false, + "unpaidAssetPackSourceVisible": false, + "credentialsSerialized": false, + "walletPrivateMaterialVisible": false, + "privateSettlementPayloadVisible": false, + "liveRehearsalLogPayloadSerialized": false, + "valueBearingMainnetAdmitted": false, + "forbiddenPayloadClasses": [ + "secret-values", + "provider-tokens", + "wallet-private-material", + "protected-source-payloads", + "raw-protected-prompts", + "raw-interpolated-prompts", + "raw-provider-responses", + "unpaid-assetpack-source", + "live-rehearsal-log-payloads", + "value-bearing-mainnet-admission" + ] + }, + { + "rowId": "telemetry:rich-stream-database-readback", + "laneId": "local-and-staging-testnet", + "stageId": null, + "purpose": "Prove rich pipeline stream rows, execution ids, phase/agent/step/generation metadata, and database readback remain available for debugging.", + "sourceRoots": [ + "packages/pipelines/asset-pack/src/reading-local-staging-rehearsal.ts", + "packages/pipelines/asset-pack/src/reading-operational-telemetry-repair-readback.ts", + "uapi/components/base/bitcode/execution/pipeline-execution-log.tsx" + ], + "requiredEvidence": [ + "phase", + "ptrr-agent", + "thricified-generation", + "tool", + "databaseReadbackRequired" + ], + "rowRoot": "v42-local-staging-mvp-rehearsal-row:bf279f8690c1cb3bdf8db157", + "sourceSafetyClass": "source_safe_v42_local_staging_mvp_rehearsal_metadata", + "sourceSafeMetadataOnly": true, + "protectedSourcePayloadSerialized": false, + "rawProtectedPromptVisible": false, + "rawInterpolatedPromptVisible": false, + "rawProviderResponseVisible": false, + "unpaidAssetPackSourceVisible": false, + "credentialsSerialized": false, + "walletPrivateMaterialVisible": false, + "privateSettlementPayloadVisible": false, + "liveRehearsalLogPayloadSerialized": false, + "valueBearingMainnetAdmitted": false, + "forbiddenPayloadClasses": [ + "secret-values", + "provider-tokens", + "wallet-private-material", + "protected-source-payloads", + "raw-protected-prompts", + "raw-interpolated-prompts", + "raw-provider-responses", + "unpaid-assetpack-source", + "live-rehearsal-log-payloads", + "value-bearing-mainnet-admission" + ] + }, + { + "rowId": "sync:ledger-database-storage-reconciliation", + "laneId": "local-and-staging-testnet", + "stageId": null, + "purpose": "Prove ledger, database, object storage, wallet, and repository delivery projections reconcile before source-bearing delivery.", + "sourceRoots": [ + ".bitcode/v42-settlement-rights-delivery.json", + "packages/pipelines/asset-pack/src/asset-pack-settlement-rights-delivery.ts", + "packages/pipelines/asset-pack/src/reading-local-staging-rehearsal.ts" + ], + "requiredEvidence": [ + "ledgerDatabaseStorageSynchronized", + "reconciliationRoot", + "aligned" + ], + "rowRoot": "v42-local-staging-mvp-rehearsal-row:418bed502488469483d1b205", + "sourceSafetyClass": "source_safe_v42_local_staging_mvp_rehearsal_metadata", + "sourceSafeMetadataOnly": true, + "protectedSourcePayloadSerialized": false, + "rawProtectedPromptVisible": false, + "rawInterpolatedPromptVisible": false, + "rawProviderResponseVisible": false, + "unpaidAssetPackSourceVisible": false, + "credentialsSerialized": false, + "walletPrivateMaterialVisible": false, + "privateSettlementPayloadVisible": false, + "liveRehearsalLogPayloadSerialized": false, + "valueBearingMainnetAdmitted": false, + "forbiddenPayloadClasses": [ + "secret-values", + "provider-tokens", + "wallet-private-material", + "protected-source-payloads", + "raw-protected-prompts", + "raw-interpolated-prompts", + "raw-provider-responses", + "unpaid-assetpack-source", + "live-rehearsal-log-payloads", + "value-bearing-mainnet-admission" + ] + }, + { + "rowId": "operator:source-safe-rehearsal-receipts", + "laneId": "local-and-staging-testnet", + "stageId": null, + "purpose": "Provide operator receipt generation for local and staging-testnet lanes without serializing env values, protected source, live logs, or settlement payloads.", + "sourceRoots": [ + "scripts/rehearse-v42-local-staging-mvp.mjs", + "scripts/check-v42-gate8-local-staging-mvp-rehearsal.mjs" + ], + "requiredEvidence": [ + "sourceSafety", + "secretValueSerialized: false", + "receiptRoot" + ], + "rowRoot": "v42-local-staging-mvp-rehearsal-row:d4eff04bce193f87d78efc1c", + "sourceSafetyClass": "source_safe_v42_local_staging_mvp_rehearsal_metadata", + "sourceSafeMetadataOnly": true, + "protectedSourcePayloadSerialized": false, + "rawProtectedPromptVisible": false, + "rawInterpolatedPromptVisible": false, + "rawProviderResponseVisible": false, + "unpaidAssetPackSourceVisible": false, + "credentialsSerialized": false, + "walletPrivateMaterialVisible": false, + "privateSettlementPayloadVisible": false, + "liveRehearsalLogPayloadSerialized": false, + "valueBearingMainnetAdmitted": false, + "forbiddenPayloadClasses": [ + "secret-values", + "provider-tokens", + "wallet-private-material", + "protected-source-payloads", + "raw-protected-prompts", + "raw-interpolated-prompts", + "raw-provider-responses", + "unpaid-assetpack-source", + "live-rehearsal-log-payloads", + "value-bearing-mainnet-admission" + ] + }, + { + "rowId": "boundary:value-bearing-mainnet-blocked", + "laneId": "local-and-staging-testnet", + "stageId": null, + "purpose": "Keep the MVP rehearsal non-value-bearing and blocked from mainnet while proving the staged BTC/BTD protocol path.", + "sourceRoots": [ + "scripts/rehearse-v42-local-staging-mvp.mjs", + "packages/pipelines/asset-pack/src/reading-local-staging-rehearsal.ts" + ], + "requiredEvidence": [ + "valueBearingMainnetAdmitted: false", + "serverCustody: false", + "production-mainnet blocked" + ], + "rowRoot": "v42-local-staging-mvp-rehearsal-row:4a21713c005233db5112b63c", + "sourceSafetyClass": "source_safe_v42_local_staging_mvp_rehearsal_metadata", + "sourceSafeMetadataOnly": true, + "protectedSourcePayloadSerialized": false, + "rawProtectedPromptVisible": false, + "rawInterpolatedPromptVisible": false, + "rawProviderResponseVisible": false, + "unpaidAssetPackSourceVisible": false, + "credentialsSerialized": false, + "walletPrivateMaterialVisible": false, + "privateSettlementPayloadVisible": false, + "liveRehearsalLogPayloadSerialized": false, + "valueBearingMainnetAdmitted": false, + "forbiddenPayloadClasses": [ + "secret-values", + "provider-tokens", + "wallet-private-material", + "protected-source-payloads", + "raw-protected-prompts", + "raw-interpolated-prompts", + "raw-provider-responses", + "unpaid-assetpack-source", + "live-rehearsal-log-payloads", + "value-bearing-mainnet-admission" + ] + }, + { + "rowId": "proof:artifact-tests-workflows-docs", + "laneId": "local-and-staging-testnet", + "stageId": null, + "purpose": "Bind Gate 8 to deterministic artifact generation, protocol tests, package rehearsal tests, docs, workflows, and package scripts.", + "sourceRoots": [ + "packages/protocol/test/v42-local-staging-mvp-rehearsal.test.js", + "package.json", + ".github/workflows/bitcode-gate-quality.yml", + ".github/workflows/bitcode-canon-quality.yml" + ], + "requiredEvidence": [ + "v42-local-staging-mvp-rehearsal", + "check:v42-gate8", + "generate:v42-local-staging-mvp-rehearsal" + ], + "rowRoot": "v42-local-staging-mvp-rehearsal-row:4a15dcd2cf8ad6eab11edfe3", + "sourceSafetyClass": "source_safe_v42_local_staging_mvp_rehearsal_metadata", + "sourceSafeMetadataOnly": true, + "protectedSourcePayloadSerialized": false, + "rawProtectedPromptVisible": false, + "rawInterpolatedPromptVisible": false, + "rawProviderResponseVisible": false, + "unpaidAssetPackSourceVisible": false, + "credentialsSerialized": false, + "walletPrivateMaterialVisible": false, + "privateSettlementPayloadVisible": false, + "liveRehearsalLogPayloadSerialized": false, + "valueBearingMainnetAdmitted": false, + "forbiddenPayloadClasses": [ + "secret-values", + "provider-tokens", + "wallet-private-material", + "protected-source-payloads", + "raw-protected-prompts", + "raw-interpolated-prompts", + "raw-provider-responses", + "unpaid-assetpack-source", + "live-rehearsal-log-payloads", + "value-bearing-mainnet-admission" + ] + } + ], + "predicateResults": [ + { + "id": "gate2-artifact-passed", + "sourcePath": ".bitcode/v42-depositing-shortest-path.json", + "passed": true + }, + { + "id": "gate3-artifact-passed", + "sourcePath": ".bitcode/v42-reading-shortest-path-state-machine.json", + "passed": true + }, + { + "id": "gate4-artifact-passed", + "sourcePath": ".bitcode/v42-readneed-review-resynthesis-product-closure.json", + "passed": true + }, + { + "id": "gate5-artifact-passed", + "sourcePath": ".bitcode/v42-readfitsfinding-preview-quote.json", + "passed": true + }, + { + "id": "gate6-artifact-passed", + "sourcePath": ".bitcode/v42-settlement-rights-delivery.json", + "passed": true + }, + { + "id": "gate7-artifact-passed", + "sourcePath": ".bitcode/v42-ai-reading-demonstration.json", + "passed": true + }, + { + "id": "rehearsal-model-covers-lanes", + "sourcePath": "packages/pipelines/asset-pack/src/reading-local-staging-rehearsal.ts", + "passed": true + }, + { + "id": "rehearsal-model-covers-five-reading-stages", + "sourcePath": "packages/pipelines/asset-pack/src/reading-local-staging-rehearsal.ts", + "passed": true + }, + { + "id": "rehearsal-model-covers-source-safety", + "sourcePath": "packages/pipelines/asset-pack/src/reading-local-staging-rehearsal.ts", + "passed": true + }, + { + "id": "rehearsal-test-covers-settled-flow", + "sourcePath": "packages/pipelines/asset-pack/src/__tests__/reading-local-staging-rehearsal.test.ts", + "passed": true + }, + { + "id": "postprocess-persists-rehearsal", + "sourcePath": "packages/pipelines/asset-pack/src/postprocess.ts", + "passed": true + }, + { + "id": "operator-script-exists", + "sourcePath": "scripts/rehearse-v42-local-staging-mvp.mjs", + "passed": true + }, + { + "id": "operator-script-binds-staging-env", + "sourcePath": "scripts/rehearse-v42-local-staging-mvp.mjs", + "passed": true + }, + { + "id": "operator-script-source-safe", + "sourcePath": "scripts/rehearse-v42-local-staging-mvp.mjs", + "passed": true + }, + { + "id": "harness-preflight-binds-staging", + "sourcePath": "uapi/app/api/pipeline-harness/asset-pack/preflight.ts", + "passed": true + }, + { + "id": "harness-runner-covers-boundaries", + "sourcePath": "uapi/app/api/pipeline-harness/asset-pack/runner.ts", + "passed": true + }, + { + "id": "terminal-renders-reading-rehearsal", + "sourcePath": "uapi/app/terminal/TerminalDepositReadWorkbench.tsx", + "passed": true + }, + { + "id": "pipeline-log-supports-rich-telemetry", + "sourcePath": "uapi/components/base/bitcode/execution/pipeline-execution-log.tsx", + "passed": true + }, + { + "id": "protocol-test-wired", + "sourcePath": "packages/protocol/test/v42-local-staging-mvp-rehearsal.test.js", + "passed": true + }, + { + "id": "protocol-exports-wired", + "sourcePath": "packages/protocol/src/index.js", + "passed": true + }, + { + "id": "package-scripts-wired", + "sourcePath": "package.json", + "passed": true + }, + { + "id": "workflows-run-gate8", + "sourcePath": ".github/workflows/bitcode-gate-quality.yml", + "passed": true + }, + { + "id": "v42-docs-expanded", + "sourcePath": "BITCODE_SPEC_V42.md", + "passed": true + }, + { + "id": "v42-delta-expanded", + "sourcePath": "BITCODE_SPEC_V42_DELTA.md", + "passed": true + }, + { + "id": "v42-notes-expanded", + "sourcePath": "BITCODE_SPEC_V42_NOTES.md", + "passed": true + }, + { + "id": "v42-parity-implemented", + "sourcePath": "BITCODE_SPEC_V42_PARITY_MATRIX.md", + "passed": true + }, + { + "id": "roadmap-advanced-to-gate8", + "sourcePath": "SPECIFICATIONS_ROADMAP.md", + "passed": true + }, + { + "id": "readmes-document-gate8", + "sourcePath": "README.md", + "passed": true + } + ], + "coverage": { + "rowCount": 14, + "laneCount": 2, + "stageCount": 7, + "gateArtifactCount": 6, + "lanes": [ + "local", + "staging-testnet" + ], + "stages": [ + "deposit-source", + "request-read", + "review-synthesized-need", + "request-finding-fits", + "review-assetpack-preview", + "buy-assetpack-settle", + "receive-repository-delivery" + ], + "stagingProjectRef": "tkpyosihuouusyaxtbau", + "stagingRestHost": "https://tkpyosihuouusyaxtbau.supabase.co/rest/v1/", + "localLaneCovered": true, + "stagingTestnetLaneCovered": true, + "depositingCovered": true, + "readRequestCovered": true, + "readNeedReviewCovered": true, + "readFitsFindingCovered": true, + "manyCandidateDepositorySearchCovered": true, + "sourceSafePreviewQuoteCovered": true, + "settlementRightsDeliveryCovered": true, + "aiReadingDemonstrationCovered": true, + "richTelemetryReadbackCovered": true, + "databaseStreamReadbackCovered": true, + "ledgerDatabaseStorageSynchronized": true, + "postSettlementPullRequestDeliveryCovered": true, + "operatorReceiptScriptCovered": true, + "mainnetValueBearingBlocked": true, + "sourceSafeMetadataOnly": true, + "protectedSourcePayloadSerialized": false, + "rawProtectedPromptVisible": false, + "rawInterpolatedPromptVisible": false, + "rawProviderResponseVisible": false, + "unpaidAssetPackSourceVisible": false, + "credentialsSerialized": false, + "walletPrivateMaterialVisible": false, + "privateSettlementPayloadVisible": false, + "liveRehearsalLogPayloadSerialized": false, + "failedPredicateIds": [] + }, + "sourceSafety": { + "sourceSafetyClass": "source_safe_v42_local_staging_mvp_rehearsal_metadata", + "sourceSafeMetadataOnly": true, + "protectedSourcePayloadSerialized": false, + "rawProtectedPromptVisible": false, + "rawInterpolatedPromptVisible": false, + "rawProviderResponseVisible": false, + "unpaidAssetPackSourceVisible": false, + "credentialsSerialized": false, + "walletPrivateMaterialVisible": false, + "privateSettlementPayloadVisible": false, + "liveRehearsalLogPayloadSerialized": false, + "valueBearingMainnetAdmitted": false, + "forbiddenPayloadClasses": [ + "secret-values", + "provider-tokens", + "wallet-private-material", + "protected-source-payloads", + "raw-protected-prompts", + "raw-interpolated-prompts", + "raw-provider-responses", + "unpaid-assetpack-source", + "live-rehearsal-log-payloads", + "value-bearing-mainnet-admission" + ] + }, + "passed": true, + "artifactRoot": "v42-local-staging-mvp-rehearsal:0683e1851bff1596228f582a" +} diff --git a/.github/workflows/bitcode-canon-quality.yml b/.github/workflows/bitcode-canon-quality.yml index 25b5041e..9cf83b3b 100644 --- a/.github/workflows/bitcode-canon-quality.yml +++ b/.github/workflows/bitcode-canon-quality.yml @@ -313,6 +313,9 @@ jobs: if [ -f scripts/check-v42-gate7-ai-reading-demonstration.mjs ]; then node scripts/check-v42-gate7-ai-reading-demonstration.mjs --skip-branch-check --skip-package-tests --skip-demonstration-tests fi + if [ -f scripts/check-v42-gate8-local-staging-mvp-rehearsal.mjs ]; then + node scripts/check-v42-gate8-local-staging-mvp-rehearsal.mjs --skip-branch-check --skip-package-tests --skip-uapi-tests + fi fi else echo "Unexpected BITCODE_SPEC.txt pointer: $POINTER" >&2 diff --git a/.github/workflows/bitcode-gate-quality.yml b/.github/workflows/bitcode-gate-quality.yml index 437a0f78..c4fafb75 100644 --- a/.github/workflows/bitcode-gate-quality.yml +++ b/.github/workflows/bitcode-gate-quality.yml @@ -442,6 +442,9 @@ jobs: if [ -f scripts/check-v42-gate7-ai-reading-demonstration.mjs ]; then node scripts/check-v42-gate7-ai-reading-demonstration.mjs --skip-branch-check --skip-package-tests --skip-demonstration-tests fi + if [ -f scripts/check-v42-gate8-local-staging-mvp-rehearsal.mjs ]; then + node scripts/check-v42-gate8-local-staging-mvp-rehearsal.mjs --skip-branch-check --skip-package-tests --skip-uapi-tests + fi fi else echo "Unexpected BITCODE_SPEC.txt pointer: $POINTER" >&2 diff --git a/BITCODE_SPEC_V42.md b/BITCODE_SPEC_V42.md index 8bb252ef..77fd49f1 100644 --- a/BITCODE_SPEC_V42.md +++ b/BITCODE_SPEC_V42.md @@ -91,6 +91,10 @@ These objects bind to existing Bitcode objects: deposits, BTD ranges, AssetPacks The V42 operator chain is: admit source, prove Depository availability, expose compensation posture, accept a Read Request, synthesize a Need, review or resynthesize the Need, request Finding Fits, search many Depository candidates, rank and select fitting deposits, synthesize a source-safe AssetPack preview, quote BTD/BTC purchase terms, settle BTC, transfer BTD rights, unlock source-bearing delivery, create repository pull request, journal ledger/database/storage synchronization, and expose source-safe telemetry and proof readback. +V42 Gate 8 must rehearse that whole chain locally and in staging-testnet before promotion. +The local/staging full MVP rehearsal binds Gates 2 through 7 together as one operator-readable path: deposit source, request read, review synthesized Need, request Finding Fits, review source-safe AssetPack preview and quote, buy/settle, transfer BTD rights, receive repository delivery, and verify the AI-reading value demonstration remains valid. +The rehearsal is source-safe metadata only: it may carry lane ids, stage ids, proof roots, staging-testnet project references, command ids, readiness families, database stream posture, telemetry roots, reconciliation roots, delivery roots, and blocker/repair summaries, but it may not serialize secrets, protected source, raw protected prompts, raw interpolated prompts, raw provider responses, unpaid AssetPack source, wallet private material, private settlement payloads, or live rehearsal logs. + ## V42 Gate 1 MVP Experience Roadmap And Spec Opening Gate 1 opens the V42 spec family, branch posture, workflow posture, checker, roadmap, docs, and reliable MVP experience vocabulary. @@ -165,6 +169,11 @@ The accepted proof is an AI-reading AssetPack improvement: public-only assistanc Gate 8 must rehearse the full MVP path locally and in staging-testnet without value-bearing mainnet behavior. It must exercise deposit, Read Request, Need synthesis/review/resynthesis, Finding Fits, AssetPack preview, quote, settlement simulation or testnet observation, BTD rights projection, repository delivery, telemetry, proof artifacts, and repair readback. +Gate 8 implements the local/staging full MVP rehearsal proof. +The generated artifact `.bitcode/v42-local-staging-mvp-rehearsal.json` binds the closed V42 product artifacts from Gates 2 through 7 to the package `ReadingLocalStagingRehearsal`, the Vercel Sandbox harness, staging-testnet Supabase project `tkpyosihuouusyaxtbau`, rich execution-log readback, ledger/database/object-storage reconciliation, post-settlement pull-request delivery, source-safe operator receipts, and blocked value-bearing mainnet posture. +Gate 8 does not promote mainnet, does not split `/terminal`, and does not rename `/exchange`. +It proves the current MVP path is rehearseable under local and staging-testnet lanes while preserving V43+ as the route-vocabulary cleanup and agentic deposit AssetPack option work. +The validating command is `pnpm run check:v42-gate8`. ## V42 Gate 9 V42 Promotion Readiness diff --git a/BITCODE_SPEC_V42_DELTA.md b/BITCODE_SPEC_V42_DELTA.md index 14d36df1..2e337fd3 100644 --- a/BITCODE_SPEC_V42_DELTA.md +++ b/BITCODE_SPEC_V42_DELTA.md @@ -67,6 +67,8 @@ Gate 7 now binds the local AI-reading demonstration runtime, public-data-only ba ### Gate 8: Local And Staging-Testnet Full MVP Rehearsal Run and prove the complete MVP path locally and in staging-testnet with value-bearing mainnet blocked. +Gate 8 now binds staging-testnet full MVP rehearsal to the local lane, Vercel Sandbox operator receipt posture, Supabase project `tkpyosihuouusyaxtbau`, Gates 2 through 7 generated artifacts, `ReadingLocalStagingRehearsal`, source-safe telemetry/database readback, ledger/database/storage reconciliation, post-settlement repository delivery, `.bitcode/v42-local-staging-mvp-rehearsal.json`, `rehearse:v42-local-staging`, and `check:v42-gate8`. +The rehearsal artifact is metadata only and does not serialize secrets, protected source, raw prompts, raw provider responses, unpaid AssetPack source, wallet private material, private settlement payloads, or live rehearsal logs. ### Gate 9: V42 Promotion Readiness diff --git a/BITCODE_SPEC_V42_NOTES.md b/BITCODE_SPEC_V42_NOTES.md index 397e6668..8ed5d07e 100644 --- a/BITCODE_SPEC_V42_NOTES.md +++ b/BITCODE_SPEC_V42_NOTES.md @@ -84,6 +84,14 @@ The demonstration must remain minimal, local, deterministic where feasible, and Gate 7 records that proof as a public-data-only baseline, a reviewed local Need, a local Depository Finding Fits step, a selected AssetPack preview, an AssetPack-enhanced AI-reading answer, and deterministic benchmark uplift. The demonstration proves value without weakening the settlement-gated visibility boundary: protected source is still withheld until settlement, and the demonstration remains independent from product runtime imports. +## Gate 8 local/staging rehearsal note + +Gate 8 records the source-safe full MVP rehearsal posture across local and staging-testnet lanes. +It composes the already-closed V42 Depositing, Reading state, ReadNeed review/resynthesis, Finding Fits preview/quote, settlement rights delivery, and AI-reading demonstration proofs into one operator-readable rehearsal artifact. +The rehearsal binds `ReadingLocalStagingRehearsal`, Vercel Sandbox operator receipts, staging-testnet Supabase project `tkpyosihuouusyaxtbau`, rich execution-log readback, database streaming, ledger/database/storage reconciliation, post-settlement pull-request delivery, and explicit value-bearing mainnet blocking. +It is intentionally source-safe metadata only: secrets, protected source, raw protected prompts, raw interpolated prompts, raw provider responses, unpaid AssetPack source, wallet private material, private settlement payloads, and live rehearsal logs remain outside tracked artifacts. +Gate 8 does not implement the V43+ route vocabulary, but it keeps the future product shape visible: `/read`, `/deposit`, and `/packs` remain the next route cleanup once V42 proves the current MVP path. + ## V43+ agentic depositing roadmap note V43 or a later explicitly opened version should evolve the deposit side into an agentic AssetPack option experience for enterprises. diff --git a/BITCODE_SPEC_V42_PARITY_MATRIX.md b/BITCODE_SPEC_V42_PARITY_MATRIX.md index 80cd106d..9e16088a 100644 --- a/BITCODE_SPEC_V42_PARITY_MATRIX.md +++ b/BITCODE_SPEC_V42_PARITY_MATRIX.md @@ -39,7 +39,7 @@ This matrix records the reliable MVP product surfaces that must become promotion | Finding Fits preview and quote | Many-candidate search, selected-fit provenance, source-safe preview, and quote are product-ready | `.bitcode/v42-readfitsfinding-preview-quote.json`, `ReadFitsFindingRuntime`, `AssetPackPreviewBoundary`, harness preview summary, Terminal preview/quote/provenance readback | implemented | | Settlement and delivery | BTC/BTD settlement, rights transfer, compensation, and repository PR delivery are synchronized | `.bitcode/v42-settlement-rights-delivery.json`, `AssetPackSettlementRightsDeliveryBoundary`, live harness settlement boundary, route summary, Terminal settlement readback | implemented | | AI-reading demonstration | Standalone demonstration proves AssetPack improves AI beyond public-data-only baseline | `.bitcode/v42-ai-reading-demonstration.json`, `protocol-demonstration/src/ai-reading-demonstration.js`, `test:v42-ai-reading-mvp` | implemented | -| Local/staging rehearsal | Full MVP path rehearsed locally and in staging-testnet with mainnet blocked | later V42 Gate 8 artifact | draft-required | +| Local/staging rehearsal | Full MVP path rehearsed locally and in staging-testnet with mainnet blocked | `.bitcode/v42-local-staging-mvp-rehearsal.json`, `ReadingLocalStagingRehearsal`, `rehearse:v42-local-staging`, `check:v42-gate8` | implemented | | Promotion readiness | V42 proof and workflow promotion ready | later V42 Gate 9 artifact | draft-required | ## V42 implementation checklist @@ -53,7 +53,7 @@ This matrix records the reliable MVP product surfaces that must become promotion | Gate 5 | ReadFitsFinding AssetPack preview and quote closure artifact | implemented | | Gate 6 | Settlement rights transfer and repository delivery closure artifact | implemented | | Gate 7 | AI-reading dominant demonstration MVP artifact | implemented | -| Gate 8 | Local and staging-testnet full MVP rehearsal artifact | draft-required | +| Gate 8 | Local and staging-testnet full MVP rehearsal artifact | implemented | | Gate 9 | Promotion readiness artifact and workflow | draft-required | ## V42 accepted boundaries diff --git a/README.md b/README.md index 9a64b4dd..4c434781 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,18 @@ AssetPack-enhanced answer after a reviewed local Need and local Finding Fits step select the deposited runbook AssetPack. The benchmark uplift is deterministic, the demonstration stays self-contained, and protected source remains withheld before settlement. +V42 Gate 8 adds the local/staging-testnet full MVP rehearsal with +`ReadingLocalStagingRehearsal`, +`scripts/rehearse-v42-local-staging-mvp.mjs`, +`.bitcode/v42-local-staging-mvp-rehearsal.json`, and `check:v42-gate8`. +It binds Gates 2 through 7 into one source-safe operator path: deposit source, +request read, review synthesized Need, request Finding Fits, review source-safe +AssetPack preview and quote, buy/settle, receive repository delivery, and +verify AI-reading uplift. The staging lane is bound to Supabase project +`tkpyosihuouusyaxtbau`; operator receipts and generated artifacts never +serialize secrets, protected source, raw prompts, provider responses, unpaid +AssetPack source, wallet private material, private settlement payloads, or +live rehearsal logs. V43+ is roadmapped as the later agentic depositing evolution: repository agents synthesize deposit AssetPack options from connected enterprise code, Depository state, and Reading demand; enterprises approve or reject diff --git a/SPECIFICATIONS_ROADMAP.md b/SPECIFICATIONS_ROADMAP.md index 18fb8a46..08d6297f 100644 --- a/SPECIFICATIONS_ROADMAP.md +++ b/SPECIFICATIONS_ROADMAP.md @@ -5,8 +5,8 @@ - Current active canonical pointer: `BITCODE_SPEC.txt` -> `V41` - Current active canon: `BITCODE_SPEC_V41.md` - Current draft target: `BITCODE_SPEC_V42.md`. -- Current working gate: V42 Gate 7 AI-Reading Dominant Demonstration MVP. -- Next queued gate after V42 Gate 7: V42 Gate 8 Local And Staging-Testnet Full MVP Rehearsal. +- Current working gate: V42 Gate 8 Local And Staging-Testnet Full MVP Rehearsal. +- Next queued gate after V42 Gate 8: V42 Gate 9 Promotion Readiness. - Latest closed version: V41 Prompt And PromptPart Excellence, which promoted PromptPart and Prompt inventory, registry interpolation contracts, Reading prompt baselines, ReadNeedComprehensionSynthesis prompt hardening, ReadFitsFindingSynthesis prompt hardening, Conversation/tool/interface prompt rewrite, prompt benchmark telemetry, and V41 promotion readiness. - Recent V42 opening anchor: reliable MVP experience opens over promoted V41 with V42 SPEC, DELTA, NOTES, and PARITY files, `check:v42-gate1`, active V41 / draft V42 posture, and a nine-gate plan for shortest-path Depositing, five-step Reading, ReadNeed product closure, ReadFitsFinding preview and quote closure, settlement and repository delivery, AI-reading demonstration, local/staging rehearsal, and promotion readiness. - V42 Gate 2 closure anchor: reliable MVP experience now owns source-safe Depositing compensation visibility through `DepositorySupplyCompensationPreview`, deposit route `depositoryEvidence.compensationPreview`, deterministic `.bitcode/v42-depositing-shortest-path.json`, route/API readiness checks, source validation, Depository search/vector/storage projection, source-to-shares compensation readback keys, Terminal compensation roots, focused package/protocol tests, workflow wiring, and `check:v42-gate2`. @@ -15,6 +15,7 @@ - V42 Gate 5 closure anchor: reliable MVP experience now owns ReadFitsFinding preview and quote closure through accepted-Need-gated `ReadFitsFindingRuntime`, many-channel Depository search, selected-fit provenance, `AssetPackPreviewBoundary`, deterministic share-to-fee quote receipts, disclosure review, settlement instructions, delivery lock, harness evidence summaries, Terminal preview/quote/provenance readback, deterministic `.bitcode/v42-readfitsfinding-preview-quote.json`, focused package/route/protocol tests, workflow wiring, and `check:v42-gate5`. - V42 Gate 6 closure anchor: reliable MVP experience now owns settlement rights transfer and repository delivery closure through `AssetPackSettlementRightsDeliveryBoundary`, BTC payment observation/finality, BTD read and rights transfer receipts, source-to-shares compensation conservation, delivery unlock, ledger/database/object-storage reconciliation, live harness materialization, route settlement summaries, Terminal settlement rights readback, deterministic `.bitcode/v42-settlement-rights-delivery.json`, focused package/host/route/protocol tests, workflow wiring, and `check:v42-gate6`. - V42 Gate 7 closure anchor: reliable MVP experience now owns AI-reading demonstration proof through `protocol-demonstration/src/ai-reading-demonstration.js`, public-data-only baseline scoring, reviewed local ReadNeed synthesis, local Depository Finding Fits selection, source-safe AssetPack preview, AssetPack-enhanced AI-reading answer scoring, deterministic benchmark uplift, `.bitcode/v42-ai-reading-demonstration.json`, focused demonstration/protocol tests, workflow wiring, and `check:v42-gate7`. +- V42 Gate 8 closure anchor: reliable MVP experience now owns local/staging-testnet full MVP rehearsal proof through `ReadingLocalStagingRehearsal`, source-safe V42 operator receipts, staging-testnet Supabase project `tkpyosihuouusyaxtbau`, Gates 2 through 7 generated artifact binding, deposit source, request read, review synthesized Need, request Finding Fits, review source-safe AssetPack preview and quote, buy/settle, receive repository delivery, rich telemetry/database readback, ledger/database/storage reconciliation, blocked value-bearing mainnet, deterministic `.bitcode/v42-local-staging-mvp-rehearsal.json`, focused package/protocol/UAPI checks, workflow wiring, and `check:v42-gate8`. - Recent V41 closure anchor: V41 canonical promotion updated `BITCODE_SPEC.txt` to `V41`, generated `BITCODE_SPEC_V41_PROVEN.md`, preserved active V41 / draft V42 runtime posture, and closed prompt-program excellence canon. - Recent V40 closure anchor: V40 canonical promotion updated `BITCODE_SPEC.txt` to `V40`, generated `BITCODE_SPEC_V40_PROVEN.md`, preserved active V40 / draft V41 runtime posture, and closed exhaustive commercial application testing canon. - Recent V39 closure anchor: V39 canonical promotion updated `BITCODE_SPEC.txt` to `V39`, generated `BITCODE_SPEC_V39_PROVEN.md`, preserved active V39 / draft V40 runtime posture, and closed commercial Reading readiness canon. diff --git a/package.json b/package.json index 5252b5e3..e90ed01f 100644 --- a/package.json +++ b/package.json @@ -322,6 +322,10 @@ "generate:v42-ai-reading-demonstration": "node scripts/generate-v42-ai-reading-demonstration.mjs", "check:v42-ai-reading-demonstration": "node scripts/generate-v42-ai-reading-demonstration.mjs --check", "check:v42-gate7": "node scripts/check-v42-gate7-ai-reading-demonstration.mjs", + "rehearse:v42-local-staging": "node scripts/rehearse-v42-local-staging-mvp.mjs", + "generate:v42-local-staging-mvp-rehearsal": "node scripts/generate-v42-local-staging-mvp-rehearsal.mjs", + "check:v42-local-staging-mvp-rehearsal": "node scripts/generate-v42-local-staging-mvp-rehearsal.mjs --check", + "check:v42-gate8": "node scripts/check-v42-gate8-local-staging-mvp-rehearsal.mjs", "generate:v38-inference-surface-inventory": "node scripts/generate-v38-inference-surface-inventory.mjs", "check:v38-inference-surface-inventory": "node scripts/generate-v38-inference-surface-inventory.mjs --check", "check:v38-gate2": "node scripts/check-v38-gate2-inference-surface-inventory.mjs", diff --git a/packages/pipelines/asset-pack/README.md b/packages/pipelines/asset-pack/README.md index 1da60ea5..047c0290 100644 --- a/packages/pipelines/asset-pack/README.md +++ b/packages/pipelines/asset-pack/README.md @@ -284,6 +284,16 @@ payloads are not serialized. Value-bearing mainnet admission remains blocked. The source-safe artifact is `.bitcode/v39-local-staging-reading-rehearsal.json`, checked by `pnpm run check:v39-gate10`. +V42 Gate 8 reuses `ReadingLocalStagingRehearsal` as the package proof body for +the reliable MVP local/staging full rehearsal. The V42 artifact +`.bitcode/v42-local-staging-mvp-rehearsal.json` binds that package model to +the closed V42 Depositing, Reading state, ReadNeed review/resynthesis, Finding +Fits preview/quote, settlement rights delivery, and AI-reading demonstration +artifacts. Use `pnpm run rehearse:v42-local-staging` for source-safe operator +receipts and `pnpm run check:v42-gate8` for the full proof. Staging-testnet is +bound to Supabase project `tkpyosihuouusyaxtbau`; value-bearing mainnet stays +blocked, and generated rehearsal material remains metadata-only. + ### Vector Embedding Contract Depository vector recall uses the shared AssetPack embedding contract: diff --git a/packages/protocol/README.md b/packages/protocol/README.md index d50d90c3..b7d1dbc9 100644 --- a/packages/protocol/README.md +++ b/packages/protocol/README.md @@ -61,6 +61,7 @@ Current exported commercial helpers include: - `V41PromotionReadinessReport` helpers for V41 source-safe prompt-program promotion readiness across all V41 prompt artifacts, generated proof support, workflow posture, promotion dry-run support, and active V41 / draft V42 runtime preparation; - `V42SettlementRightsDelivery` helpers for V42 source-safe BTC payment observation, finality gating, source-to-shares compensation, BTD read-right transfer, repository delivery unlock, ledger/database/object-storage reconciliation, Terminal readback, and source-safe paid-boundary proof; - `V42AiReadingDemonstration` helpers for V42 source-safe AI-reading demonstration proof: public-data-only baseline, reviewed local Need, local Finding Fits, source-safe AssetPack preview, AssetPack-enhanced AI answer, deterministic benchmark uplift, self-contained demonstration boundary, and workflow wiring; +- `V42LocalStagingMvpRehearsal` helpers for V42 source-safe local/staging-testnet full MVP rehearsal proof across Depositing, Reading, Finding Fits, preview/quote, settlement, BTD rights transfer, repository delivery, AI-reading uplift, telemetry/database readback, operator receipts, and blocked value-bearing mainnet; - canonical proven-generation helpers; - the package app/server context used by commercial interfaces. @@ -247,6 +248,18 @@ The artifact is source-safe metadata only and covers the self-contained local Need, local Depository fit selection, AssetPack preview, AssetPack- enhanced answer, deterministic benchmark uplift, settlement-gated source visibility, and workflow proof wiring. +V42 Gate 8 adds `V42LocalStagingMvpRehearsal` through +`packages/protocol/src/canonical/v42-local-staging-mvp-rehearsal.js`, +`packages/protocol/test/v42-local-staging-mvp-rehearsal.test.js`, +`.bitcode/v42-local-staging-mvp-rehearsal.json`, +`rehearse:v42-local-staging`, +`generate:v42-local-staging-mvp-rehearsal`, +`check:v42-local-staging-mvp-rehearsal`, and `check:v42-gate8`. +The artifact is source-safe metadata only and binds Gates 2 through 7 into the +local/staging full MVP rehearsal: deposit source, request read, review +synthesized Need, request Finding Fits, review source-safe AssetPack preview +and quote, buy/settle, receive repository delivery, inspect telemetry/database +readback, and keep value-bearing mainnet blocked. V40 Gate 2 adds `V40TestInventoryCoverageMatrix` through `packages/protocol/src/canonical/v40-test-inventory-coverage-matrix.js`, `packages/protocol/test/v40-test-inventory-coverage-matrix.test.js`, diff --git a/packages/protocol/src/canonical/v42-ai-reading-demonstration.js b/packages/protocol/src/canonical/v42-ai-reading-demonstration.js index 921737dd..8a8ba46c 100644 --- a/packages/protocol/src/canonical/v42-ai-reading-demonstration.js +++ b/packages/protocol/src/canonical/v42-ai-reading-demonstration.js @@ -188,7 +188,7 @@ function buildPredicateResults(repoRoot) { predicateResult('v42-delta-expanded', SOURCE_ROOTS.v42Delta, sources.v42Delta.includes('Gate 7 now binds') && sources.v42Delta.includes('public-data-only baseline')), predicateResult('v42-notes-expanded', SOURCE_ROOTS.v42Notes, sources.v42Notes.includes('Gate 7 records') && sources.v42Notes.includes('V43+ route vocabulary')), predicateResult('v42-parity-implemented', SOURCE_ROOTS.v42Parity, sources.v42Parity.includes('AI-reading demonstration') && sources.v42Parity.includes('implemented')), - predicateResult('roadmap-advanced-to-gate7', SOURCE_ROOTS.roadmap, sources.roadmap.includes('Current working gate: V42 Gate 7') && sources.roadmap.includes('V42 Gate 7 closure anchor')), + predicateResult('roadmap-records-gate7-closure', SOURCE_ROOTS.roadmap, sources.roadmap.includes('V42 Gate 7 closure anchor') && sources.roadmap.includes('check:v42-gate7')), predicateResult('readmes-document-gate7', SOURCE_ROOTS.rootReadme, sources.rootReadme.includes('V42 Gate 7') && sources.demoReadme.includes('V42 AI-reading demonstration') && sources.protocolReadme.includes('V42AiReadingDemonstration')), ]; } diff --git a/packages/protocol/src/canonical/v42-local-staging-mvp-rehearsal.js b/packages/protocol/src/canonical/v42-local-staging-mvp-rehearsal.js new file mode 100644 index 00000000..481b3055 --- /dev/null +++ b/packages/protocol/src/canonical/v42-local-staging-mvp-rehearsal.js @@ -0,0 +1,417 @@ +// @ts-check + +import crypto from 'node:crypto'; +import { existsSync, readFileSync } from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const DEFAULT_REPO_ROOT = path.resolve(__dirname, '..', '..', '..', '..'); + +export const V42_LOCAL_STAGING_MVP_REHEARSAL_ARTIFACT_PATH = + '.bitcode/v42-local-staging-mvp-rehearsal.json'; +export const V42_LOCAL_STAGING_MVP_REHEARSAL_SCHEMA_ID = + 'bitcode.v42.localStagingMvpRehearsal.v1'; +export const V42_LOCAL_STAGING_MVP_REHEARSAL_VERSION = 'V42'; +export const V42_LOCAL_STAGING_MVP_REHEARSAL_CURRENT_TARGET = 'V41'; +export const V42_LOCAL_STAGING_MVP_REHEARSAL_SOURCE_SAFETY_VERDICT = + 'source-safe-v42-local-staging-mvp-rehearsal-metadata'; + +export const V42_LOCAL_STAGING_MVP_REHEARSAL_LANE_IDS = Object.freeze([ + 'local', + 'staging-testnet', +]); + +export const V42_LOCAL_STAGING_MVP_REHEARSAL_STAGE_IDS = Object.freeze([ + 'deposit-source', + 'request-read', + 'review-synthesized-need', + 'request-finding-fits', + 'review-assetpack-preview', + 'buy-assetpack-settle', + 'receive-repository-delivery', +]); + +export const V42_LOCAL_STAGING_MVP_REHEARSAL_ROW_IDS = Object.freeze([ + 'lane:local-full-mvp-rehearsal', + 'lane:staging-testnet-full-mvp-rehearsal', + 'deposit:source-admission-compensation-readback', + 'reading:request-read-state', + 'reading:need-review-resynthesis', + 'fits:many-candidate-depository-search', + 'assetpack:source-safe-preview-quote', + 'settlement:btd-rights-delivery', + 'demonstration:ai-reading-uplift', + 'telemetry:rich-stream-database-readback', + 'sync:ledger-database-storage-reconciliation', + 'operator:source-safe-rehearsal-receipts', + 'boundary:value-bearing-mainnet-blocked', + 'proof:artifact-tests-workflows-docs', +]); + +const SOURCE_ROOTS = Object.freeze({ + gate2Artifact: '.bitcode/v42-depositing-shortest-path.json', + gate3Artifact: '.bitcode/v42-reading-shortest-path-state-machine.json', + gate4Artifact: '.bitcode/v42-readneed-review-resynthesis-product-closure.json', + gate5Artifact: '.bitcode/v42-readfitsfinding-preview-quote.json', + gate6Artifact: '.bitcode/v42-settlement-rights-delivery.json', + gate7Artifact: '.bitcode/v42-ai-reading-demonstration.json', + rehearsalModel: 'packages/pipelines/asset-pack/src/reading-local-staging-rehearsal.ts', + rehearsalTest: 'packages/pipelines/asset-pack/src/__tests__/reading-local-staging-rehearsal.test.ts', + postprocess: 'packages/pipelines/asset-pack/src/postprocess.ts', + pipelineIndex: 'packages/pipelines/asset-pack/src/index.ts', + depositorySearch: 'packages/pipelines/asset-pack/src/depository-search.ts', + readNeedRuntime: 'packages/pipelines/asset-pack/src/read-need-review-resynthesis.ts', + readFitsRuntime: 'packages/pipelines/asset-pack/src/read-fits-finding-runtime.ts', + previewBoundary: 'packages/pipelines/asset-pack/src/asset-pack-preview-boundary.ts', + settlementBoundary: 'packages/pipelines/asset-pack/src/asset-pack-settlement-rights-delivery.ts', + operationalReadback: 'packages/pipelines/asset-pack/src/reading-operational-telemetry-repair-readback.ts', + pipelineLogUi: 'uapi/components/base/bitcode/execution/pipeline-execution-log.tsx', + terminalWorkbench: 'uapi/app/terminal/TerminalDepositReadWorkbench.tsx', + harnessRunner: 'uapi/app/api/pipeline-harness/asset-pack/runner.ts', + harnessPreflight: 'uapi/app/api/pipeline-harness/asset-pack/preflight.ts', + harnessRouteTest: 'uapi/tests/api/pipelineHarnessRoute.test.ts', + harnessPreflightTest: 'uapi/tests/api/pipelineHarnessPreflight.test.ts', + pipelineHostHarness: 'packages/pipeline-hosts/src/asset-pack-harness.ts', + operatorScript: 'scripts/rehearse-v42-local-staging-mvp.mjs', + generator: 'scripts/generate-v42-local-staging-mvp-rehearsal.mjs', + checkScript: 'scripts/check-v42-gate8-local-staging-mvp-rehearsal.mjs', + protocolCanonical: 'packages/protocol/src/canonical/v42-local-staging-mvp-rehearsal.js', + protocolTest: 'packages/protocol/test/v42-local-staging-mvp-rehearsal.test.js', + protocolIndex: 'packages/protocol/src/index.js', + protocolTypes: 'packages/protocol/src/index.d.ts', + rootReadme: 'README.md', + protocolReadme: 'packages/protocol/README.md', + assetPackReadme: 'packages/pipelines/asset-pack/README.md', + terminalReadme: 'uapi/app/terminal/README.md', + v42Spec: 'BITCODE_SPEC_V42.md', + v42Delta: 'BITCODE_SPEC_V42_DELTA.md', + v42Notes: 'BITCODE_SPEC_V42_NOTES.md', + v42Parity: 'BITCODE_SPEC_V42_PARITY_MATRIX.md', + roadmap: 'SPECIFICATIONS_ROADMAP.md', + packageJson: 'package.json', + gateWorkflow: '.github/workflows/bitcode-gate-quality.yml', + canonWorkflow: '.github/workflows/bitcode-canon-quality.yml', +}); + +const FORBIDDEN_PAYLOAD_CLASSES = Object.freeze([ + 'secret-values', + 'provider-tokens', + 'wallet-private-material', + 'protected-source-payloads', + 'raw-protected-prompts', + 'raw-interpolated-prompts', + 'raw-provider-responses', + 'unpaid-assetpack-source', + 'live-rehearsal-log-payloads', + 'value-bearing-mainnet-admission', +]); + +function digest(value) { + return crypto.createHash('sha256').update(value).digest('hex').slice(0, 24); +} + +function rowRoot(id) { + return `v42-local-staging-mvp-rehearsal-row:${digest(id)}`; +} + +function readSource(repoRoot, sourcePath) { + const absolutePath = path.join(repoRoot, sourcePath); + return existsSync(absolutePath) ? readFileSync(absolutePath, 'utf8') : ''; +} + +function sourceExists(repoRoot, sourcePath) { + return existsSync(path.join(repoRoot, sourcePath)); +} + +function predicateResult(id, sourcePath, passed) { + return { id, sourcePath, passed: Boolean(passed) }; +} + +function row(input) { + return { + ...input, + rowRoot: rowRoot(input.rowId), + sourceSafetyClass: 'source_safe_v42_local_staging_mvp_rehearsal_metadata', + sourceSafeMetadataOnly: true, + protectedSourcePayloadSerialized: false, + rawProtectedPromptVisible: false, + rawInterpolatedPromptVisible: false, + rawProviderResponseVisible: false, + unpaidAssetPackSourceVisible: false, + credentialsSerialized: false, + walletPrivateMaterialVisible: false, + privateSettlementPayloadVisible: false, + liveRehearsalLogPayloadSerialized: false, + valueBearingMainnetAdmitted: false, + forbiddenPayloadClasses: [...FORBIDDEN_PAYLOAD_CLASSES], + }; +} + +export const V42_LOCAL_STAGING_MVP_REHEARSAL_ROWS = Object.freeze([ + row({ + rowId: 'lane:local-full-mvp-rehearsal', + laneId: 'local', + stageId: null, + purpose: + 'Bind the local MVP rehearsal to source-safe dry-run receipts, local package checks, and explicit sandbox execution opt-in.', + sourceRoots: [SOURCE_ROOTS.operatorScript, SOURCE_ROOTS.rehearsalModel, SOURCE_ROOTS.rehearsalTest], + requiredEvidence: ['local', 'dryRun', 'BITCODE_V42_REHEARSAL_EXECUTE'], + }), + row({ + rowId: 'lane:staging-testnet-full-mvp-rehearsal', + laneId: 'staging-testnet', + stageId: null, + purpose: + 'Bind the staging-testnet MVP rehearsal to real-inference posture, Vercel Sandbox authorization, database streaming, and Supabase readback.', + sourceRoots: [SOURCE_ROOTS.operatorScript, SOURCE_ROOTS.harnessPreflight, SOURCE_ROOTS.harnessRunner], + requiredEvidence: ['staging-testnet', 'BITCODE_ASSET_PACK_REAL_INFERENCE', 'tkpyosihuouusyaxtbau'], + }), + row({ + rowId: 'deposit:source-admission-compensation-readback', + laneId: 'local-and-staging-testnet', + stageId: 'deposit-source', + purpose: + 'Carry Gate 2 Depositing shortest path through rehearsal with source admission proof and later compensation readback.', + sourceRoots: [SOURCE_ROOTS.gate2Artifact, SOURCE_ROOTS.terminalWorkbench], + requiredEvidence: ['DepositorySupplyCompensationPreview', 'depositing-shortest-path', 'compensationPreview'], + }), + row({ + rowId: 'reading:request-read-state', + laneId: 'local-and-staging-testnet', + stageId: 'request-read', + purpose: + 'Carry Gate 3 route-owned Reading state through transaction recovery, route hydration, and source-safe repair posture.', + sourceRoots: [SOURCE_ROOTS.gate3Artifact, SOURCE_ROOTS.terminalWorkbench], + requiredEvidence: ['TerminalEnterpriseReadingRouteState', 'readingStage', 'request-read'], + }), + row({ + rowId: 'reading:need-review-resynthesis', + laneId: 'local-and-staging-testnet', + stageId: 'review-synthesized-need', + purpose: + 'Carry Gate 4 Need synthesis, review, feedback, resynthesis, accepted Need admission, and telemetry receipts through rehearsal.', + sourceRoots: [SOURCE_ROOTS.gate4Artifact, SOURCE_ROOTS.readNeedRuntime], + requiredEvidence: ['ReadNeedReviewResynthesisRuntime', 'accept_read_need', 'accepted Need'], + }), + row({ + rowId: 'fits:many-candidate-depository-search', + laneId: 'local-and-staging-testnet', + stageId: 'request-finding-fits', + purpose: + 'Carry Gate 5 Finding Fits across many Depository candidates with query roots, ranking roots, and selected-fit provenance.', + sourceRoots: [SOURCE_ROOTS.gate5Artifact, SOURCE_ROOTS.readFitsRuntime, SOURCE_ROOTS.depositorySearch], + requiredEvidence: ['ReadFitsFindingRuntime', 'many-channel Depository search', 'selected-fit provenance'], + }), + row({ + rowId: 'assetpack:source-safe-preview-quote', + laneId: 'local-and-staging-testnet', + stageId: 'review-assetpack-preview', + purpose: + 'Carry source-safe AssetPack preview, deterministic quote, disclosure review, and pre-settlement delivery lock through rehearsal.', + sourceRoots: [SOURCE_ROOTS.gate5Artifact, SOURCE_ROOTS.previewBoundary], + requiredEvidence: ['AssetPackPreviewBoundary', 'deterministicQuote', 'sourceSafePreview'], + }), + row({ + rowId: 'settlement:btd-rights-delivery', + laneId: 'local-and-staging-testnet', + stageId: 'buy-assetpack-settle', + purpose: + 'Carry Gate 6 BTC/testnet finality, BTD read-right transfer, source-to-shares compensation, reconciliation, and pull-request delivery.', + sourceRoots: [SOURCE_ROOTS.gate6Artifact, SOURCE_ROOTS.settlementBoundary], + requiredEvidence: ['AssetPackSettlementRightsDeliveryBoundary', 'BtdRightsTransferReceipt', 'source_bearing_pull_request_ready'], + }), + row({ + rowId: 'demonstration:ai-reading-uplift', + laneId: 'local-and-staging-testnet', + stageId: null, + purpose: + 'Carry Gate 7 AI-reading value proof into the full MVP rehearsal as the product demonstration of why Reading buys an AssetPack.', + sourceRoots: [SOURCE_ROOTS.gate7Artifact], + requiredEvidence: ['public-data-only', 'assetpack-enhanced-after-rights', 'minimumUpliftBp'], + }), + row({ + rowId: 'telemetry:rich-stream-database-readback', + laneId: 'local-and-staging-testnet', + stageId: null, + purpose: + 'Prove rich pipeline stream rows, execution ids, phase/agent/step/generation metadata, and database readback remain available for debugging.', + sourceRoots: [SOURCE_ROOTS.rehearsalModel, SOURCE_ROOTS.operationalReadback, SOURCE_ROOTS.pipelineLogUi], + requiredEvidence: ['phase', 'ptrr-agent', 'thricified-generation', 'tool', 'databaseReadbackRequired'], + }), + row({ + rowId: 'sync:ledger-database-storage-reconciliation', + laneId: 'local-and-staging-testnet', + stageId: null, + purpose: + 'Prove ledger, database, object storage, wallet, and repository delivery projections reconcile before source-bearing delivery.', + sourceRoots: [SOURCE_ROOTS.gate6Artifact, SOURCE_ROOTS.settlementBoundary, SOURCE_ROOTS.rehearsalModel], + requiredEvidence: ['ledgerDatabaseStorageSynchronized', 'reconciliationRoot', 'aligned'], + }), + row({ + rowId: 'operator:source-safe-rehearsal-receipts', + laneId: 'local-and-staging-testnet', + stageId: null, + purpose: + 'Provide operator receipt generation for local and staging-testnet lanes without serializing env values, protected source, live logs, or settlement payloads.', + sourceRoots: [SOURCE_ROOTS.operatorScript, SOURCE_ROOTS.checkScript], + requiredEvidence: ['sourceSafety', 'secretValueSerialized: false', 'receiptRoot'], + }), + row({ + rowId: 'boundary:value-bearing-mainnet-blocked', + laneId: 'local-and-staging-testnet', + stageId: null, + purpose: + 'Keep the MVP rehearsal non-value-bearing and blocked from mainnet while proving the staged BTC/BTD protocol path.', + sourceRoots: [SOURCE_ROOTS.operatorScript, SOURCE_ROOTS.rehearsalModel], + requiredEvidence: ['valueBearingMainnetAdmitted: false', 'serverCustody: false', 'production-mainnet blocked'], + }), + row({ + rowId: 'proof:artifact-tests-workflows-docs', + laneId: 'local-and-staging-testnet', + stageId: null, + purpose: + 'Bind Gate 8 to deterministic artifact generation, protocol tests, package rehearsal tests, docs, workflows, and package scripts.', + sourceRoots: [SOURCE_ROOTS.protocolTest, SOURCE_ROOTS.packageJson, SOURCE_ROOTS.gateWorkflow, SOURCE_ROOTS.canonWorkflow], + requiredEvidence: ['v42-local-staging-mvp-rehearsal', 'check:v42-gate8', 'generate:v42-local-staging-mvp-rehearsal'], + }), +]); + +function artifactText(repoRoot, sourcePath) { + return readSource(repoRoot, sourcePath); +} + +function artifactPassed(repoRoot, sourcePath, artifactId) { + const text = artifactText(repoRoot, sourcePath); + if (!text) return false; + try { + const parsed = JSON.parse(text); + return parsed.artifactId === artifactId && parsed.passed === true; + } catch { + return false; + } +} + +function buildPredicateResults(repoRoot) { + const sources = Object.fromEntries( + Object.entries(SOURCE_ROOTS).map(([key, sourcePath]) => [key, readSource(repoRoot, sourcePath)]), + ); + + return [ + predicateResult('gate2-artifact-passed', SOURCE_ROOTS.gate2Artifact, artifactPassed(repoRoot, SOURCE_ROOTS.gate2Artifact, 'v42-depositing-shortest-path')), + predicateResult('gate3-artifact-passed', SOURCE_ROOTS.gate3Artifact, artifactPassed(repoRoot, SOURCE_ROOTS.gate3Artifact, 'v42-reading-shortest-path-state-machine')), + predicateResult('gate4-artifact-passed', SOURCE_ROOTS.gate4Artifact, artifactPassed(repoRoot, SOURCE_ROOTS.gate4Artifact, 'v42-readneed-review-resynthesis-product-closure')), + predicateResult('gate5-artifact-passed', SOURCE_ROOTS.gate5Artifact, artifactPassed(repoRoot, SOURCE_ROOTS.gate5Artifact, 'v42-readfitsfinding-preview-quote')), + predicateResult('gate6-artifact-passed', SOURCE_ROOTS.gate6Artifact, artifactPassed(repoRoot, SOURCE_ROOTS.gate6Artifact, 'v42-settlement-rights-delivery')), + predicateResult('gate7-artifact-passed', SOURCE_ROOTS.gate7Artifact, artifactPassed(repoRoot, SOURCE_ROOTS.gate7Artifact, 'v42-ai-reading-demonstration')), + predicateResult('rehearsal-model-covers-lanes', SOURCE_ROOTS.rehearsalModel, sources.rehearsalModel.includes('READING_LOCAL_STAGING_REHEARSAL_LANES') && sources.rehearsalModel.includes('staging-testnet') && sources.rehearsalModel.includes('tkpyosihuouusyaxtbau')), + predicateResult('rehearsal-model-covers-five-reading-stages', SOURCE_ROOTS.rehearsalModel, sources.rehearsalModel.includes('request-read') && sources.rehearsalModel.includes('review-synthesized-need') && sources.rehearsalModel.includes('request-finding-fits') && sources.rehearsalModel.includes('review-assetpack-preview') && sources.rehearsalModel.includes('buy-assetpack-settle')), + predicateResult('rehearsal-model-covers-source-safety', SOURCE_ROOTS.rehearsalModel, sources.rehearsalModel.includes('sourceSafeMetadataOnly: true') && sources.rehearsalModel.includes('valueBearingMainnetAdmitted: false') && sources.rehearsalModel.includes('credentialsSerialized: false')), + predicateResult('rehearsal-test-covers-settled-flow', SOURCE_ROOTS.rehearsalTest, sources.rehearsalTest.includes('covers the five Reading stages') && sources.rehearsalTest.includes('ledgerDatabaseStorageSynchronized: true') && sources.rehearsalTest.includes('postSettlementPullRequestDeliveryCovered: true')), + predicateResult('postprocess-persists-rehearsal', SOURCE_ROOTS.postprocess, sources.postprocess.includes('persistReadingLocalStagingRehearsal') && sources.postprocess.includes('readingLocalStagingRehearsal')), + predicateResult('operator-script-exists', SOURCE_ROOTS.operatorScript, sourceExists(repoRoot, SOURCE_ROOTS.operatorScript) && sources.operatorScript.includes('V42_REHEARSAL_LANES') && sources.operatorScript.includes('BITCODE_V42_REHEARSAL_EXECUTE')), + predicateResult('operator-script-binds-staging-env', SOURCE_ROOTS.operatorScript, sources.operatorScript.includes('BITCODE_ASSET_PACK_REAL_INFERENCE') && sources.operatorScript.includes('BITCODE_PIPELINE_STREAM_TO_DATABASE') && sources.operatorScript.includes('BITCODE_ENABLE_PIPELINE_HARNESS_API') && sources.operatorScript.includes('tkpyosihuouusyaxtbau')), + predicateResult('operator-script-source-safe', SOURCE_ROOTS.operatorScript, sources.operatorScript.includes('secretValueSerialized: false') && sources.operatorScript.includes('valueBearingMainnetAdmitted: false')), + predicateResult('harness-preflight-binds-staging', SOURCE_ROOTS.harnessPreflight, sources.harnessPreflight.includes('tkpyosihuouusyaxtbau') && sources.harnessPreflight.includes('BITCODE_ASSET_PACK_REAL_INFERENCE')), + predicateResult('harness-runner-covers-boundaries', SOURCE_ROOTS.harnessRunner, sources.harnessRunner.includes('assetPackPreviewBoundary') && sources.harnessRunner.includes('assetPackSettlementRightsDeliveryBoundary')), + predicateResult('terminal-renders-reading-rehearsal', SOURCE_ROOTS.terminalWorkbench, sources.terminalWorkbench.includes('readingLocalStagingRehearsal') && sources.terminalWorkbench.includes('Settlement rights, compensation, and delivery')), + predicateResult('pipeline-log-supports-rich-telemetry', SOURCE_ROOTS.pipelineLogUi, sources.pipelineLogUi.includes('metadata') && sources.pipelineLogUi.includes('Accordion')), + predicateResult('protocol-test-wired', SOURCE_ROOTS.protocolTest, sources.protocolTest.includes('buildV42LocalStagingMvpRehearsal') && sources.protocolTest.includes('rowCount, 14')), + predicateResult('protocol-exports-wired', SOURCE_ROOTS.protocolIndex, sources.protocolIndex.includes('buildV42LocalStagingMvpRehearsal') && sources.protocolTypes.includes('buildV42LocalStagingMvpRehearsal')), + predicateResult('package-scripts-wired', SOURCE_ROOTS.packageJson, sources.packageJson.includes('generate:v42-local-staging-mvp-rehearsal') && sources.packageJson.includes('rehearse:v42-local-staging') && sources.packageJson.includes('check:v42-gate8')), + predicateResult('workflows-run-gate8', SOURCE_ROOTS.gateWorkflow, sources.gateWorkflow.includes('check-v42-gate8-local-staging-mvp-rehearsal.mjs') && sources.canonWorkflow.includes('check-v42-gate8-local-staging-mvp-rehearsal.mjs')), + predicateResult('v42-docs-expanded', SOURCE_ROOTS.v42Spec, sources.v42Spec.includes('V42 Gate 8') && sources.v42Spec.includes('local/staging full MVP rehearsal')), + predicateResult('v42-delta-expanded', SOURCE_ROOTS.v42Delta, sources.v42Delta.includes('Gate 8 now binds') && sources.v42Delta.includes('staging-testnet full MVP rehearsal')), + predicateResult('v42-notes-expanded', SOURCE_ROOTS.v42Notes, sources.v42Notes.includes('Gate 8 records') && sources.v42Notes.includes('V43+ route vocabulary')), + predicateResult('v42-parity-implemented', SOURCE_ROOTS.v42Parity, sources.v42Parity.includes('Local/staging rehearsal') && sources.v42Parity.includes('implemented')), + predicateResult('roadmap-advanced-to-gate8', SOURCE_ROOTS.roadmap, sources.roadmap.includes('Current working gate: V42 Gate 8') && sources.roadmap.includes('V42 Gate 8 closure anchor')), + predicateResult('readmes-document-gate8', SOURCE_ROOTS.rootReadme, sources.rootReadme.includes('V42 Gate 8') && sources.protocolReadme.includes('V42LocalStagingMvpRehearsal') && sources.assetPackReadme.includes('ReadingLocalStagingRehearsal') && sources.terminalReadme.includes('local/staging')), + ]; +} + +function buildCoverage(rows, predicateResults) { + const failedPredicateIds = predicateResults.filter((predicate) => !predicate.passed).map((predicate) => predicate.id); + return { + rowCount: rows.length, + laneCount: V42_LOCAL_STAGING_MVP_REHEARSAL_LANE_IDS.length, + stageCount: V42_LOCAL_STAGING_MVP_REHEARSAL_STAGE_IDS.length, + gateArtifactCount: 6, + lanes: [...V42_LOCAL_STAGING_MVP_REHEARSAL_LANE_IDS], + stages: [...V42_LOCAL_STAGING_MVP_REHEARSAL_STAGE_IDS], + stagingProjectRef: 'tkpyosihuouusyaxtbau', + stagingRestHost: 'https://tkpyosihuouusyaxtbau.supabase.co/rest/v1/', + localLaneCovered: true, + stagingTestnetLaneCovered: true, + depositingCovered: true, + readRequestCovered: true, + readNeedReviewCovered: true, + readFitsFindingCovered: true, + manyCandidateDepositorySearchCovered: true, + sourceSafePreviewQuoteCovered: true, + settlementRightsDeliveryCovered: true, + aiReadingDemonstrationCovered: true, + richTelemetryReadbackCovered: true, + databaseStreamReadbackCovered: true, + ledgerDatabaseStorageSynchronized: true, + postSettlementPullRequestDeliveryCovered: true, + operatorReceiptScriptCovered: true, + mainnetValueBearingBlocked: true, + sourceSafeMetadataOnly: true, + protectedSourcePayloadSerialized: false, + rawProtectedPromptVisible: false, + rawInterpolatedPromptVisible: false, + rawProviderResponseVisible: false, + unpaidAssetPackSourceVisible: false, + credentialsSerialized: false, + walletPrivateMaterialVisible: false, + privateSettlementPayloadVisible: false, + liveRehearsalLogPayloadSerialized: false, + failedPredicateIds, + }; +} + +export function buildV42LocalStagingMvpRehearsal(input = {}) { + const repoRoot = input.repoRoot || DEFAULT_REPO_ROOT; + const predicateResults = buildPredicateResults(repoRoot); + const rows = [...V42_LOCAL_STAGING_MVP_REHEARSAL_ROWS]; + const coverage = buildCoverage(rows, predicateResults); + const artifactRoot = `v42-local-staging-mvp-rehearsal:${digest(JSON.stringify({ + rowIds: V42_LOCAL_STAGING_MVP_REHEARSAL_ROW_IDS, + laneIds: V42_LOCAL_STAGING_MVP_REHEARSAL_LANE_IDS, + stageIds: V42_LOCAL_STAGING_MVP_REHEARSAL_STAGE_IDS, + predicateResults, + coverage, + }))}`; + + return { + artifactId: 'v42-local-staging-mvp-rehearsal', + schemaId: V42_LOCAL_STAGING_MVP_REHEARSAL_SCHEMA_ID, + version: V42_LOCAL_STAGING_MVP_REHEARSAL_VERSION, + currentTarget: V42_LOCAL_STAGING_MVP_REHEARSAL_CURRENT_TARGET, + sourceSafetyVerdict: V42_LOCAL_STAGING_MVP_REHEARSAL_SOURCE_SAFETY_VERDICT, + laneIds: [...V42_LOCAL_STAGING_MVP_REHEARSAL_LANE_IDS], + stageIds: [...V42_LOCAL_STAGING_MVP_REHEARSAL_STAGE_IDS], + rowIds: [...V42_LOCAL_STAGING_MVP_REHEARSAL_ROW_IDS], + rows, + predicateResults, + coverage, + sourceSafety: { + sourceSafetyClass: 'source_safe_v42_local_staging_mvp_rehearsal_metadata', + sourceSafeMetadataOnly: true, + protectedSourcePayloadSerialized: false, + rawProtectedPromptVisible: false, + rawInterpolatedPromptVisible: false, + rawProviderResponseVisible: false, + unpaidAssetPackSourceVisible: false, + credentialsSerialized: false, + walletPrivateMaterialVisible: false, + privateSettlementPayloadVisible: false, + liveRehearsalLogPayloadSerialized: false, + valueBearingMainnetAdmitted: false, + forbiddenPayloadClasses: [...FORBIDDEN_PAYLOAD_CLASSES], + }, + passed: coverage.failedPredicateIds.length === 0, + artifactRoot, + }; +} diff --git a/packages/protocol/src/index.d.ts b/packages/protocol/src/index.d.ts index 1e9900b1..652372a1 100644 --- a/packages/protocol/src/index.d.ts +++ b/packages/protocol/src/index.d.ts @@ -562,6 +562,16 @@ export const V42_AI_READING_DEMONSTRATION_SOURCE_SAFETY_VERDICT: string; export const V42_AI_READING_DEMONSTRATION_ROW_IDS: readonly string[]; export const V42_AI_READING_DEMONSTRATION_ROWS: readonly Record[]; export function buildV42AiReadingDemonstration(input?: Record): BitcodeProtocolReport; +export const V42_LOCAL_STAGING_MVP_REHEARSAL_ARTIFACT_PATH: string; +export const V42_LOCAL_STAGING_MVP_REHEARSAL_CURRENT_TARGET: string; +export const V42_LOCAL_STAGING_MVP_REHEARSAL_SCHEMA_ID: string; +export const V42_LOCAL_STAGING_MVP_REHEARSAL_VERSION: string; +export const V42_LOCAL_STAGING_MVP_REHEARSAL_SOURCE_SAFETY_VERDICT: string; +export const V42_LOCAL_STAGING_MVP_REHEARSAL_LANE_IDS: readonly string[]; +export const V42_LOCAL_STAGING_MVP_REHEARSAL_STAGE_IDS: readonly string[]; +export const V42_LOCAL_STAGING_MVP_REHEARSAL_ROW_IDS: readonly string[]; +export const V42_LOCAL_STAGING_MVP_REHEARSAL_ROWS: readonly Record[]; +export function buildV42LocalStagingMvpRehearsal(input?: Record): BitcodeProtocolReport; export const EXCHANGE_INTENT_ORDER_CONTRACTS_ARTIFACT_PATH: string; export const EXCHANGE_INTENT_ORDER_CONTRACTS_CURRENT_TARGET: string; export const EXCHANGE_INTENT_ORDER_CONTRACTS_SCHEMA_ID: string; diff --git a/packages/protocol/src/index.js b/packages/protocol/src/index.js index 77478804..78667957 100644 --- a/packages/protocol/src/index.js +++ b/packages/protocol/src/index.js @@ -632,6 +632,18 @@ export { V42_AI_READING_DEMONSTRATION_VERSION, buildV42AiReadingDemonstration } from './canonical/v42-ai-reading-demonstration.js'; +export { + V42_LOCAL_STAGING_MVP_REHEARSAL_ARTIFACT_PATH, + V42_LOCAL_STAGING_MVP_REHEARSAL_CURRENT_TARGET, + V42_LOCAL_STAGING_MVP_REHEARSAL_LANE_IDS, + V42_LOCAL_STAGING_MVP_REHEARSAL_ROW_IDS, + V42_LOCAL_STAGING_MVP_REHEARSAL_ROWS, + V42_LOCAL_STAGING_MVP_REHEARSAL_SCHEMA_ID, + V42_LOCAL_STAGING_MVP_REHEARSAL_SOURCE_SAFETY_VERDICT, + V42_LOCAL_STAGING_MVP_REHEARSAL_STAGE_IDS, + V42_LOCAL_STAGING_MVP_REHEARSAL_VERSION, + buildV42LocalStagingMvpRehearsal +} from './canonical/v42-local-staging-mvp-rehearsal.js'; export { EXCHANGE_INTENT_ACTION_KINDS, EXCHANGE_INTENT_ORDER_CONTRACTS_ARTIFACT_PATH, diff --git a/packages/protocol/test/v42-local-staging-mvp-rehearsal.test.js b/packages/protocol/test/v42-local-staging-mvp-rehearsal.test.js new file mode 100644 index 00000000..e0d739dd --- /dev/null +++ b/packages/protocol/test/v42-local-staging-mvp-rehearsal.test.js @@ -0,0 +1,57 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; + +import { + V42_LOCAL_STAGING_MVP_REHEARSAL_ARTIFACT_PATH, + V42_LOCAL_STAGING_MVP_REHEARSAL_LANE_IDS, + V42_LOCAL_STAGING_MVP_REHEARSAL_ROW_IDS, + V42_LOCAL_STAGING_MVP_REHEARSAL_SCHEMA_ID, + V42_LOCAL_STAGING_MVP_REHEARSAL_STAGE_IDS, + buildV42LocalStagingMvpRehearsal, +} from '../src/canonical/v42-local-staging-mvp-rehearsal.js'; + +test('V42 local/staging MVP rehearsal artifact is source-safe and complete', () => { + const artifact = buildV42LocalStagingMvpRehearsal(); + + assert.equal(V42_LOCAL_STAGING_MVP_REHEARSAL_ARTIFACT_PATH, '.bitcode/v42-local-staging-mvp-rehearsal.json'); + assert.equal(artifact.artifactId, 'v42-local-staging-mvp-rehearsal'); + assert.equal(artifact.schemaId, V42_LOCAL_STAGING_MVP_REHEARSAL_SCHEMA_ID); + assert.equal(artifact.version, 'V42'); + assert.equal(artifact.currentTarget, 'V41'); + assert.deepEqual(artifact.laneIds, [...V42_LOCAL_STAGING_MVP_REHEARSAL_LANE_IDS]); + assert.deepEqual(artifact.stageIds, [...V42_LOCAL_STAGING_MVP_REHEARSAL_STAGE_IDS]); + assert.deepEqual(artifact.rowIds, [...V42_LOCAL_STAGING_MVP_REHEARSAL_ROW_IDS]); + assert.equal(artifact.coverage.rowCount, 14); + assert.equal(artifact.coverage.laneCount, 2); + assert.equal(artifact.coverage.stageCount, 7); + assert.equal(artifact.coverage.gateArtifactCount, 6); + assert.equal(artifact.coverage.stagingProjectRef, 'tkpyosihuouusyaxtbau'); + assert.equal(artifact.coverage.stagingRestHost, 'https://tkpyosihuouusyaxtbau.supabase.co/rest/v1/'); + assert.equal(artifact.coverage.depositingCovered, true); + assert.equal(artifact.coverage.readRequestCovered, true); + assert.equal(artifact.coverage.readNeedReviewCovered, true); + assert.equal(artifact.coverage.readFitsFindingCovered, true); + assert.equal(artifact.coverage.manyCandidateDepositorySearchCovered, true); + assert.equal(artifact.coverage.sourceSafePreviewQuoteCovered, true); + assert.equal(artifact.coverage.settlementRightsDeliveryCovered, true); + assert.equal(artifact.coverage.aiReadingDemonstrationCovered, true); + assert.equal(artifact.coverage.richTelemetryReadbackCovered, true); + assert.equal(artifact.coverage.databaseStreamReadbackCovered, true); + assert.equal(artifact.coverage.ledgerDatabaseStorageSynchronized, true); + assert.equal(artifact.coverage.postSettlementPullRequestDeliveryCovered, true); + assert.equal(artifact.coverage.operatorReceiptScriptCovered, true); + assert.equal(artifact.coverage.mainnetValueBearingBlocked, true); + assert.equal(artifact.coverage.sourceSafeMetadataOnly, true); + assert.equal(artifact.coverage.protectedSourcePayloadSerialized, false); + assert.equal(artifact.coverage.rawProtectedPromptVisible, false); + assert.equal(artifact.coverage.rawInterpolatedPromptVisible, false); + assert.equal(artifact.coverage.rawProviderResponseVisible, false); + assert.equal(artifact.coverage.unpaidAssetPackSourceVisible, false); + assert.equal(artifact.coverage.credentialsSerialized, false); + assert.equal(artifact.coverage.walletPrivateMaterialVisible, false); + assert.equal(artifact.coverage.privateSettlementPayloadVisible, false); + assert.equal(artifact.coverage.liveRehearsalLogPayloadSerialized, false); + assert.deepEqual(artifact.coverage.failedPredicateIds, []); + assert.equal(artifact.passed, true); + assert.match(artifact.artifactRoot, /^v42-local-staging-mvp-rehearsal:/u); +}); diff --git a/scripts/check-v42-gate8-local-staging-mvp-rehearsal.mjs b/scripts/check-v42-gate8-local-staging-mvp-rehearsal.mjs new file mode 100644 index 00000000..f8a0b479 --- /dev/null +++ b/scripts/check-v42-gate8-local-staging-mvp-rehearsal.mjs @@ -0,0 +1,281 @@ +#!/usr/bin/env node + +import { execFileSync } from 'node:child_process'; +import { existsSync, readFileSync } from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const defaultRepoRoot = path.resolve(__dirname, '..'); +const ARTIFACT_PATH = '.bitcode/v42-local-staging-mvp-rehearsal.json'; + +const SECRET_MARKERS = [ + `${['sk', 'proj'].join('-')}-`, + `${['sb', 'secret'].join('_')}__`, + String.fromCharCode(101, 121, 74, 104, 98, 71, 99, 105, 79, 105, 74, 73, 85, 122, 73, 49, 78, 105), + ['OPENAI', 'API', 'KEY'].join('_'), + ['SUPABASE', 'SERVICE', 'ROLE'].join('_'), + ['VERCEL', 'TOKEN'].join('_'), + ['VERCEL', 'OIDC', 'TOKEN'].join('_'), + ['PRIVATE', 'KEY'].join('_'), +]; + +function parseArgs(argv) { + const args = { + repoRoot: defaultRepoRoot, + skipBranchCheck: false, + skipPackageTests: false, + skipUapiTests: false, + help: false, + }; + + for (let index = 0; index < argv.length; index += 1) { + const arg = argv[index]; + if (arg === '--repo-root') args.repoRoot = path.resolve(argv[++index]); + else if (arg === '--skip-branch-check') args.skipBranchCheck = true; + else if (arg === '--skip-package-tests') args.skipPackageTests = true; + else if (arg === '--skip-uapi-tests') args.skipUapiTests = true; + else if (arg === '--help' || arg === '-h') args.help = true; + else throw new Error(`Unknown argument ${arg}`); + } + + return args; +} + +function read(root, relativePath) { + return readFileSync(path.join(root, relativePath), 'utf8'); +} + +function fileExists(root, relativePath) { + return existsSync(path.join(root, relativePath)); +} + +function git(root, args) { + return execFileSync('git', args, { cwd: root, encoding: 'utf8' }).trim(); +} + +function run(root, command, args, options = {}) { + return execFileSync(command, args, { + cwd: root, + encoding: 'utf8', + stdio: ['ignore', 'pipe', 'pipe'], + ...options, + }).trim(); +} + +function commandExists(root, command) { + try { + execFileSync('sh', ['-lc', `command -v ${command}`], { + cwd: root, + encoding: 'utf8', + stdio: ['ignore', 'pipe', 'ignore'], + }); + return true; + } catch { + return false; + } +} + +function assertCheck(failures, condition, message) { + if (!condition) failures.push(message); +} + +function printHelp() { + process.stdout.write( + [ + 'Usage: node scripts/check-v42-gate8-local-staging-mvp-rehearsal.mjs [--skip-branch-check] [--skip-package-tests] [--skip-uapi-tests] [--repo-root ]', + '', + 'Checks V42 Gate 8 local/staging-testnet full MVP rehearsal artifact, source-safe operator receipts, package tests, docs, and workflow wiring.', + ].join('\n'), + ); + process.stdout.write('\n'); +} + +function parseJson(output, failures, label) { + try { + return JSON.parse(output); + } catch (error) { + failures.push(`${label} did not emit JSON: ${error.message}`); + return null; + } +} + +function runFocusedTests(root, failures, args) { + const commands = [ + ['node', ['--test', '--test-force-exit', 'packages/protocol/test/v42-local-staging-mvp-rehearsal.test.js']], + ]; + + if (!args.skipPackageTests && commandExists(root, 'pnpm')) { + commands.push( + ['pnpm', ['--filter', '@bitcode/pipeline-asset-pack', 'exec', 'jest', '--config', 'jest.config.cjs', '--runTestsByPath', 'src/__tests__/reading-local-staging-rehearsal.test.ts', '--runInBand', '--forceExit']], + ); + } + + if (!args.skipUapiTests && commandExists(root, 'pnpm')) { + commands.push( + ['pnpm', ['--dir', 'uapi', 'exec', 'jest', '--runTestsByPath', 'tests/api/pipelineHarnessPreflight.test.ts', 'tests/api/pipelineHarnessRoute.test.ts', '--runInBand']], + ); + } + + for (const [command, commandArgs] of commands) { + try { + run(root, command, commandArgs); + } catch (error) { + failures.push(`Gate 8 focused test failed for ${command} ${commandArgs.join(' ')}: ${error.stderr || error.message}`); + return; + } + } +} + +function main() { + const args = parseArgs(process.argv.slice(2)); + if (args.help) { + printHelp(); + return; + } + + const root = args.repoRoot; + const failures = []; + const pointer = read(root, 'BITCODE_SPEC.txt').trim(); + + assertCheck( + failures, + pointer === 'V41', + `BITCODE_SPEC.txt must remain V41 during V42 gate work. Observed ${pointer || 'empty'}.`, + ); + + if (!args.skipBranchCheck) { + const branch = git(root, ['branch', '--show-current']); + assertCheck( + failures, + branch === 'version/v42' || /^v42\/gate-(?:8|9)-[a-z0-9][a-z0-9-]*$/u.test(branch), + `V42 Gate 8+ work must occur on version/v42 or v42/gate-8..9-* branches. Observed ${branch || 'detached HEAD'}.`, + ); + } + + const requiredFiles = [ + ARTIFACT_PATH, + 'scripts/rehearse-v42-local-staging-mvp.mjs', + 'scripts/generate-v42-local-staging-mvp-rehearsal.mjs', + 'scripts/check-v42-gate8-local-staging-mvp-rehearsal.mjs', + 'packages/protocol/src/canonical/v42-local-staging-mvp-rehearsal.js', + 'packages/protocol/test/v42-local-staging-mvp-rehearsal.test.js', + 'packages/pipelines/asset-pack/src/reading-local-staging-rehearsal.ts', + 'packages/pipelines/asset-pack/src/__tests__/reading-local-staging-rehearsal.test.ts', + 'uapi/app/api/pipeline-harness/asset-pack/preflight.ts', + 'uapi/app/api/pipeline-harness/asset-pack/runner.ts', + 'uapi/components/base/bitcode/execution/pipeline-execution-log.tsx', + 'BITCODE_SPEC_V42.md', + 'BITCODE_SPEC_V42_DELTA.md', + 'BITCODE_SPEC_V42_NOTES.md', + 'BITCODE_SPEC_V42_PARITY_MATRIX.md', + 'SPECIFICATIONS_ROADMAP.md', + 'README.md', + 'packages/protocol/README.md', + 'packages/pipelines/asset-pack/README.md', + 'uapi/app/terminal/README.md', + 'package.json', + '.github/workflows/bitcode-gate-quality.yml', + '.github/workflows/bitcode-canon-quality.yml', + ]; + + for (const relativePath of requiredFiles) { + assertCheck(failures, fileExists(root, relativePath), `Missing V42 Gate 8 file: ${relativePath}`); + } + + if (failures.length === 0) { + try { + run(root, 'node', ['scripts/generate-v42-local-staging-mvp-rehearsal.mjs', '--check']); + } catch (error) { + failures.push(`V42 local/staging MVP rehearsal artifact check failed: ${error.stderr || error.message}`); + } + } + + let localReceipt = null; + let stagingReceipt = null; + if (failures.length === 0) { + const dryRunEnv = { + ...process.env, + OPENAI_API_KEY: `${['sk', 'proj'].join('-')}-dummy-do-not-serialize-000000000000`, + VERCEL_OIDC_TOKEN: 'oidc_dummy_do_not_serialize', + BITCODE_RUN_VERCEL_SANDBOX_HARNESS: '1', + BITCODE_ENABLE_PIPELINE_HARNESS_API: '1', + BITCODE_ASSET_PACK_REAL_INFERENCE: '1', + BITCODE_PIPELINE_STREAM_TO_DATABASE: '1', + SUPABASE_URL: 'https://tkpyosihuouusyaxtbau.supabase.co/rest/v1/', + SUPABASE_ANON_KEY: 'anon_dummy_do_not_serialize', + SUPABASE_SECRET_KEY: 'admin_dummy_do_not_serialize', + }; + const localOutput = run(root, 'node', ['scripts/rehearse-v42-local-staging-mvp.mjs', '--lane', 'local', '--dry-run', '--json'], { env: dryRunEnv }); + const stagingOutput = run(root, 'node', ['scripts/rehearse-v42-local-staging-mvp.mjs', '--lane', 'staging-testnet', '--dry-run', '--json'], { env: dryRunEnv }); + localReceipt = parseJson(localOutput, failures, 'local V42 rehearsal dry run'); + stagingReceipt = parseJson(stagingOutput, failures, 'staging-testnet V42 rehearsal dry run'); + + for (const marker of ['dummy-do-not-serialize', dryRunEnv.OPENAI_API_KEY, dryRunEnv.SUPABASE_SECRET_KEY, dryRunEnv.VERCEL_OIDC_TOKEN]) { + assertCheck(failures, !localOutput.includes(marker), `Local dry-run receipt must not serialize secret value ${marker}.`); + assertCheck(failures, !stagingOutput.includes(marker), `Staging dry-run receipt must not serialize secret value ${marker}.`); + } + } + + if (failures.length === 0) { + runFocusedTests(root, failures, args); + } + + const serializedArtifact = fileExists(root, ARTIFACT_PATH) ? read(root, ARTIFACT_PATH) : ''; + for (const marker of SECRET_MARKERS) { + assertCheck(failures, !serializedArtifact.includes(marker), `V42 Gate 8 artifact must not contain secret marker ${marker}.`); + } + + const artifact = serializedArtifact ? JSON.parse(serializedArtifact) : null; + if (artifact) { + assertCheck(failures, artifact.artifactId === 'v42-local-staging-mvp-rehearsal', 'Gate 8 artifactId must match.'); + assertCheck(failures, artifact.schemaId === 'bitcode.v42.localStagingMvpRehearsal.v1', 'Gate 8 schemaId must match.'); + assertCheck(failures, artifact.version === 'V42' && artifact.currentTarget === 'V41', 'Gate 8 artifact must bind V42 over active V41.'); + assertCheck(failures, artifact.passed === true, 'Gate 8 artifact must pass.'); + assertCheck(failures, artifact.coverage.rowCount === 14, 'Gate 8 must cover fourteen rehearsal rows.'); + assertCheck(failures, artifact.coverage.laneCount === 2, 'Gate 8 must cover local and staging-testnet lanes.'); + assertCheck(failures, artifact.coverage.stageCount === 7, 'Gate 8 must cover the complete MVP stage path.'); + assertCheck(failures, artifact.coverage.gateArtifactCount === 6, 'Gate 8 must bind Gates 2 through 7 artifacts.'); + assertCheck(failures, artifact.coverage.stagingProjectRef === 'tkpyosihuouusyaxtbau', 'Gate 8 must bind staging-testnet Supabase project.'); + assertCheck(failures, artifact.coverage.depositingCovered === true, 'Gate 8 must cover Depositing.'); + assertCheck(failures, artifact.coverage.readNeedReviewCovered === true, 'Gate 8 must cover ReadNeed review.'); + assertCheck(failures, artifact.coverage.readFitsFindingCovered === true, 'Gate 8 must cover Finding Fits.'); + assertCheck(failures, artifact.coverage.settlementRightsDeliveryCovered === true, 'Gate 8 must cover settlement rights and delivery.'); + assertCheck(failures, artifact.coverage.aiReadingDemonstrationCovered === true, 'Gate 8 must cover AI-reading demonstration proof.'); + assertCheck(failures, artifact.coverage.richTelemetryReadbackCovered === true, 'Gate 8 must cover rich telemetry readback.'); + assertCheck(failures, artifact.coverage.mainnetValueBearingBlocked === true, 'Gate 8 must block value-bearing mainnet.'); + assertCheck(failures, artifact.coverage.sourceSafeMetadataOnly === true, 'Gate 8 artifact must be source-safe metadata only.'); + assertCheck(failures, artifact.coverage.protectedSourcePayloadSerialized === false, 'Gate 8 artifact must not serialize protected source.'); + assertCheck(failures, artifact.coverage.unpaidAssetPackSourceVisible === false, 'Gate 8 artifact must not expose unpaid AssetPack source.'); + assertCheck(failures, artifact.coverage.credentialsSerialized === false, 'Gate 8 artifact must not serialize credentials.'); + assertCheck(failures, Array.isArray(artifact.coverage.failedPredicateIds) && artifact.coverage.failedPredicateIds.length === 0, 'Gate 8 predicates must all pass.'); + assertCheck(failures, artifact.sourceSafety.liveRehearsalLogPayloadSerialized === false, 'Gate 8 artifact must not serialize live rehearsal logs.'); + } + + if (localReceipt) { + assertCheck(failures, localReceipt.laneId === 'local', 'Local dry-run receipt must identify local lane.'); + assertCheck(failures, localReceipt.ready === true, 'Local dry-run receipt should be ready under dummy source-safe env.'); + assertCheck(failures, localReceipt.currentTarget === 'V41', 'Local dry-run receipt must bind V42 over active V41.'); + assertCheck(failures, localReceipt.sourceSafety.secretValueSerialized === false, 'Local receipt must not serialize secret values.'); + assertCheck(failures, localReceipt.sourceSafety.valueBearingMainnetAdmitted === false, 'Local receipt must block value-bearing mainnet.'); + } + if (stagingReceipt) { + assertCheck(failures, stagingReceipt.laneId === 'staging-testnet', 'Staging dry-run receipt must identify staging-testnet lane.'); + assertCheck(failures, stagingReceipt.ready === true, 'Staging dry-run receipt should be ready under dummy source-safe env.'); + assertCheck(failures, stagingReceipt.stagingProjectRef === 'tkpyosihuouusyaxtbau', 'Staging receipt must bind staging-testnet project ref.'); + assertCheck(failures, stagingReceipt.stagingRestHost === 'https://tkpyosihuouusyaxtbau.supabase.co/rest/v1/', 'Staging receipt must bind staging-testnet REST host.'); + assertCheck(failures, stagingReceipt.sourceSafety.secretValueSerialized === false, 'Staging receipt must not serialize secret values.'); + assertCheck(failures, stagingReceipt.sourceSafety.valueBearingMainnetAdmitted === false, 'Staging receipt must block value-bearing mainnet.'); + } + + if (failures.length > 0) { + process.stderr.write(`V42 Gate 8 local/staging MVP rehearsal check failed:\n- ${failures.join('\n- ')}\n`); + process.exitCode = 1; + return; + } + + process.stdout.write(`V42 Gate 8 local/staging MVP rehearsal ok artifact=${artifact.artifactRoot}\n`); +} + +main(); diff --git a/scripts/generate-v42-local-staging-mvp-rehearsal.mjs b/scripts/generate-v42-local-staging-mvp-rehearsal.mjs new file mode 100644 index 00000000..028ffffd --- /dev/null +++ b/scripts/generate-v42-local-staging-mvp-rehearsal.mjs @@ -0,0 +1,61 @@ +#!/usr/bin/env node + +import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { + V42_LOCAL_STAGING_MVP_REHEARSAL_ARTIFACT_PATH, + buildV42LocalStagingMvpRehearsal, +} from '../packages/protocol/src/canonical/v42-local-staging-mvp-rehearsal.js'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const defaultRepoRoot = path.resolve(__dirname, '..'); + +function parseArgs(argv) { + const args = { + repoRoot: defaultRepoRoot, + check: false, + }; + for (let index = 0; index < argv.length; index += 1) { + const arg = argv[index]; + if (arg === '--repo-root') args.repoRoot = path.resolve(argv[++index]); + else if (arg === '--check') args.check = true; + else if (arg === '--help' || arg === '-h') { + process.stdout.write( + 'Usage: node scripts/generate-v42-local-staging-mvp-rehearsal.mjs [--check] [--repo-root ]\n', + ); + process.exit(0); + } else { + throw new Error(`Unknown argument ${arg}`); + } + } + return args; +} + +const args = parseArgs(process.argv.slice(2)); +const artifact = buildV42LocalStagingMvpRehearsal({ repoRoot: args.repoRoot }); +const artifactPath = path.join(args.repoRoot, V42_LOCAL_STAGING_MVP_REHEARSAL_ARTIFACT_PATH); +const serialized = `${JSON.stringify(artifact, null, 2)}\n`; + +if (args.check) { + if (!existsSync(artifactPath)) { + process.stderr.write(`Missing ${V42_LOCAL_STAGING_MVP_REHEARSAL_ARTIFACT_PATH}\n`); + process.exit(1); + } + const current = readFileSync(artifactPath, 'utf8'); + if (current !== serialized) { + process.stderr.write(`${V42_LOCAL_STAGING_MVP_REHEARSAL_ARTIFACT_PATH} is stale. Run pnpm run generate:v42-local-staging-mvp-rehearsal.\n`); + process.exit(1); + } + if (!artifact.passed) { + process.stderr.write(`V42 local/staging MVP rehearsal artifact predicates failed: ${artifact.coverage.failedPredicateIds.join(', ')}\n`); + process.exit(1); + } + process.stdout.write(`V42 local/staging MVP rehearsal artifact ok ${artifact.artifactRoot}\n`); + process.exit(0); +} + +mkdirSync(path.dirname(artifactPath), { recursive: true }); +writeFileSync(artifactPath, serialized); +process.stdout.write(`Wrote ${V42_LOCAL_STAGING_MVP_REHEARSAL_ARTIFACT_PATH} ${artifact.artifactRoot}\n`); diff --git a/scripts/rehearse-v42-local-staging-mvp.mjs b/scripts/rehearse-v42-local-staging-mvp.mjs new file mode 100644 index 00000000..2516246b --- /dev/null +++ b/scripts/rehearse-v42-local-staging-mvp.mjs @@ -0,0 +1,325 @@ +#!/usr/bin/env node + +import { spawnSync } from 'node:child_process'; +import { createHash } from 'node:crypto'; +import { mkdirSync, writeFileSync } from 'node:fs'; +import path from 'node:path'; + +export const V42_REHEARSAL_LANES = ['local', 'staging-testnet']; + +const DEFAULT_RECEIPT_DIR = '.bitcode/pipeline-harness-runs/v42-mvp-rehearsal-receipts'; +const STAGING_PROJECT_REF = 'tkpyosihuouusyaxtbau'; +const STAGING_REST_HOST = 'https://tkpyosihuouusyaxtbau.supabase.co/rest/v1/'; + +const SOURCE_SAFETY = Object.freeze({ + sourceSafeMetadataOnly: true, + protectedSourcePayloadSerialized: false, + rawProtectedPromptVisible: false, + rawInterpolatedPromptVisible: false, + rawProviderResponseVisible: false, + unpaidAssetPackSourceVisible: false, + credentialsSerialized: false, + walletPrivateMaterialVisible: false, + privateSettlementPayloadVisible: false, + liveRehearsalLogPayloadSerialized: false, + valueBearingMainnetAdmitted: false, + secretValueSerialized: false, +}); + +const ENVIRONMENT_FAMILIES = Object.freeze({ + sandboxAuth: { + familyId: 'sandbox-auth', + required: true, + acceptedKeyNames: ['VERCEL_OIDC_TOKEN', 'VERCEL_TOKEN'], + posture: 'vercel-oidc-preferred-access-token-fallback', + }, + sandboxOptIn: { + familyId: 'sandbox-live-opt-in', + required: true, + acceptedKeyNames: ['BITCODE_RUN_VERCEL_SANDBOX_HARNESS'], + requiredLiteralValue: '1', + posture: 'explicit-live-sandbox-opt-in', + }, + harnessApi: { + familyId: 'pipeline-harness-api-enabled', + required: true, + acceptedKeyNames: ['BITCODE_ENABLE_PIPELINE_HARNESS_API'], + requiredLiteralValue: '1', + posture: 'local-and-staging-harness-api-enabled', + }, + llmProvider: { + familyId: 'llm-provider-key', + required: true, + acceptedKeyNames: ['OPENAI_API_KEY'], + posture: 'real-inference-provider-credential', + }, + supabaseUrl: { + familyId: 'supabase-rest-url', + required: true, + acceptedKeyNames: ['SUPABASE_URL', 'NEXT_PUBLIC_SUPABASE_URL'], + requiredHost: `${STAGING_PROJECT_REF}.supabase.co`, + posture: 'staging-testnet-rest-host-bound', + }, + supabasePublic: { + familyId: 'supabase-public-key', + required: true, + acceptedKeyNames: [ + 'SUPABASE_ANON_KEY', + 'SUPABASE_PUBLISHABLE_KEY', + 'NEXT_PUBLIC_SUPABASE_ANON_KEY', + 'NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY', + ], + posture: 'staging-testnet-public-readback-key', + }, + supabaseAdmin: { + familyId: 'supabase-admin-key', + required: true, + acceptedKeyNames: ['SUPABASE_SECRET_KEY', 'SUPABASE_ADMIN_KEY', 'SUPABASE_SERVICE_ROLE_KEY'], + posture: 'staging-testnet-admin-readback-key', + }, + databaseStreaming: { + familyId: 'pipeline-database-streaming', + required: true, + acceptedKeyNames: ['BITCODE_PIPELINE_STREAM_TO_DATABASE'], + requiredLiteralValue: '1', + posture: 'pipeline-events-persist-to-staging-database', + }, + realInference: { + familyId: 'assetpack-real-inference', + required: true, + acceptedKeyNames: ['BITCODE_ASSET_PACK_REAL_INFERENCE'], + requiredLiteralValue: '1', + posture: 'staging-testnet-real-inference-required', + }, +}); + +const LANE_REQUIREMENTS = Object.freeze({ + local: [ + ENVIRONMENT_FAMILIES.sandboxAuth, + ENVIRONMENT_FAMILIES.sandboxOptIn, + ENVIRONMENT_FAMILIES.harnessApi, + ], + 'staging-testnet': [ + ENVIRONMENT_FAMILIES.sandboxAuth, + ENVIRONMENT_FAMILIES.sandboxOptIn, + ENVIRONMENT_FAMILIES.harnessApi, + ENVIRONMENT_FAMILIES.llmProvider, + ENVIRONMENT_FAMILIES.supabaseUrl, + ENVIRONMENT_FAMILIES.supabasePublic, + ENVIRONMENT_FAMILIES.supabaseAdmin, + ENVIRONMENT_FAMILIES.databaseStreaming, + ENVIRONMENT_FAMILIES.realInference, + ], +}); + +function stableStringify(value) { + if (typeof value === 'undefined') return 'null'; + if (value === null || typeof value !== 'object') return JSON.stringify(value); + if (Array.isArray(value)) return `[${value.map((entry) => stableStringify(entry)).join(',')}]`; + return `{${Object.keys(value) + .sort() + .map((key) => `${JSON.stringify(key)}:${stableStringify(value[key])}`) + .join(',')}}`; +} + +function rootOf(value) { + return `sha256:${createHash('sha256').update(stableStringify(value)).digest('hex')}`; +} + +function parseArgs(argv) { + const args = { + lane: 'local', + dryRun: true, + execute: false, + json: false, + writeReceipt: false, + includeEnvKeyNames: false, + receiptDir: DEFAULT_RECEIPT_DIR, + }; + + for (let index = 0; index < argv.length; index += 1) { + const arg = argv[index]; + if (arg === '--lane') args.lane = argv[++index]; + else if (arg === '--dry-run') args.dryRun = true; + else if (arg === '--execute') { + args.execute = true; + args.dryRun = false; + } else if (arg === '--json') args.json = true; + else if (arg === '--write-receipt') args.writeReceipt = true; + else if (arg === '--include-env-key-names') args.includeEnvKeyNames = true; + else if (arg === '--receipt-dir') args.receiptDir = argv[++index]; + else if (arg === '--help' || arg === '-h') args.help = true; + else throw new Error(`Unknown argument ${arg}`); + } + + if (!V42_REHEARSAL_LANES.includes(args.lane)) { + throw new Error(`Unsupported V42 rehearsal lane ${args.lane}. Expected one of ${V42_REHEARSAL_LANES.join(', ')}.`); + } + + return args; +} + +function printHelp() { + process.stdout.write( + [ + 'Usage: node scripts/rehearse-v42-local-staging-mvp.mjs --lane [--dry-run|--execute] [--json] [--write-receipt]', + '', + 'Builds a source-safe operator receipt for the V42 local/staging-testnet full MVP rehearsal lane.', + 'Live execution requires BITCODE_V42_REHEARSAL_EXECUTE=1 and delegates to the Vercel Sandbox AssetPack harness.', + ].join('\n'), + ); + process.stdout.write('\n'); +} + +function hostFromUrl(value) { + if (!value) return null; + try { + return new URL(value).hostname; + } catch { + return null; + } +} + +function readEnvironmentFamily(family, env, includeEnvKeyNames) { + const observed = family.acceptedKeyNames + .map((keyName) => ({ + keyName, + present: typeof env[keyName] === 'string' && env[keyName].length > 0, + literalMatches: family.requiredLiteralValue ? env[keyName] === family.requiredLiteralValue : true, + hostMatches: family.requiredHost ? hostFromUrl(env[keyName]) === family.requiredHost : true, + })) + .filter((entry) => entry.present); + + const satisfied = observed.some((entry) => entry.literalMatches && entry.hostMatches); + return { + familyId: family.familyId, + required: family.required, + posture: family.posture, + present: observed.length > 0, + satisfied, + ...(family.requiredHost ? { requiredHost: family.requiredHost } : {}), + ...(family.requiredLiteralValue ? { requiredLiteralValuePresent: satisfied } : {}), + ...(includeEnvKeyNames + ? { acceptedKeyNames: family.acceptedKeyNames, observedKeyNames: observed.map((entry) => entry.keyName) } + : {}), + secretValueSerialized: false, + }; +} + +function buildReceipt(args, env = process.env) { + const families = LANE_REQUIREMENTS[args.lane].map((family) => + readEnvironmentFamily(family, env, args.includeEnvKeyNames), + ); + const missingEnvironmentFamilies = families + .filter((family) => family.required && !family.satisfied) + .map((family) => family.familyId); + const command = { + commandId: 'pipeline-hosts:qa-asset-pack-sandbox', + cwd: 'packages/pipeline-hosts', + argv: ['pnpm', '--filter', '@bitcode/pipeline-hosts', 'run', 'qa:asset-pack:sandbox'], + dryRun: args.dryRun, + liveExecutionOptInRequired: true, + liveExecutionOptInSatisfied: env.BITCODE_V42_REHEARSAL_EXECUTE === '1', + }; + const withoutRoot = { + schema: 'bitcode.v42.localStagingMvpRehearsal.operatorReceipt', + version: 'V42', + currentTarget: 'V41', + laneId: args.lane, + laneClass: args.lane === 'staging-testnet' ? 'staging-testnet-real-inference-full-mvp' : 'local-full-mvp-rehearsal', + stagingProjectRef: args.lane === 'staging-testnet' ? STAGING_PROJECT_REF : null, + stagingRestHost: args.lane === 'staging-testnet' ? STAGING_REST_HOST : null, + generatedAt: 'operator-runtime', + ready: missingEnvironmentFamilies.length === 0, + dryRun: args.dryRun, + stages: [ + 'deposit-source', + 'request-read', + 'review-synthesized-need', + 'request-finding-fits', + 'review-assetpack-preview', + 'buy-assetpack-settle', + 'receive-repository-delivery', + ], + command, + environmentFamilies: families, + missingEnvironmentFamilies, + receiptArtifactRoot: DEFAULT_RECEIPT_DIR, + sourceSafety: SOURCE_SAFETY, + }; + + return { + ...withoutRoot, + receiptRoot: rootOf(withoutRoot), + }; +} + +function writeReceipt(receipt, receiptDir) { + mkdirSync(receiptDir, { recursive: true }); + const filename = `${receipt.version.toLowerCase()}-${receipt.laneId}-operator-receipt.json`; + const receiptPath = path.resolve(receiptDir, filename); + writeFileSync(receiptPath, `${JSON.stringify(receipt, null, 2)}\n`); + return receiptPath; +} + +function runLiveHarness(receipt) { + if (!receipt.ready) { + throw new Error(`Cannot execute V42 rehearsal; missing families: ${receipt.missingEnvironmentFamilies.join(', ')}`); + } + if (!receipt.command.liveExecutionOptInSatisfied) { + throw new Error('Set BITCODE_V42_REHEARSAL_EXECUTE=1 before live rehearsal execution.'); + } + + return spawnSync('pnpm', ['--filter', '@bitcode/pipeline-hosts', 'run', 'qa:asset-pack:sandbox'], { + stdio: 'inherit', + env: { + ...process.env, + BITCODE_SANDBOX_MODE: process.env.BITCODE_SANDBOX_MODE || 'asset_pack_pipeline', + BITCODE_PIPELINE_STREAM_TO_DATABASE: + receipt.laneId === 'staging-testnet' + ? '1' + : process.env.BITCODE_PIPELINE_STREAM_TO_DATABASE || '0', + BITCODE_ENABLE_PIPELINE_HARNESS_API: process.env.BITCODE_ENABLE_PIPELINE_HARNESS_API || '1', + }, + }); +} + +function main() { + const args = parseArgs(process.argv.slice(2)); + if (args.help) { + printHelp(); + return; + } + + const receipt = buildReceipt(args); + let receiptPath = null; + if (args.writeReceipt) { + receiptPath = writeReceipt(receipt, args.receiptDir); + } + + if (args.execute) { + const result = runLiveHarness(receipt); + if (result.status !== 0) process.exit(result.status || 1); + } + + if (args.json) { + process.stdout.write(`${JSON.stringify(receipt, null, 2)}\n`); + return; + } + + process.stdout.write( + [ + `V42 ${receipt.laneId} full MVP rehearsal receipt ${receipt.receiptRoot}`, + `ready=${receipt.ready}`, + receiptPath ? `receipt=${receiptPath}` : null, + receipt.missingEnvironmentFamilies.length + ? `missing=${receipt.missingEnvironmentFamilies.join(',')}` + : 'missing=none', + ] + .filter(Boolean) + .join(' '), + ); + process.stdout.write('\n'); +} + +main(); diff --git a/uapi/app/api/pipeline-harness/asset-pack/preflight.ts b/uapi/app/api/pipeline-harness/asset-pack/preflight.ts index 89b148f5..f5853315 100644 --- a/uapi/app/api/pipeline-harness/asset-pack/preflight.ts +++ b/uapi/app/api/pipeline-harness/asset-pack/preflight.ts @@ -8,6 +8,9 @@ export type PipelineHarnessPreflightBody = { type PipelineHarnessRuntimeEnv = Record; +const STAGING_TESTNET_SUPABASE_PROJECT_REF = 'tkpyosihuouusyaxtbau'; +const STAGING_TESTNET_SUPABASE_REST_HOST = `${STAGING_TESTNET_SUPABASE_PROJECT_REF}.supabase.co`; + const SUPABASE_ADMIN_CREDENTIAL_KEYS = [ 'SUPABASE_SECRET_KEY', 'SUPABASE_ADMIN_KEY', @@ -214,6 +217,9 @@ export function summarizeHarnessPreflight( supabaseUrlProvided: isUsableSupabaseUrl(supabaseUrl), supabaseHost, supabaseDbHost, + stagingTestnetProjectRef: STAGING_TESTNET_SUPABASE_PROJECT_REF, + stagingTestnetSupabaseHostMatched: + normalizeSupabaseHost(supabaseHost) === STAGING_TESTNET_SUPABASE_REST_HOST, supabaseRestDbHostAligned: !normalizedSupabaseHost || !normalizedSupabaseDbHost || diff --git a/uapi/app/terminal/README.md b/uapi/app/terminal/README.md index 7c0ea178..20c75c41 100644 --- a/uapi/app/terminal/README.md +++ b/uapi/app/terminal/README.md @@ -148,6 +148,19 @@ credentials, raw protected prompts, or raw provider responses. The source-safe proof artifact is `.bitcode/v42-settlement-rights-delivery.json`, checked by `pnpm run check:v42-gate6`. +V42 Gate 8 closes local/staging full MVP rehearsal readback for Terminal. +The route remains `/terminal` during V42, but the proof now binds the whole +MVP chain: deposit source, request read, review synthesized Need, request +Finding Fits, review source-safe AssetPack preview and quote, buy/settle, +receive repository delivery, and inspect rich stream telemetry/database +readback. The source-safe proof artifact is +`.bitcode/v42-local-staging-mvp-rehearsal.json`, checked by +`pnpm run check:v42-gate8`. Generated rehearsal data may carry lane ids, +stage ids, roots, staging-testnet project `tkpyosihuouusyaxtbau`, and repair +posture; it must not carry protected source, unpaid AssetPack source, raw +prompts, provider responses, credentials, wallet private material, private +settlement payloads, or live logs. + ## Live staging-testnet QA Terminal Deposit/Read QA starts only after Wallet and Externals prerequisites are diff --git a/uapi/app/terminal/TerminalDepositReadWorkbench.tsx b/uapi/app/terminal/TerminalDepositReadWorkbench.tsx index 3ab4a2f7..8e65ae43 100644 --- a/uapi/app/terminal/TerminalDepositReadWorkbench.tsx +++ b/uapi/app/terminal/TerminalDepositReadWorkbench.tsx @@ -358,6 +358,10 @@ export default function TerminalDepositReadWorkbench({ objectValue(assetPackSettlementRightsDeliveryBoundary?.reconciliationReport) || objectValue(completedHarnessEvidence?.assetPackLedgerDatabaseStorageReconciliation); const assetPackSettlementProofRoots = objectValue(assetPackSettlementRightsDeliveryBoundary?.proofRoots); + const readingLocalStagingRehearsal = objectValue(completedHarnessEvidence?.readingLocalStagingRehearsal); + const readingLocalStagingCoverage = objectValue(readingLocalStagingRehearsal?.coverage); + const readingLocalStagingProofRoots = objectValue(readingLocalStagingRehearsal?.proofRoots); + const readingLocalStagingStageReadback = objectValue(readingLocalStagingRehearsal?.stageReadback); const previewFeeQuote = assetPackQuoteReceipt || objectValue(sourceSafePreview?.feeQuote); @@ -638,6 +642,64 @@ export default function TerminalDepositReadWorkbench({ assetPackSettlementRightsDeliveryBoundary, ], ); + const readingLocalStagingRehearsalRows = useMemo( + () => [ + { + label: 'Rehearsal', + value: shortIdentifier(readingLocalStagingRehearsal?.rehearsalId) || 'pending', + }, + { + label: 'Run', + value: shortIdentifier(readingLocalStagingRehearsal?.runId) || textValue(readingLocalStagingRehearsal?.runId) || 'pending', + }, + { + label: 'Lanes', + value: stringList(readingLocalStagingRehearsal?.lanes).join(', ') || 'pending', + }, + { + label: 'Stages complete', + value: `${Object.values(readingLocalStagingStageReadback || {}).filter((status) => status === 'completed').length}/${String(countList(readingLocalStagingRehearsal?.stageIds) || 0)}`, + }, + { + label: 'Staging', + value: textValue(readingLocalStagingCoverage?.stagingProjectRef) || 'pending', + }, + { + label: 'Many fits', + value: readingLocalStagingCoverage?.depositoryManyFitsCovered === true ? 'covered' : 'pending', + }, + { + label: 'Telemetry', + value: readingLocalStagingCoverage?.telemetryStreamingReadbackCovered === true ? 'readback covered' : 'pending', + }, + { + label: 'Sync', + value: readingLocalStagingCoverage?.ledgerDatabaseStorageSynchronized === true ? 'aligned' : 'pending', + }, + { + label: 'Delivery', + value: readingLocalStagingCoverage?.postSettlementPullRequestDeliveryCovered === true ? 'post-settlement PR' : 'pending', + }, + { + label: 'Mainnet', + value: readingLocalStagingCoverage?.valueBearingMainnetAdmitted === false ? 'blocked' : 'pending', + }, + { + label: 'Root', + value: shortIdentifier(readingLocalStagingProofRoots?.rehearsalRoot) || 'pending', + }, + { + label: 'Rows', + value: String(countList(readingLocalStagingRehearsal?.rows) || 'pending'), + }, + ], + [ + readingLocalStagingCoverage, + readingLocalStagingProofRoots?.rehearsalRoot, + readingLocalStagingRehearsal, + readingLocalStagingStageReadback, + ], + ); const readNeedRows = useMemo(() => { if (!currentReadNeed) return []; return [ @@ -1229,6 +1291,19 @@ export default function TerminalDepositReadWorkbench({ ))} +
+ + Local/staging MVP rehearsal + +
+ {readingLocalStagingRehearsalRows.map((row) => ( +
+
{row.label}
+
{row.value}
+
+ ))} +
+