gate-evm-tools 1.0.27 → 1.0.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -1
- package/bin/cli.js +3 -0
- package/bin/delivery.cjs +51 -0
- package/bin/manifest-bootstrap.js +4 -15
- package/bin/workflow.cjs +1 -1
- package/dist/commands/plan/file-store.d.ts.map +1 -0
- package/dist/commands/plan/generate-deployment.d.ts +48 -0
- package/dist/commands/plan/generate-deployment.d.ts.map +1 -0
- package/dist/commands/plan/generate-deployment.js +211 -0
- package/dist/commands/plan/generate-deployment.js.map +1 -0
- package/dist/commands/plan/helpers.d.ts.map +1 -0
- package/dist/commands/plan/index.d.ts +3 -0
- package/dist/commands/plan/index.d.ts.map +1 -0
- package/dist/commands/plan/index.js +88 -0
- package/dist/commands/plan/index.js.map +1 -0
- package/dist/commands/sync.js +1 -1
- package/dist/commands/sync.js.map +1 -1
- package/dist/core/BytecodeChecker.d.ts.map +1 -1
- package/dist/core/BytecodeChecker.js +27 -8
- package/dist/core/BytecodeChecker.js.map +1 -1
- package/dist/core/preparation/artifacts.d.ts +2 -0
- package/dist/core/preparation/artifacts.d.ts.map +1 -1
- package/dist/core/preparation/artifacts.js +9 -3
- package/dist/core/preparation/artifacts.js.map +1 -1
- package/dist/core/preparation/evm.d.ts +38 -2
- package/dist/core/preparation/evm.d.ts.map +1 -1
- package/dist/core/preparation/evm.js +104 -32
- package/dist/core/preparation/evm.js.map +1 -1
- package/dist/core/preparation/evmManifestSync.d.ts +63 -0
- package/dist/core/preparation/evmManifestSync.d.ts.map +1 -0
- package/dist/core/preparation/evmManifestSync.js +146 -0
- package/dist/core/preparation/evmManifestSync.js.map +1 -0
- package/dist/core/preparation/index.d.ts +40 -2
- package/dist/core/preparation/index.d.ts.map +1 -1
- package/dist/core/preparation/index.js +3 -3
- package/dist/core/preparation/index.js.map +1 -1
- package/dist/core/preparation/manifest.d.ts +15 -3
- package/dist/core/preparation/manifest.d.ts.map +1 -1
- package/dist/core/preparation/manifest.js +21 -26
- package/dist/core/preparation/manifest.js.map +1 -1
- package/dist/core/preparation/normalize.d.ts.map +1 -1
- package/dist/core/preparation/normalize.js +14 -9
- package/dist/core/preparation/normalize.js.map +1 -1
- package/dist/core/preparation/types.d.ts +7 -2
- package/dist/core/preparation/types.d.ts.map +1 -1
- package/dist/custody/hardhat-runtime.d.ts.map +1 -1
- package/dist/custody/hardhat-runtime.js +2 -0
- package/dist/custody/hardhat-runtime.js.map +1 -1
- package/dist/custody/hardhat.d.ts +1 -0
- package/dist/custody/hardhat.d.ts.map +1 -1
- package/dist/custody/hardhat.js +1 -0
- package/dist/custody/hardhat.js.map +1 -1
- package/dist/custody/index.d.ts +1 -0
- package/dist/custody/index.d.ts.map +1 -1
- package/dist/custody/index.js +1 -0
- package/dist/custody/index.js.map +1 -1
- package/dist/custody/provider-wait.d.ts +13 -0
- package/dist/custody/provider-wait.d.ts.map +1 -0
- package/dist/custody/provider-wait.js +78 -0
- package/dist/custody/provider-wait.js.map +1 -0
- package/dist/delivery/policy.d.ts +6 -0
- package/dist/delivery/policy.d.ts.map +1 -0
- package/dist/delivery/policy.js +24 -0
- package/dist/delivery/policy.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/sync/index.d.ts +15 -0
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +8 -0
- package/dist/sync/index.js.map +1 -1
- package/dist/workflow/index.d.ts +6 -1
- package/dist/workflow/index.d.ts.map +1 -1
- package/dist/workflow/index.js +4 -0
- package/dist/workflow/index.js.map +1 -1
- package/dist-cjs/core/BytecodeChecker.js +526 -0
- package/dist-cjs/core/BytecodeChecker.js.map +1 -0
- package/dist-cjs/core/legacyProxyArtifact.js +42 -0
- package/dist-cjs/core/legacyProxyArtifact.js.map +1 -0
- package/dist-cjs/core/preparation/artifacts.js +11 -4
- package/dist-cjs/core/preparation/artifacts.js.map +1 -1
- package/dist-cjs/core/preparation/evm.js +105 -32
- package/dist-cjs/core/preparation/evm.js.map +1 -1
- package/dist-cjs/core/preparation/evmManifestSync.js +155 -0
- package/dist-cjs/core/preparation/evmManifestSync.js.map +1 -0
- package/dist-cjs/core/preparation/index.js +3 -3
- package/dist-cjs/core/preparation/index.js.map +1 -1
- package/dist-cjs/core/preparation/manifest.js +23 -28
- package/dist-cjs/core/preparation/manifest.js.map +1 -1
- package/dist-cjs/core/preparation/normalize.js +14 -9
- package/dist-cjs/core/preparation/normalize.js.map +1 -1
- package/dist-cjs/custody/hardhat-runtime.js +2 -0
- package/dist-cjs/custody/hardhat-runtime.js.map +1 -1
- package/dist-cjs/custody/hardhat.js +3 -1
- package/dist-cjs/custody/hardhat.js.map +1 -1
- package/dist-cjs/custody/index.js +3 -1
- package/dist-cjs/custody/index.js.map +1 -1
- package/dist-cjs/custody/provider-wait.js +81 -0
- package/dist-cjs/custody/provider-wait.js.map +1 -0
- package/dist-cjs/delivery/policy.js +29 -0
- package/dist-cjs/delivery/policy.js.map +1 -0
- package/dist-cjs/sync/index.js +8 -0
- package/dist-cjs/sync/index.js.map +1 -1
- package/dist-cjs/workflow/index.js +12 -1
- package/dist-cjs/workflow/index.js.map +1 -1
- package/dist-runtime/config/hardhatAdapters.d.ts +2 -0
- package/dist-runtime/config/hardhatAdapters.js +8 -0
- package/dist-runtime/config/hardhatAdapters.js.map +1 -1
- package/dist-runtime/config/networks.d.ts +25 -1
- package/dist-runtime/config/networks.js +8 -2
- package/dist-runtime/config/networks.js.map +1 -1
- package/dist-runtime/config/openzeppelin.d.ts +2 -1
- package/dist-runtime/config/openzeppelin.js +2 -19
- package/dist-runtime/config/openzeppelin.js.map +1 -1
- package/dist-runtime/delivery/abi.d.ts +14 -0
- package/dist-runtime/delivery/abi.js +161 -0
- package/dist-runtime/delivery/abi.js.map +1 -0
- package/dist-runtime/delivery/aggregate-bootstrap.d.ts +12 -0
- package/dist-runtime/delivery/aggregate-bootstrap.js +40 -0
- package/dist-runtime/delivery/aggregate-bootstrap.js.map +1 -0
- package/dist-runtime/delivery/aggregate-channel.d.ts +28 -0
- package/dist-runtime/delivery/aggregate-channel.js +155 -0
- package/dist-runtime/delivery/aggregate-channel.js.map +1 -0
- package/dist-runtime/delivery/aggregate-inputs.d.ts +168 -0
- package/dist-runtime/delivery/aggregate-inputs.js +57 -0
- package/dist-runtime/delivery/aggregate-inputs.js.map +1 -0
- package/dist-runtime/delivery/aggregate-source.d.ts +25 -0
- package/dist-runtime/delivery/aggregate-source.js +79 -0
- package/dist-runtime/delivery/aggregate-source.js.map +1 -0
- package/dist-runtime/delivery/aggregate-worker.d.ts +1 -0
- package/dist-runtime/delivery/aggregate-worker.js +191 -0
- package/dist-runtime/delivery/aggregate-worker.js.map +1 -0
- package/dist-runtime/delivery/aggregate.d.ts +51 -0
- package/dist-runtime/delivery/aggregate.js +190 -0
- package/dist-runtime/delivery/aggregate.js.map +1 -0
- package/dist-runtime/delivery/bindings.d.ts +21 -0
- package/dist-runtime/delivery/bindings.js +53 -0
- package/dist-runtime/delivery/bindings.js.map +1 -0
- package/dist-runtime/delivery/check-code.d.ts +19 -0
- package/dist-runtime/delivery/check-code.js +63 -0
- package/dist-runtime/delivery/check-code.js.map +1 -0
- package/dist-runtime/delivery/closure-format.d.ts +77 -0
- package/dist-runtime/delivery/closure-format.js +225 -0
- package/dist-runtime/delivery/closure-format.js.map +1 -0
- package/dist-runtime/delivery/codec-pin.d.ts +2 -0
- package/dist-runtime/delivery/codec-pin.js +7 -0
- package/dist-runtime/delivery/codec-pin.js.map +1 -0
- package/dist-runtime/delivery/codec.d.ts +19 -0
- package/dist-runtime/delivery/codec.js +73 -0
- package/dist-runtime/delivery/codec.js.map +1 -0
- package/dist-runtime/delivery/compiler-dependency-pins.d.ts +7 -0
- package/dist-runtime/delivery/compiler-dependency-pins.js +1689 -0
- package/dist-runtime/delivery/compiler-dependency-pins.js.map +1 -0
- package/dist-runtime/delivery/compiler-files.d.ts +40 -0
- package/dist-runtime/delivery/compiler-files.js +220 -0
- package/dist-runtime/delivery/compiler-files.js.map +1 -0
- package/dist-runtime/delivery/compiler-io.d.ts +2 -0
- package/dist-runtime/delivery/compiler-io.js +13 -0
- package/dist-runtime/delivery/compiler-io.js.map +1 -0
- package/dist-runtime/delivery/compiler-pins.d.ts +10 -0
- package/dist-runtime/delivery/compiler-pins.js +147 -0
- package/dist-runtime/delivery/compiler-pins.js.map +1 -0
- package/dist-runtime/delivery/compiler.d.ts +188 -0
- package/dist-runtime/delivery/compiler.js +850 -0
- package/dist-runtime/delivery/compiler.js.map +1 -0
- package/dist-runtime/delivery/config.d.ts +48 -0
- package/dist-runtime/delivery/config.js +99 -0
- package/dist-runtime/delivery/config.js.map +1 -0
- package/dist-runtime/delivery/configuration-definition.d.ts +22 -0
- package/dist-runtime/delivery/configuration-definition.js +316 -0
- package/dist-runtime/delivery/configuration-definition.js.map +1 -0
- package/dist-runtime/delivery/configuration-hre.d.ts +17 -0
- package/dist-runtime/delivery/configuration-hre.js +198 -0
- package/dist-runtime/delivery/configuration-hre.js.map +1 -0
- package/dist-runtime/delivery/configuration-runtime.d.ts +36 -0
- package/dist-runtime/delivery/configuration-runtime.js +248 -0
- package/dist-runtime/delivery/configuration-runtime.js.map +1 -0
- package/dist-runtime/delivery/configuration.d.ts +35 -0
- package/dist-runtime/delivery/configuration.js +83 -0
- package/dist-runtime/delivery/configuration.js.map +1 -0
- package/dist-runtime/delivery/create2.d.ts +3 -0
- package/dist-runtime/delivery/create2.js +48 -0
- package/dist-runtime/delivery/create2.js.map +1 -0
- package/dist-runtime/delivery/custom-closure.d.ts +27 -0
- package/dist-runtime/delivery/custom-closure.js +818 -0
- package/dist-runtime/delivery/custom-closure.js.map +1 -0
- package/dist-runtime/delivery/custom-format.d.ts +35 -0
- package/dist-runtime/delivery/custom-format.js +383 -0
- package/dist-runtime/delivery/custom-format.js.map +1 -0
- package/dist-runtime/delivery/custom.d.ts +32 -0
- package/dist-runtime/delivery/custom.js +158 -0
- package/dist-runtime/delivery/custom.js.map +1 -0
- package/dist-runtime/delivery/data.d.ts +7 -0
- package/dist-runtime/delivery/data.js +86 -0
- package/dist-runtime/delivery/data.js.map +1 -0
- package/dist-runtime/delivery/development.d.ts +91 -0
- package/dist-runtime/delivery/development.js +395 -0
- package/dist-runtime/delivery/development.js.map +1 -0
- package/dist-runtime/delivery/engine.d.ts +9 -0
- package/dist-runtime/delivery/engine.js +23 -0
- package/dist-runtime/delivery/engine.js.map +1 -0
- package/dist-runtime/delivery/eoa-observation.d.ts +43 -0
- package/dist-runtime/delivery/eoa-observation.js +145 -0
- package/dist-runtime/delivery/eoa-observation.js.map +1 -0
- package/dist-runtime/delivery/eoa-signed.d.ts +2 -0
- package/dist-runtime/delivery/eoa-signed.js +74 -0
- package/dist-runtime/delivery/eoa-signed.js.map +1 -0
- package/dist-runtime/delivery/eoa.d.ts +81 -0
- package/dist-runtime/delivery/eoa.js +274 -0
- package/dist-runtime/delivery/eoa.js.map +1 -0
- package/dist-runtime/delivery/execution-db.d.ts +20 -0
- package/dist-runtime/delivery/execution-db.js +153 -0
- package/dist-runtime/delivery/execution-db.js.map +1 -0
- package/dist-runtime/delivery/execution-files.d.ts +9 -0
- package/dist-runtime/delivery/execution-files.js +138 -0
- package/dist-runtime/delivery/execution-files.js.map +1 -0
- package/dist-runtime/delivery/execution-model.d.ts +56 -0
- package/dist-runtime/delivery/execution-model.js +66 -0
- package/dist-runtime/delivery/execution-model.js.map +1 -0
- package/dist-runtime/delivery/execution-store.d.ts +48 -0
- package/dist-runtime/delivery/execution-store.js +361 -0
- package/dist-runtime/delivery/execution-store.js.map +1 -0
- package/dist-runtime/delivery/existing-code.d.ts +37 -0
- package/dist-runtime/delivery/existing-code.js +75 -0
- package/dist-runtime/delivery/existing-code.js.map +1 -0
- package/dist-runtime/delivery/export.d.ts +51 -0
- package/dist-runtime/delivery/export.js +69 -0
- package/dist-runtime/delivery/export.js.map +1 -0
- package/dist-runtime/delivery/forkAudit.d.ts +119 -0
- package/dist-runtime/delivery/forkAudit.js +473 -0
- package/dist-runtime/delivery/forkAudit.js.map +1 -0
- package/dist-runtime/delivery/hardhat.d.ts +3 -0
- package/dist-runtime/delivery/hardhat.js +45 -0
- package/dist-runtime/delivery/hardhat.js.map +1 -0
- package/dist-runtime/delivery/history-registration.d.ts +2 -0
- package/dist-runtime/delivery/history-registration.js +17 -0
- package/dist-runtime/delivery/history-registration.js.map +1 -0
- package/dist-runtime/delivery/identities.d.ts +22 -0
- package/dist-runtime/delivery/identities.js +97 -0
- package/dist-runtime/delivery/identities.js.map +1 -0
- package/dist-runtime/delivery/input-files.d.ts +5 -0
- package/dist-runtime/delivery/input-files.js +70 -0
- package/dist-runtime/delivery/input-files.js.map +1 -0
- package/dist-runtime/delivery/inputs.d.ts +62 -0
- package/dist-runtime/delivery/inputs.js +187 -0
- package/dist-runtime/delivery/inputs.js.map +1 -0
- package/dist-runtime/delivery/journal.d.ts +35 -0
- package/dist-runtime/delivery/journal.js +270 -0
- package/dist-runtime/delivery/journal.js.map +1 -0
- package/dist-runtime/delivery/manifest.d.ts +14 -0
- package/dist-runtime/delivery/manifest.js +68 -0
- package/dist-runtime/delivery/manifest.js.map +1 -0
- package/dist-runtime/delivery/materialization.d.ts +20 -0
- package/dist-runtime/delivery/materialization.js +138 -0
- package/dist-runtime/delivery/materialization.js.map +1 -0
- package/dist-runtime/delivery/observations.d.ts +31 -0
- package/dist-runtime/delivery/observations.js +38 -0
- package/dist-runtime/delivery/observations.js.map +1 -0
- package/dist-runtime/delivery/parameters.d.ts +53 -0
- package/dist-runtime/delivery/parameters.js +257 -0
- package/dist-runtime/delivery/parameters.js.map +1 -0
- package/dist-runtime/delivery/pending.d.ts +70 -0
- package/dist-runtime/delivery/pending.js +99 -0
- package/dist-runtime/delivery/pending.js.map +1 -0
- package/dist-runtime/delivery/plan.d.ts +50 -0
- package/dist-runtime/delivery/plan.js +209 -0
- package/dist-runtime/delivery/plan.js.map +1 -0
- package/dist-runtime/delivery/planning.d.ts +81 -0
- package/dist-runtime/delivery/planning.js +302 -0
- package/dist-runtime/delivery/planning.js.map +1 -0
- package/dist-runtime/delivery/policy.d.ts +4 -0
- package/dist-runtime/delivery/policy.js +9 -0
- package/dist-runtime/delivery/policy.js.map +1 -0
- package/dist-runtime/delivery/preparation.d.ts +6 -0
- package/dist-runtime/delivery/preparation.js +158 -0
- package/dist-runtime/delivery/preparation.js.map +1 -0
- package/dist-runtime/delivery/production-environment.d.ts +2 -0
- package/dist-runtime/delivery/production-environment.js +12 -0
- package/dist-runtime/delivery/production-environment.js.map +1 -0
- package/dist-runtime/delivery/production-finalization.d.ts +86 -0
- package/dist-runtime/delivery/production-finalization.js +278 -0
- package/dist-runtime/delivery/production-finalization.js.map +1 -0
- package/dist-runtime/delivery/production.d.ts +461 -0
- package/dist-runtime/delivery/production.js +396 -0
- package/dist-runtime/delivery/production.js.map +1 -0
- package/dist-runtime/delivery/project-files.d.ts +8 -0
- package/dist-runtime/delivery/project-files.js +82 -0
- package/dist-runtime/delivery/project-files.js.map +1 -0
- package/dist-runtime/delivery/project.d.ts +15 -0
- package/dist-runtime/delivery/project.js +157 -0
- package/dist-runtime/delivery/project.js.map +1 -0
- package/dist-runtime/delivery/protocol.d.ts +49 -0
- package/dist-runtime/delivery/protocol.js +112 -0
- package/dist-runtime/delivery/protocol.js.map +1 -0
- package/dist-runtime/delivery/references.d.ts +19 -0
- package/dist-runtime/delivery/references.js +84 -0
- package/dist-runtime/delivery/references.js.map +1 -0
- package/dist-runtime/delivery/release-graph.d.ts +93 -0
- package/dist-runtime/delivery/release-graph.js +106 -0
- package/dist-runtime/delivery/release-graph.js.map +1 -0
- package/dist-runtime/delivery/release-history-capture.d.ts +7 -0
- package/dist-runtime/delivery/release-history-capture.js +76 -0
- package/dist-runtime/delivery/release-history-capture.js.map +1 -0
- package/dist-runtime/delivery/release-history.d.ts +43 -0
- package/dist-runtime/delivery/release-history.js +246 -0
- package/dist-runtime/delivery/release-history.js.map +1 -0
- package/dist-runtime/delivery/release.d.ts +172 -0
- package/dist-runtime/delivery/release.js +209 -0
- package/dist-runtime/delivery/release.js.map +1 -0
- package/dist-runtime/delivery/safe-manifest.d.ts +9 -0
- package/dist-runtime/delivery/safe-manifest.js +13 -0
- package/dist-runtime/delivery/safe-manifest.js.map +1 -0
- package/dist-runtime/delivery/safe-observation.d.ts +30 -0
- package/dist-runtime/delivery/safe-observation.js +487 -0
- package/dist-runtime/delivery/safe-observation.js.map +1 -0
- package/dist-runtime/delivery/safe-prepare.d.ts +13 -0
- package/dist-runtime/delivery/safe-prepare.js +81 -0
- package/dist-runtime/delivery/safe-prepare.js.map +1 -0
- package/dist-runtime/delivery/safe.d.ts +91 -0
- package/dist-runtime/delivery/safe.js +243 -0
- package/dist-runtime/delivery/safe.js.map +1 -0
- package/dist-runtime/delivery/same-fork-baseline.d.ts +8 -0
- package/dist-runtime/delivery/same-fork-baseline.js +20 -0
- package/dist-runtime/delivery/same-fork-baseline.js.map +1 -0
- package/dist-runtime/delivery/setup.d.ts +31 -0
- package/dist-runtime/delivery/setup.js +215 -0
- package/dist-runtime/delivery/setup.js.map +1 -0
- package/dist-runtime/delivery/source.d.ts +41 -0
- package/dist-runtime/delivery/source.js +137 -0
- package/dist-runtime/delivery/source.js.map +1 -0
- package/dist-runtime/delivery/target-fields.d.ts +2 -0
- package/dist-runtime/delivery/target-fields.js +11 -0
- package/dist-runtime/delivery/target-fields.js.map +1 -0
- package/dist-runtime/delivery/validation.d.ts +9 -0
- package/dist-runtime/delivery/validation.js +150 -0
- package/dist-runtime/delivery/validation.js.map +1 -0
- package/dist-runtime/delivery/verification.d.ts +16 -0
- package/dist-runtime/delivery/verification.js +65 -0
- package/dist-runtime/delivery/verification.js.map +1 -0
- package/dist-runtime/migrate.js +1 -0
- package/dist-runtime/migrate.js.map +1 -1
- package/dist-runtime/miner/binary.d.ts +2 -0
- package/dist-runtime/miner/binary.js +54 -0
- package/dist-runtime/miner/binary.js.map +1 -0
- package/dist-runtime/miner/cli.d.ts +1 -0
- package/dist-runtime/miner/cli.js +131 -0
- package/dist-runtime/miner/cli.js.map +1 -0
- package/dist-runtime/miner/index.d.ts +5 -0
- package/dist-runtime/miner/index.js +13 -0
- package/dist-runtime/miner/index.js.map +1 -0
- package/dist-runtime/miner/request.d.ts +7 -0
- package/dist-runtime/miner/request.js +73 -0
- package/dist-runtime/miner/request.js.map +1 -0
- package/dist-runtime/miner/runner.d.ts +2 -0
- package/dist-runtime/miner/runner.js +131 -0
- package/dist-runtime/miner/runner.js.map +1 -0
- package/dist-runtime/miner/types.d.ts +89 -0
- package/dist-runtime/miner/types.js +3 -0
- package/dist-runtime/miner/types.js.map +1 -0
- package/dist-runtime/miner/verify.d.ts +2 -0
- package/dist-runtime/miner/verify.js +75 -0
- package/dist-runtime/miner/verify.js.map +1 -0
- package/dist-runtime/runtime-identity.json +2 -2
- package/dist-runtime/vendor/plan-codec/index.cjs +820 -0
- package/dist-runtime/vendor/plan-codec/index.d.cts +32 -0
- package/dist-runtime/vendor/plan-codec/provenance.json +24 -0
- package/dist-runtime/workflow/engine.d.ts +14 -0
- package/dist-runtime/workflow/engine.js +160 -0
- package/dist-runtime/workflow/engine.js.map +1 -0
- package/dist-runtime/workflow/lib/authority.d.ts +6 -3
- package/dist-runtime/workflow/lib/authority.js.map +1 -1
- package/dist-runtime/workflow/lib/calls.d.ts +1 -1
- package/dist-runtime/workflow/lib/calls.js +43 -34
- package/dist-runtime/workflow/lib/calls.js.map +1 -1
- package/dist-runtime/workflow/lib/canonicalData.d.ts +8 -0
- package/dist-runtime/workflow/lib/canonicalData.js +68 -0
- package/dist-runtime/workflow/lib/canonicalData.js.map +1 -0
- package/dist-runtime/workflow/lib/config.d.ts +3 -1
- package/dist-runtime/workflow/lib/config.js.map +1 -1
- package/dist-runtime/workflow/lib/context.d.ts +76 -0
- package/dist-runtime/workflow/lib/context.js +3 -0
- package/dist-runtime/workflow/lib/context.js.map +1 -0
- package/dist-runtime/workflow/lib/controlledMulticallAbi.d.ts +2 -0
- package/dist-runtime/workflow/lib/controlledMulticallAbi.js +10 -0
- package/dist-runtime/workflow/lib/controlledMulticallAbi.js.map +1 -0
- package/dist-runtime/workflow/lib/create2.d.ts +1 -1
- package/dist-runtime/workflow/lib/create2.js +9 -12
- package/dist-runtime/workflow/lib/create2.js.map +1 -1
- package/dist-runtime/workflow/lib/deployments.d.ts +5 -5
- package/dist-runtime/workflow/lib/deployments.js +5 -13
- package/dist-runtime/workflow/lib/deployments.js.map +1 -1
- package/dist-runtime/workflow/lib/evidencePorts.d.ts +55 -0
- package/dist-runtime/workflow/lib/evidencePorts.js +3 -0
- package/dist-runtime/workflow/lib/evidencePorts.js.map +1 -0
- package/dist-runtime/workflow/lib/executionPlan.d.ts +4 -42
- package/dist-runtime/workflow/lib/executionPlan.js +15 -210
- package/dist-runtime/workflow/lib/executionPlan.js.map +1 -1
- package/dist-runtime/workflow/lib/gateTool.d.ts +6 -2
- package/dist-runtime/workflow/lib/gateTool.js +20 -10
- package/dist-runtime/workflow/lib/gateTool.js.map +1 -1
- package/dist-runtime/workflow/lib/gateToolSync.d.ts +1 -1
- package/dist-runtime/workflow/lib/gateToolSync.js +3 -2
- package/dist-runtime/workflow/lib/gateToolSync.js.map +1 -1
- package/dist-runtime/workflow/lib/operationNames.d.ts +3 -0
- package/dist-runtime/workflow/lib/operationNames.js +34 -0
- package/dist-runtime/workflow/lib/operationNames.js.map +1 -0
- package/dist-runtime/workflow/lib/parameters.d.ts +1 -1
- package/dist-runtime/workflow/lib/parameters.js +9 -24
- package/dist-runtime/workflow/lib/parameters.js.map +1 -1
- package/dist-runtime/workflow/lib/pendingDeploymentReuse.js +18 -52
- package/dist-runtime/workflow/lib/pendingDeploymentReuse.js.map +1 -1
- package/dist-runtime/workflow/lib/pendingUupsBinding.d.ts +42 -0
- package/dist-runtime/workflow/lib/pendingUupsBinding.js +39 -0
- package/dist-runtime/workflow/lib/pendingUupsBinding.js.map +1 -0
- package/dist-runtime/workflow/lib/plan.d.ts +55 -0
- package/dist-runtime/workflow/lib/plan.js +324 -0
- package/dist-runtime/workflow/lib/plan.js.map +1 -0
- package/dist-runtime/workflow/lib/planCli.d.ts +14 -0
- package/dist-runtime/workflow/lib/planCli.js +279 -0
- package/dist-runtime/workflow/lib/planCli.js.map +1 -0
- package/dist-runtime/workflow/lib/preparationEvidence.d.ts +4 -0
- package/dist-runtime/workflow/lib/preparationEvidence.js +19 -0
- package/dist-runtime/workflow/lib/preparationEvidence.js.map +1 -0
- package/dist-runtime/workflow/lib/proxy.d.ts +3 -2
- package/dist-runtime/workflow/lib/proxy.js +3 -4
- package/dist-runtime/workflow/lib/proxy.js.map +1 -1
- package/dist-runtime/workflow/lib/runtime.d.ts +6 -0
- package/dist-runtime/workflow/lib/runtime.js +48 -0
- package/dist-runtime/workflow/lib/runtime.js.map +1 -0
- package/dist-runtime/workflow/lib/signer.d.ts +3 -2
- package/dist-runtime/workflow/lib/signer.js +18 -18
- package/dist-runtime/workflow/lib/signer.js.map +1 -1
- package/dist-runtime/workflow/lib/simulation.d.ts +13 -6
- package/dist-runtime/workflow/lib/simulation.js +39 -31
- package/dist-runtime/workflow/lib/simulation.js.map +1 -1
- package/dist-runtime/workflow/lib/state.js +3 -3
- package/dist-runtime/workflow/lib/state.js.map +1 -1
- package/dist-runtime/workflow/lib/staticValidation.d.ts +28 -0
- package/dist-runtime/workflow/lib/staticValidation.js +54 -10
- package/dist-runtime/workflow/lib/staticValidation.js.map +1 -1
- package/dist-runtime/workflow/lib/transactionPlanner.d.ts +62 -0
- package/dist-runtime/workflow/lib/transactionPlanner.js +258 -0
- package/dist-runtime/workflow/lib/transactionPlanner.js.map +1 -0
- package/dist-runtime/workflow/lib/typedValue.d.ts +3 -0
- package/dist-runtime/workflow/lib/typedValue.js +76 -0
- package/dist-runtime/workflow/lib/typedValue.js.map +1 -0
- package/dist-runtime/workflow/lib/validation.d.ts +23 -0
- package/dist-runtime/workflow/lib/validation.js +15 -0
- package/dist-runtime/workflow/lib/validation.js.map +1 -0
- package/dist-runtime/workflow/planAdd.d.ts +1 -0
- package/dist-runtime/workflow/planAdd.js +11 -0
- package/dist-runtime/workflow/planAdd.js.map +1 -0
- package/dist-runtime/workflow/planRead.d.ts +1 -0
- package/dist-runtime/workflow/planRead.js +11 -0
- package/dist-runtime/workflow/planRead.js.map +1 -0
- package/dist-runtime/workflow/planStatus.d.ts +1 -0
- package/dist-runtime/workflow/planStatus.js +11 -0
- package/dist-runtime/workflow/planStatus.js.map +1 -0
- package/dist-runtime/workflow/planWrite.d.ts +1 -0
- package/dist-runtime/workflow/planWrite.js +11 -0
- package/dist-runtime/workflow/planWrite.js.map +1 -0
- package/dist-runtime/workflow/run.d.ts +1 -40
- package/dist-runtime/workflow/run.js +68 -136
- package/dist-runtime/workflow/run.js.map +1 -1
- package/dist-runtime/workflow/staticValidate.js +8 -3
- package/dist-runtime/workflow/staticValidate.js.map +1 -1
- package/dist-runtime/workflow/steps/call.d.ts +1 -1
- package/dist-runtime/workflow/steps/check.d.ts +1 -1
- package/dist-runtime/workflow/steps/custom.d.ts +1 -1
- package/dist-runtime/workflow/steps/deploy.d.ts +1 -1
- package/dist-runtime/workflow/steps/deploy.js +58 -55
- package/dist-runtime/workflow/steps/deploy.js.map +1 -1
- package/dist-runtime/workflow/steps/upgrade.d.ts +1 -1
- package/dist-runtime/workflow/steps/upgrade.js +63 -41
- package/dist-runtime/workflow/steps/upgrade.js.map +1 -1
- package/dist-runtime/workflow/steps/view.d.ts +1 -1
- package/docs/compiler-qualification.md +32 -0
- package/docs/configuration-runtime-observation.md +29 -0
- package/docs/create2-miner.md +100 -0
- package/docs/delivery-aggregate.md +27 -0
- package/docs/delivery-custom-input-closure.md +51 -0
- package/docs/delivery-development.md +32 -0
- package/docs/delivery-eoa.md +46 -0
- package/docs/delivery-evm-manifest.md +20 -0
- package/docs/delivery-execution-store.md +33 -0
- package/docs/delivery-inputs.md +46 -0
- package/docs/delivery-parameters.md +65 -0
- package/docs/delivery-planning.md +140 -0
- package/docs/delivery-release.md +65 -0
- package/docs/delivery-safe.md +72 -0
- package/docs/delivery-setup.md +146 -0
- package/docs/delivery-source.md +67 -0
- package/docs/direct-package-acceptance.md +20 -0
- package/docs/external-infrastructure-acceptance.md +33 -0
- package/docs/network-runtime-acceptance.md +18 -0
- package/docs/plans/2026-09-09-workflow-extraction.md +16 -0
- package/docs/superpowers/plans/2026-07-22-manifest-bootstrap-transaction.md +50 -0
- package/docs/superpowers/plans/2026-07-22-manifest-review-remediation.md +49 -0
- package/docs/superpowers/plans/2026-08-17-custody-hardhat-signers.md +227 -0
- package/docs/superpowers/plans/2026-09-09-remove-template-infrastructure-contracts.md +11 -0
- package/docs/superpowers/plans/2026-09-24-scheme-aware-static-validation.md +193 -0
- package/docs/superpowers/plans/2026-10-28-create2-miner.md +82 -0
- package/docs/workflow-reference.md +1181 -0
- package/docs/workflow-runtime-acceptance.md +17 -0
- package/docs/workflow-runtime.md +56 -0
- package/package.json +134 -9
- package/resources/create2/LICENSE +21 -0
- package/resources/create2/README.md +9 -0
- package/resources/create2/darwin-arm64/smartflow_miner +0 -0
- package/resources/create2/darwin-x64/smartflow_miner +0 -0
- package/resources/create2/manifest.json +27 -0
- package/runtime/config/hardhatAdapters.ts +8 -0
- package/runtime/config/networks.ts +20 -11
- package/runtime/config/openzeppelin.ts +3 -21
- package/runtime/delivery/abi.ts +225 -0
- package/runtime/delivery/aggregate-bootstrap.ts +29 -0
- package/runtime/delivery/aggregate-channel.ts +85 -0
- package/runtime/delivery/aggregate-inputs.ts +39 -0
- package/runtime/delivery/aggregate-source.ts +53 -0
- package/runtime/delivery/aggregate-worker.ts +133 -0
- package/runtime/delivery/aggregate.ts +139 -0
- package/runtime/delivery/bindings.ts +37 -0
- package/runtime/delivery/check-code.ts +38 -0
- package/runtime/delivery/closure-format.ts +350 -0
- package/runtime/delivery/codec-pin.ts +3 -0
- package/runtime/delivery/codec.ts +50 -0
- package/runtime/delivery/compiler-dependency-pins.ts +1685 -0
- package/runtime/delivery/compiler-files.ts +179 -0
- package/runtime/delivery/compiler-io.ts +10 -0
- package/runtime/delivery/compiler-pins.ts +143 -0
- package/runtime/delivery/compiler.ts +700 -0
- package/runtime/delivery/config.ts +93 -0
- package/runtime/delivery/configuration-definition.ts +133 -0
- package/runtime/delivery/configuration-hre.ts +130 -0
- package/runtime/delivery/configuration-runtime.ts +163 -0
- package/runtime/delivery/configuration.ts +64 -0
- package/runtime/delivery/create2.ts +57 -0
- package/runtime/delivery/custom-closure.ts +993 -0
- package/runtime/delivery/custom-format.ts +464 -0
- package/runtime/delivery/custom.ts +219 -0
- package/runtime/delivery/data.ts +94 -0
- package/runtime/delivery/development.ts +262 -0
- package/runtime/delivery/engine.ts +29 -0
- package/runtime/delivery/eoa-observation.ts +106 -0
- package/runtime/delivery/eoa-signed.ts +55 -0
- package/runtime/delivery/eoa.ts +288 -0
- package/runtime/delivery/execution-db.ts +131 -0
- package/runtime/delivery/execution-files.ts +135 -0
- package/runtime/delivery/execution-model.ts +102 -0
- package/runtime/delivery/execution-store.ts +411 -0
- package/runtime/delivery/existing-code.ts +44 -0
- package/runtime/delivery/export.ts +99 -0
- package/runtime/delivery/forkAudit.ts +620 -0
- package/runtime/delivery/hardhat.ts +38 -0
- package/runtime/delivery/history-registration.ts +10 -0
- package/runtime/delivery/identities.ts +132 -0
- package/runtime/delivery/input-files.ts +46 -0
- package/runtime/delivery/inputs.ts +197 -0
- package/runtime/delivery/journal.ts +201 -0
- package/runtime/delivery/manifest.ts +54 -0
- package/runtime/delivery/materialization.ts +53 -0
- package/runtime/delivery/observations.ts +60 -0
- package/runtime/delivery/parameters.ts +349 -0
- package/runtime/delivery/pending.ts +98 -0
- package/runtime/delivery/plan.ts +337 -0
- package/runtime/delivery/planning.ts +397 -0
- package/runtime/delivery/policy.ts +9 -0
- package/runtime/delivery/preparation.ts +224 -0
- package/runtime/delivery/production-environment.ts +6 -0
- package/runtime/delivery/production-finalization.ts +172 -0
- package/runtime/delivery/production.ts +375 -0
- package/runtime/delivery/project-files.ts +58 -0
- package/runtime/delivery/project.ts +117 -0
- package/runtime/delivery/protocol.ts +94 -0
- package/runtime/delivery/references.ts +106 -0
- package/runtime/delivery/release-graph.ts +49 -0
- package/runtime/delivery/release-history-capture.ts +32 -0
- package/runtime/delivery/release-history.ts +120 -0
- package/runtime/delivery/release.ts +128 -0
- package/runtime/delivery/safe-manifest.ts +11 -0
- package/runtime/delivery/safe-observation.ts +626 -0
- package/runtime/delivery/safe-prepare.ts +101 -0
- package/runtime/delivery/safe.ts +344 -0
- package/runtime/delivery/same-fork-baseline.ts +16 -0
- package/runtime/delivery/setup.ts +172 -0
- package/runtime/delivery/source.ts +130 -0
- package/runtime/delivery/target-fields.ts +7 -0
- package/runtime/delivery/validation.ts +247 -0
- package/runtime/delivery/verification.ts +47 -0
- package/runtime/migrate.ts +1 -0
- package/runtime/miner/binary.ts +41 -0
- package/runtime/miner/cli.ts +87 -0
- package/runtime/miner/index.ts +5 -0
- package/runtime/miner/request.ts +54 -0
- package/runtime/miner/runner.ts +90 -0
- package/runtime/miner/types.ts +71 -0
- package/runtime/miner/verify.ts +61 -0
- package/runtime/vendor/plan-codec/index.cjs +820 -0
- package/runtime/vendor/plan-codec/index.d.cts +32 -0
- package/runtime/vendor/plan-codec/provenance.json +24 -0
- package/runtime/workflow/engine.ts +174 -0
- package/runtime/workflow/lib/authority.ts +3 -3
- package/runtime/workflow/lib/calls.ts +46 -37
- package/runtime/workflow/lib/canonicalData.ts +45 -0
- package/runtime/workflow/lib/config.ts +1 -1
- package/runtime/workflow/lib/context.ts +76 -0
- package/runtime/workflow/lib/controlledMulticallAbi.ts +6 -0
- package/runtime/workflow/lib/create2.ts +10 -12
- package/runtime/workflow/lib/deployments.ts +6 -14
- package/runtime/workflow/lib/evidencePorts.ts +20 -0
- package/runtime/workflow/lib/executionPlan.ts +17 -268
- package/runtime/workflow/lib/gateTool.ts +20 -8
- package/runtime/workflow/lib/gateToolSync.ts +3 -3
- package/runtime/workflow/lib/operationNames.ts +32 -0
- package/runtime/workflow/lib/parameters.ts +7 -23
- package/runtime/workflow/lib/pendingDeploymentReuse.ts +4 -56
- package/runtime/workflow/lib/pendingUupsBinding.ts +43 -0
- package/runtime/workflow/lib/plan.ts +334 -0
- package/runtime/workflow/lib/planCli.ts +279 -0
- package/runtime/workflow/lib/preparationEvidence.ts +14 -0
- package/runtime/workflow/lib/proxy.ts +5 -3
- package/runtime/workflow/lib/runtime.ts +46 -0
- package/runtime/workflow/lib/signer.ts +8 -5
- package/runtime/workflow/lib/simulation.ts +41 -17
- package/runtime/workflow/lib/state.ts +3 -3
- package/runtime/workflow/lib/staticValidation.ts +92 -11
- package/runtime/workflow/lib/transactionPlanner.ts +314 -0
- package/runtime/workflow/lib/typedValue.ts +46 -0
- package/runtime/workflow/lib/validation.ts +50 -0
- package/runtime/workflow/planAdd.ts +8 -0
- package/runtime/workflow/planRead.ts +8 -0
- package/runtime/workflow/planStatus.ts +8 -0
- package/runtime/workflow/planWrite.ts +8 -0
- package/runtime/workflow/run.ts +41 -174
- package/runtime/workflow/staticValidate.ts +8 -3
- package/runtime/workflow/steps/call.ts +1 -1
- package/runtime/workflow/steps/check.ts +1 -1
- package/runtime/workflow/steps/custom.ts +1 -1
- package/runtime/workflow/steps/deploy.ts +59 -59
- package/runtime/workflow/steps/upgrade.ts +71 -47
- package/runtime/workflow/steps/view.ts +1 -1
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import ts from 'typescript';
|
|
3
|
+
import { positiveInteger, type ProjectNetworkSnapshot } from './protocol';
|
|
4
|
+
import { validateNetworkAlias } from './policy';
|
|
5
|
+
|
|
6
|
+
export { stat, confinedFile, projectRoot, readFile, coreMarker } from './project-files';
|
|
7
|
+
import { confinedFile, readFile } from './project-files';
|
|
8
|
+
|
|
9
|
+
function unwrap(node: ts.Expression): ts.Expression {
|
|
10
|
+
while (ts.isParenthesizedExpression(node) || ts.isAsExpression(node) || ts.isSatisfiesExpression(node)) node = node.expression;
|
|
11
|
+
return node;
|
|
12
|
+
}
|
|
13
|
+
function properties(node: ts.Expression, label: string): Map<string, ts.Expression> {
|
|
14
|
+
node = unwrap(node);
|
|
15
|
+
if (!ts.isObjectLiteralExpression(node)) throw new Error(`${label} must be a static object literal`);
|
|
16
|
+
const map = new Map<string, ts.Expression>();
|
|
17
|
+
for (const item of node.properties) {
|
|
18
|
+
if (!ts.isPropertyAssignment(item) || (!ts.isIdentifier(item.name) && !ts.isStringLiteral(item.name))) throw new Error(`${label} has unsupported computed or spread fields`);
|
|
19
|
+
const key = item.name.text;
|
|
20
|
+
if (['__proto__', 'constructor', 'prototype'].includes(key)) throw new Error(`Reserved prototype property in ${label}`);
|
|
21
|
+
if (map.has(key)) throw new Error(`Duplicate ${label} field: ${key}`);
|
|
22
|
+
map.set(key, unwrap(item.initializer));
|
|
23
|
+
}
|
|
24
|
+
return map;
|
|
25
|
+
}
|
|
26
|
+
export function parseProjectConfig(source: string): { file: ts.SourceFile; networks: Map<string, ts.Expression>; fields: Map<string, ts.Expression> } {
|
|
27
|
+
const file = ts.createSourceFile('hardhat.config.ts', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
28
|
+
const diagnostics = (file as ts.SourceFile & { parseDiagnostics: ts.Diagnostic[] }).parseDiagnostics;
|
|
29
|
+
if (diagnostics.length) throw new Error('Invalid hardhat.config.ts syntax');
|
|
30
|
+
const exports = file.statements.filter(ts.isExportAssignment);
|
|
31
|
+
if (exports.length !== 1 || exports[0].isExportEquals) throw new Error('Config requires one default export');
|
|
32
|
+
let config = unwrap(exports[0].expression);
|
|
33
|
+
if (ts.isIdentifier(config)) {
|
|
34
|
+
const name = config.text;
|
|
35
|
+
const declarations = file.statements.filter(ts.isVariableStatement).flatMap(statement => [...statement.declarationList.declarations]
|
|
36
|
+
.map(declaration => ({ declaration, statement }))).filter(({ declaration }) => ts.isIdentifier(declaration.name) && declaration.name.text === name);
|
|
37
|
+
if (declarations.length !== 1 || !(declarations[0].statement.declarationList.flags & ts.NodeFlags.Const) || !declarations[0].declaration.initializer) throw new Error('Config requires a static const object');
|
|
38
|
+
const declaration = declarations[0].declaration;
|
|
39
|
+
const references: ts.Identifier[] = [];
|
|
40
|
+
const visit = (node: ts.Node): void => { if (ts.isIdentifier(node) && node.text === name) references.push(node); ts.forEachChild(node, visit); };
|
|
41
|
+
visit(file);
|
|
42
|
+
if (references.some(node => node !== declaration.name && node !== config)) throw new Error('Ambiguous mutable config references');
|
|
43
|
+
config = unwrap(declaration.initializer!);
|
|
44
|
+
}
|
|
45
|
+
const fields = properties(config, 'config');
|
|
46
|
+
const networkNode = fields.get('networks');
|
|
47
|
+
if (!networkNode) throw new Error('Project config must declare networks');
|
|
48
|
+
return { file, networks: properties(networkNode, 'networks'), fields };
|
|
49
|
+
}
|
|
50
|
+
export function projectSourcesDirectory(root: string): string {
|
|
51
|
+
const { fields } = parseProjectConfig(readFile(root, 'hardhat.config.ts') ?? '');
|
|
52
|
+
const paths = fields.get('paths');
|
|
53
|
+
const sources = paths && properties(paths, 'paths').get('sources');
|
|
54
|
+
if (sources && !ts.isStringLiteral(sources)) throw new Error('Project paths.sources must be a static string for dependency inspection');
|
|
55
|
+
const sourcePath = sources && ts.isStringLiteral(sources) ? sources.text : 'contracts';
|
|
56
|
+
const relative = path.relative(root, path.resolve(root, sourcePath)).split(path.sep).join('/');
|
|
57
|
+
return confinedFile(root, relative, 'directory');
|
|
58
|
+
}
|
|
59
|
+
export function projectDefaultNetwork(root: string): string {
|
|
60
|
+
const { fields } = parseProjectConfig(readFile(root, 'hardhat.config.ts') ?? '');
|
|
61
|
+
const network = fields.get('defaultNetwork');
|
|
62
|
+
if (!network) return 'hardhat';
|
|
63
|
+
if (!ts.isStringLiteral(network)) throw new Error('Project defaultNetwork must be a static string for delivery routing');
|
|
64
|
+
return validateNetworkAlias(network.text, 'defaultNetwork');
|
|
65
|
+
}
|
|
66
|
+
function rpcValue(node: ts.Expression, env: NodeJS.ProcessEnv): string | undefined {
|
|
67
|
+
node = unwrap(node);
|
|
68
|
+
if (ts.isStringLiteral(node)) return node.text;
|
|
69
|
+
if (ts.isPropertyAccessExpression(node) && ts.isPropertyAccessExpression(node.expression)
|
|
70
|
+
&& ts.isIdentifier(node.expression.expression) && node.expression.expression.text === 'process'
|
|
71
|
+
&& node.expression.name.text === 'env') return env[node.name.text];
|
|
72
|
+
if (ts.isElementAccessExpression(node) && ts.isPropertyAccessExpression(node.expression)
|
|
73
|
+
&& ts.isIdentifier(node.expression.expression) && node.expression.expression.text === 'process'
|
|
74
|
+
&& node.expression.name.text === 'env' && ts.isStringLiteral(node.argumentExpression)) return env[node.argumentExpression.text];
|
|
75
|
+
if (ts.isBinaryExpression(node) && [ts.SyntaxKind.BarBarToken, ts.SyntaxKind.QuestionQuestionToken].includes(node.operatorToken.kind)) {
|
|
76
|
+
const left = rpcValue(node.left, env);
|
|
77
|
+
return node.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken
|
|
78
|
+
? left ?? rpcValue(node.right, env) : left || rpcValue(node.right, env);
|
|
79
|
+
}
|
|
80
|
+
throw new Error('Selected network URL must be a literal or process.env reference');
|
|
81
|
+
}
|
|
82
|
+
/** Read the project-owned definitions without evaluating the config, plugins or HRE. */
|
|
83
|
+
export function readProjectNetworkSnapshots(root: string, aliases: string[], env: NodeJS.ProcessEnv = process.env): ProjectNetworkSnapshot[] {
|
|
84
|
+
return parseProjectNetworkSnapshots(readFile(root, 'hardhat.config.ts') ?? '', aliases, env);
|
|
85
|
+
}
|
|
86
|
+
/** Parse one captured project definition without rereading files or evaluating plugins/HRE. */
|
|
87
|
+
export function parseProjectNetworkSnapshots(source: string, aliases: string[], env: NodeJS.ProcessEnv = process.env): ProjectNetworkSnapshot[] {
|
|
88
|
+
const { networks } = parseProjectConfig(source);
|
|
89
|
+
return aliases.map(network => {
|
|
90
|
+
validateNetworkAlias(network, 'network', false);
|
|
91
|
+
const selected = networks.get(network);
|
|
92
|
+
if (!selected || network === 'hardhat') throw new Error(`Selected project network is missing or not an RPC target: ${network}`);
|
|
93
|
+
const fields = properties(selected, `network ${network}`);
|
|
94
|
+
const chainId = fields.get('chainId');
|
|
95
|
+
if (!chainId || !ts.isNumericLiteral(chainId)) throw new Error(`Selected network ${network} requires a static chainId`);
|
|
96
|
+
if (fields.has('zksync') && fields.get('zksync')!.kind !== ts.SyntaxKind.FalseKeyword) throw new Error('Delivery requires an EVM network');
|
|
97
|
+
const url = fields.get('url');
|
|
98
|
+
if (!url) throw new Error(`Selected network ${network} requires an RPC URL definition`);
|
|
99
|
+
return { network, chainId: positiveInteger(Number(chainId.text), 'network chainId'), url: rpcValue(url, env) ?? '' };
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
export function integratedConfig(source: string): string {
|
|
103
|
+
const { file } = parseProjectConfig(source);
|
|
104
|
+
const imports = file.statements.filter(ts.isImportDeclaration);
|
|
105
|
+
const delivery = imports.filter(node => ts.isStringLiteral(node.moduleSpecifier) && node.moduleSpecifier.text === 'gate-evm-tools/delivery-hardhat');
|
|
106
|
+
if (delivery.length > 1 || delivery.some(node => node.importClause)) throw new Error('Conflicting manual delivery plugin import');
|
|
107
|
+
// Place bootstrap before all imports, after leading comments/shebang/directives.
|
|
108
|
+
const first = file.statements.find(node => !(ts.isExpressionStatement(node) && ts.isStringLiteral(node.expression)));
|
|
109
|
+
if (!first) throw new Error('Missing project config statements');
|
|
110
|
+
if (delivery.length) {
|
|
111
|
+
if (delivery[0] !== first) throw new Error('Delivery plugin must be the first import; move it before other imports');
|
|
112
|
+
return source;
|
|
113
|
+
}
|
|
114
|
+
const at = first.getStart(file);
|
|
115
|
+
const newline = source.includes('\r\n') ? '\r\n' : '\n';
|
|
116
|
+
return source.slice(0, at) + `import "gate-evm-tools/delivery-hardhat";${newline}` + source.slice(at);
|
|
117
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/** Syntax and routing constraints only. Source verification and host authorization are separate gates. */
|
|
2
|
+
import { validateNetworkAlias } from './policy';
|
|
3
|
+
export type DeliveryEnvironment = 'dev' | 'prod';
|
|
4
|
+
export type DeliveryMode = 'simulate' | 'execute' | 'export-calldata' | 'reconcile' | 'verify';
|
|
5
|
+
export interface DeliveryRequest {
|
|
6
|
+
version: 1;
|
|
7
|
+
environment: DeliveryEnvironment;
|
|
8
|
+
purpose: 'dev-execution' | 'prod-qualification' | 'prod-execution';
|
|
9
|
+
mode: DeliveryMode;
|
|
10
|
+
network: string;
|
|
11
|
+
sourceRef: { path: string; taskId: string; planKey: string; rev: number };
|
|
12
|
+
releaseRef?: { path: string; releaseId: string; inputsHash: string };
|
|
13
|
+
fork?: { blockNumber: number; blockHash: string; readOnly: true };
|
|
14
|
+
devSigner?: string;
|
|
15
|
+
operator?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface ProjectNetworkSnapshot { network: string; chainId: number; url: string }
|
|
18
|
+
export function object(value: unknown, label: string, keys?: string[]): Record<string, unknown> {
|
|
19
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)
|
|
20
|
+
|| ![Object.prototype, null].includes(Object.getPrototypeOf(value))) throw new Error(`${label} must be an object`);
|
|
21
|
+
const result = value as Record<string, unknown>;
|
|
22
|
+
if (keys && Object.keys(result).some(key => !keys.includes(key))) throw new Error(`${label} has unknown fields`);
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
export function safeId(value: unknown, label: string): string {
|
|
26
|
+
if (typeof value !== 'string' || !/^[A-Za-z0-9][A-Za-z0-9_-]{0,199}$/.test(value)
|
|
27
|
+
|| ['__proto__', 'prototype', 'constructor'].includes(value)) throw new Error(`Invalid ${label}`);
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
export function portablePath(value: unknown, label: string): string {
|
|
31
|
+
if (typeof value !== 'string' || !value || /[\\\0:]/.test(value)
|
|
32
|
+
|| value.split('/').some(part => !part || part === '.' || part === '..'
|
|
33
|
+
|| ['__proto__', 'prototype', 'constructor'].includes(part))) throw new Error(`Invalid relative ${label}`);
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
export function address(value: unknown, label: string): string {
|
|
37
|
+
if (typeof value !== 'string' || !/^0x[\da-fA-F]{40}$/.test(value) || /^0x0{40}$/.test(value)) throw new Error(`Invalid ${label} address`);
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
export function positiveInteger(value: unknown, label: string): number {
|
|
41
|
+
if (typeof value !== 'number' || !Number.isSafeInteger(value) || value <= 0) throw new Error(`Invalid ${label}`);
|
|
42
|
+
return value;
|
|
43
|
+
}
|
|
44
|
+
export function parseDeliveryRequest(input: unknown): DeliveryRequest {
|
|
45
|
+
const value = object(input, 'delivery request', ['version', 'environment', 'purpose', 'mode', 'network', 'sourceRef', 'releaseRef', 'fork', 'devSigner', 'operator']);
|
|
46
|
+
if (value.version !== 1) throw new Error('Unsupported delivery request version');
|
|
47
|
+
if (typeof value.environment !== 'string' || !['dev', 'prod'].includes(value.environment)) throw new Error('environment must be dev or prod');
|
|
48
|
+
if (typeof value.purpose !== 'string' || !['dev-execution', 'prod-qualification', 'prod-execution'].includes(value.purpose)) throw new Error('Invalid purpose');
|
|
49
|
+
const dev = value.purpose === 'dev-execution';
|
|
50
|
+
if (value.environment !== (dev ? 'dev' : 'prod')) throw new Error('purpose conflicts with environment');
|
|
51
|
+
const modes = dev ? ['simulate', 'execute', 'reconcile', 'verify'] : value.purpose === 'prod-qualification' ? ['simulate', 'verify'] : ['simulate', 'execute', 'export-calldata', 'reconcile', 'verify'];
|
|
52
|
+
if (typeof value.mode !== 'string' || !modes.includes(value.mode)) throw new Error('Explicit valid mode is required for purpose');
|
|
53
|
+
validateNetworkAlias(value.network, 'network', false);
|
|
54
|
+
const source = object(value.sourceRef, 'sourceRef', ['path', 'taskId', 'planKey', 'rev']);
|
|
55
|
+
portablePath(source.path, 'sourceRef.path'); safeId(source.taskId, 'taskId'); safeId(source.planKey, 'planKey'); positiveInteger(source.rev, 'rev');
|
|
56
|
+
if (dev) {
|
|
57
|
+
address(value.devSigner, 'devSigner');
|
|
58
|
+
if ('operator' in value) throw new Error('devSigner and prod operator are separate roles');
|
|
59
|
+
} else {
|
|
60
|
+
address(value.operator, 'operator');
|
|
61
|
+
if ('devSigner' in value) throw new Error('prod operator cannot inherit devSigner');
|
|
62
|
+
}
|
|
63
|
+
if (value.purpose === 'prod-execution') {
|
|
64
|
+
const release = object(value.releaseRef, 'releaseRef', ['path', 'releaseId', 'inputsHash']);
|
|
65
|
+
portablePath(release.path, 'releaseRef.path'); safeId(release.releaseId, 'releaseId');
|
|
66
|
+
if (typeof release.inputsHash !== 'string' || !/^[a-f0-9]{64}$/.test(release.inputsHash)) throw new Error('Invalid releaseRef.inputsHash');
|
|
67
|
+
} else if ('releaseRef' in value) throw new Error('releaseRef requires prod-execution');
|
|
68
|
+
if (value.purpose === 'prod-qualification' && value.mode === 'simulate' && !value.fork) throw new Error('prod-qualification simulate requires a pinned read-only fork');
|
|
69
|
+
if ('fork' in value) {
|
|
70
|
+
const fork = object(value.fork, 'fork', ['blockNumber', 'blockHash', 'readOnly']);
|
|
71
|
+
if (typeof fork.blockNumber !== 'number' || !Number.isSafeInteger(fork.blockNumber) || fork.blockNumber < 0) throw new Error('Invalid fork.blockNumber');
|
|
72
|
+
if (fork.readOnly !== true || typeof fork.blockHash !== 'string' || !/^0x[\da-fA-F]{64}$/.test(fork.blockHash)) throw new Error('fork must pin a block hash and be readOnly');
|
|
73
|
+
if (value.mode !== 'simulate') throw new Error('fork is only valid for simulate mode');
|
|
74
|
+
}
|
|
75
|
+
// Return detached data so callers cannot change routing during an asynchronous provider load.
|
|
76
|
+
return JSON.parse(JSON.stringify(value)) as DeliveryRequest;
|
|
77
|
+
}
|
|
78
|
+
export interface ChainIdProvider { request(args: { method: 'eth_chainId'; params: [] }): Promise<unknown> }
|
|
79
|
+
/** Does not load HRE, signers, verify source contents, or grant execution authority. */
|
|
80
|
+
export async function validateDeliveryRpc(
|
|
81
|
+
input: unknown,
|
|
82
|
+
snapshot: ProjectNetworkSnapshot,
|
|
83
|
+
loadProvider: (snapshot: ProjectNetworkSnapshot) => Promise<ChainIdProvider>,
|
|
84
|
+
): Promise<{ request: DeliveryRequest; chainId: number }> {
|
|
85
|
+
const request = parseDeliveryRequest(input);
|
|
86
|
+
if (snapshot.network !== request.network) throw new Error('Selected project network snapshot mismatch');
|
|
87
|
+
const expected = positiveInteger(snapshot.chainId, 'snapshot.chainId');
|
|
88
|
+
const provider = await loadProvider({ ...snapshot });
|
|
89
|
+
const raw = await provider.request({ method: 'eth_chainId', params: [] });
|
|
90
|
+
if (typeof raw !== 'string' || !/^0x[\da-fA-F]+$/.test(raw)) throw new Error('Invalid RPC eth_chainId response');
|
|
91
|
+
const actual = BigInt(raw);
|
|
92
|
+
if (actual !== BigInt(expected)) throw new Error(`RPC chainId mismatch: expected ${expected}, actual ${actual}`);
|
|
93
|
+
return { request, chainId: expected };
|
|
94
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { deepFreeze, semanticHash } from "../workflow/lib/canonicalData";
|
|
2
|
+
import { strictData, ownPath } from "./data";
|
|
3
|
+
import { PUBLIC_TARGET_FIELDS } from './target-fields';
|
|
4
|
+
export const DEFERRED = Symbol("delivery.future-state");
|
|
5
|
+
export interface ReferenceObservation {
|
|
6
|
+
reference: string;
|
|
7
|
+
contentIdentity: string;
|
|
8
|
+
resolvedIdentity: string;
|
|
9
|
+
}
|
|
10
|
+
export interface BusinessReferenceContext {
|
|
11
|
+
params: unknown;
|
|
12
|
+
target: unknown;
|
|
13
|
+
state(): unknown;
|
|
14
|
+
}
|
|
15
|
+
const PUBLIC_TARGET = PUBLIC_TARGET_FIELDS;
|
|
16
|
+
export function parseBusinessReference(raw: unknown): string | null {
|
|
17
|
+
const value = strictData(raw);
|
|
18
|
+
let ref: unknown;
|
|
19
|
+
if (typeof value === "string" && value.startsWith("$")) ref = value.slice(1);
|
|
20
|
+
else if (
|
|
21
|
+
value &&
|
|
22
|
+
typeof value === "object" &&
|
|
23
|
+
!Array.isArray(value) &&
|
|
24
|
+
Object.hasOwn(value, "$ref")
|
|
25
|
+
) {
|
|
26
|
+
if (Object.keys(value).length !== 1)
|
|
27
|
+
throw new Error("Business $ref requires exact shape");
|
|
28
|
+
ref = (value as Record<string, unknown>).$ref;
|
|
29
|
+
} else return null;
|
|
30
|
+
if (
|
|
31
|
+
typeof ref !== "string" ||
|
|
32
|
+
!/^(param|target|state)\.[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)*$/.test(ref)
|
|
33
|
+
)
|
|
34
|
+
throw new Error("Invalid business reference namespace or path");
|
|
35
|
+
if (ref.startsWith("target.") && !PUBLIC_TARGET.has(ref.slice(7)))
|
|
36
|
+
throw new Error("Reference is outside public target boundary");
|
|
37
|
+
return ref;
|
|
38
|
+
}
|
|
39
|
+
export function resolveBusinessValue(
|
|
40
|
+
raw: unknown,
|
|
41
|
+
context: BusinessReferenceContext,
|
|
42
|
+
options: { deferState?: boolean } = {},
|
|
43
|
+
): { value: unknown; observations: ReferenceObservation[] } {
|
|
44
|
+
const params = strictData(context.params),
|
|
45
|
+
input = strictData(raw),
|
|
46
|
+
active = new Set<string>();
|
|
47
|
+
const observations: ReferenceObservation[] = [];
|
|
48
|
+
let state: unknown,
|
|
49
|
+
stateRead = false;
|
|
50
|
+
const visit = (value: unknown): unknown => {
|
|
51
|
+
const ref = parseBusinessReference(value);
|
|
52
|
+
if (ref) {
|
|
53
|
+
if (active.has(ref)) throw new Error(`Business reference cycle: ${ref}`);
|
|
54
|
+
const [ns, ...parts] = ref.split(".");
|
|
55
|
+
if (ns === "state" && options.deferState) return DEFERRED;
|
|
56
|
+
if (ns === "state" && !stateRead) {
|
|
57
|
+
// Runtime producers may retain unrelated optional undefined metadata.
|
|
58
|
+
// Validate the selected subtree below, never invoke descriptors on the path.
|
|
59
|
+
state = context.state();
|
|
60
|
+
stateRead = true;
|
|
61
|
+
}
|
|
62
|
+
// Read only the allowlisted target leaf; secret fields are never traversed or observed.
|
|
63
|
+
const source = strictData(
|
|
64
|
+
ownPath(
|
|
65
|
+
ns === "param" ? params : ns === "state" ? state : context.target,
|
|
66
|
+
parts,
|
|
67
|
+
ref,
|
|
68
|
+
),
|
|
69
|
+
);
|
|
70
|
+
if (ns === "target" && (source === null || typeof source === "object"))
|
|
71
|
+
throw new Error("Public target references require scalar leaves");
|
|
72
|
+
active.add(ref);
|
|
73
|
+
const resolved = visit(source);
|
|
74
|
+
active.delete(ref);
|
|
75
|
+
if (!containsDeferred(resolved))
|
|
76
|
+
observations.push({
|
|
77
|
+
reference: ref,
|
|
78
|
+
contentIdentity: semanticHash(source),
|
|
79
|
+
resolvedIdentity: semanticHash(resolved),
|
|
80
|
+
});
|
|
81
|
+
return resolved;
|
|
82
|
+
}
|
|
83
|
+
if (Array.isArray(value)) return value.map(visit);
|
|
84
|
+
if (value && typeof value === "object")
|
|
85
|
+
return Object.fromEntries(
|
|
86
|
+
Object.entries(value).map(([k, v]) => [k, visit(v)]),
|
|
87
|
+
);
|
|
88
|
+
return value;
|
|
89
|
+
};
|
|
90
|
+
return deepFreeze({
|
|
91
|
+
value: visit(input),
|
|
92
|
+
observations: observations.sort((a, b) =>
|
|
93
|
+
a.reference < b.reference ? -1 : a.reference > b.reference ? 1 : 0,
|
|
94
|
+
),
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
export function containsDeferred(value: unknown): boolean {
|
|
98
|
+
return (
|
|
99
|
+
value === DEFERRED ||
|
|
100
|
+
!!(
|
|
101
|
+
value &&
|
|
102
|
+
typeof value === "object" &&
|
|
103
|
+
Object.values(value).some(containsDeferred)
|
|
104
|
+
)
|
|
105
|
+
);
|
|
106
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/** Actual-file release graph classification. No caller-selected roots or target subsets. */
|
|
2
|
+
import {parseCanonicalPlan,projectCanonicalDefinitions} from './source';
|
|
3
|
+
import {projectRoot} from './project-files';
|
|
4
|
+
import {readInputBytes,parseInputDocument,assertUnambiguousHandoff} from './input-files';
|
|
5
|
+
import {canonicalJson,deepFreeze,semanticHash,exactObject} from '../workflow/lib/canonicalData';
|
|
6
|
+
import {safeId,portablePath} from './protocol';
|
|
7
|
+
export interface ReleaseGraphOptions {workspaceRoot:string;projectRoot:string;handoff:string;taskId:string;deploymentId:string;releaseRef:{path:string;releaseId:string;inputsHash:string}}
|
|
8
|
+
export const sameReleaseData=(a:unknown,b:unknown,label:string):void=>{if(canonicalJson(a)!==canonicalJson(b))throw Error(`${label} mismatch`);};
|
|
9
|
+
const stages=['release-prepare','release-execute','release-verify'];
|
|
10
|
+
export function readReleaseUniverse(input:Omit<ReleaseGraphOptions,'releaseRef'>){
|
|
11
|
+
const workspace=projectRoot(input.workspaceRoot,'.'),root=projectRoot(workspace,input.projectRoot);
|
|
12
|
+
safeId(input.deploymentId,'deploymentId');portablePath(input.handoff,'handoff');
|
|
13
|
+
const text=readInputBytes(workspace,input.handoff).toString();assertUnambiguousHandoff(text);
|
|
14
|
+
const plan=parseCanonicalPlan(text);if(plan.taskId!==input.taskId)throw Error('Current task identity mismatch');
|
|
15
|
+
const task=exactObject(parseInputDocument(readInputBytes(root,`scripts/tasks/${input.deploymentId}/task.yaml`),'yaml'),['version','id','developmentNetwork','releaseTargetNetworks'],'task.yaml');
|
|
16
|
+
if(task.version!==1||task.id!==input.deploymentId||!Array.isArray(task.releaseTargetNetworks)||!task.releaseTargetNetworks.length)throw Error('Invalid release target scope');
|
|
17
|
+
const targets=task.releaseTargetNetworks as string[];if(new Set(targets).size!==targets.length)throw Error('Duplicate release target');
|
|
18
|
+
const entries=Object.entries(plan.tasks).flatMap(([lane,tasks])=>tasks.map(task=>({lane,task}))),relevant=entries.filter(({task:t})=>{const d=t.scope?.deployment as any;return d?.projectRoot===input.projectRoot&&d?.deploymentId===input.deploymentId;});
|
|
19
|
+
for(const {task:t} of relevant){const d=t.scope!.deployment as any;sameReleaseData(d.developmentNetwork,task.developmentNetwork,'Current development target');sameReleaseData(d.releaseTargetNetworks,targets,'Current selected targets');}
|
|
20
|
+
const qualifications=targets.map(target=>{const rows=relevant.filter(({task:t})=>t.step==='deploy-test'&&(t.scope!.deployment as any).targetNetwork===target);if(rows.length!==1)throw Error('Missing or ambiguous qualification target');const row=rows[0],d=row.task.scope!.deployment as any;if(plan.lanes[row.lane].state!=='enabled'||row.task.status==='cancelled'||d.environment!=='prod'||d.releaseRef!==undefined)throw Error('Ineligible qualification task');sameReleaseData(d.allowedActions,['simulate','verify'],'Qualification allowedActions');return row.task;});
|
|
21
|
+
if(relevant.some(({task:t})=>t.step==='deploy-test'&&!targets.includes((t.scope!.deployment as any).targetNetwork)))throw Error('Unknown qualification target');
|
|
22
|
+
const upstream=projectCanonicalDefinitions(text,{roots:qualifications.map(t=>t.planKey),mode:'upstream'});
|
|
23
|
+
return {workspace,root,text,plan,entries,relevant,targets,qualifications,upstream,developmentNetwork:task.developmentNetwork as string};
|
|
24
|
+
}
|
|
25
|
+
export function readReleaseGraph(input:ReleaseGraphOptions){
|
|
26
|
+
const u=readReleaseUniverse(input);safeId(input.releaseRef.releaseId,'releaseId');portablePath(input.releaseRef.path,'releaseRef.path');if(!/^[a-f0-9]{64}$/.test(input.releaseRef.inputsHash))throw Error('Invalid release input hash');
|
|
27
|
+
// Classify ALL relevant production tasks first. Filtering a good ref first conceals split/wrong bindings.
|
|
28
|
+
const groups=new Map<string,typeof u.relevant>();
|
|
29
|
+
for(const row of u.relevant.filter(({task})=>stages.includes(task.step??''))){const d=row.task.scope!.deployment as any,ref=d.releaseRef;if(!ref)throw Error('Missing release binding');const key=canonicalJson(ref),rows=groups.get(key)??[];rows.push(row);groups.set(key,rows);}
|
|
30
|
+
const selectedKey=canonicalJson(input.releaseRef);
|
|
31
|
+
for(const [key,rows] of groups){const ref=(rows[0].task.scope!.deployment as any).releaseRef;if(ref.releaseId===input.releaseRef.releaseId&&key!==selectedKey)throw Error('Split release binding');
|
|
32
|
+
if(rows.length!==u.targets.length*3)throw Error('Incomplete or duplicate production stage graph');
|
|
33
|
+
for(const target of u.targets){const chain=stages.map(step=>{const matches=rows.filter(({task})=>task.step===step&&(task.scope!.deployment as any).targetNetwork===target);if(matches.length!==1)throw Error('Missing or duplicate release stage');return matches[0];});
|
|
34
|
+
for(const [index,{lane,task}] of chain.entries()){const d=task.scope!.deployment as any;if(u.plan.lanes[lane].state!=='enabled'||task.status==='cancelled'||d.environment!=='prod')throw Error('Ineligible production task');const required=index===0?u.qualifications.find(t=>(t.scope!.deployment as any).targetNetwork===target)!.planKey:chain[index-1].task.planKey;if(!task.dependsOn.includes(required))throw Error('Split release dependency graph');const allowed=index===0?['simulate']:index===1?['execute','export-calldata','reconcile']:['verify'];sameReleaseData(d.allowedActions,allowed,'Release allowedActions');}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const selected=groups.get(selectedKey);if(!selected)throw Error('Missing complete release graph');
|
|
38
|
+
const graph=projectCanonicalDefinitions(u.text,{roots:selected.map(r=>r.task.planKey),mode:'full'});
|
|
39
|
+
return deepFreeze({targets:u.targets,graph:graph.snapshot,prodTaskGraphHash:semanticHash(graph.snapshot)});
|
|
40
|
+
}
|
|
41
|
+
/** Progress is deliberately outside sourceDefinitionHash: eligibility is checked anew. */
|
|
42
|
+
export function currentReleasePrerequisites(input:Omit<ReleaseGraphOptions,'releaseRef'>){
|
|
43
|
+
const u=readReleaseUniverse(input),keys=new Set(u.upstream.snapshot.tasks.map(t=>t.planKey)),qual=new Set(u.qualifications.map(t=>t.planKey));
|
|
44
|
+
const required=u.entries.filter(({lane,task})=>keys.has(task.planKey)&&!qual.has(task.planKey)&&u.plan.lanes[lane].state==='enabled');
|
|
45
|
+
for(const row of u.entries){if(['development','audit'].includes(row.lane)&&u.plan.lanes[row.lane].state==='enabled'&&!keys.has(row.task.planKey))throw Error('Mandatory prerequisite missing from current closure');}
|
|
46
|
+
for(const step of ['deploy','check-code'])if(!required.some(r=>r.task.step===step))throw Error(`Missing development acceptance prerequisite: ${step}`);
|
|
47
|
+
for(const {task} of required)if(task.status!=='completed'||task.result?.kind!=='success'||task.adoptedRev!==task.rev)throw Error(`Current prerequisite is incomplete or stale: ${task.planKey}`);
|
|
48
|
+
return {...u,required};
|
|
49
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** Narrow R1→R2 handoff: capture the currently installed producer and changing containers BEFORE prod edits. */
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import {gzipSync} from 'node:zlib';
|
|
5
|
+
import {readInputBytes} from './input-files';
|
|
6
|
+
import {confinedFile,projectRoot} from './project-files';
|
|
7
|
+
import {atomicDevelopmentWrite,byteHash,developmentPath} from './materialization';
|
|
8
|
+
import {canonicalJson,semanticHash} from '../workflow/lib/canonicalData';
|
|
9
|
+
import {parseDeliveryPlan} from './plan';
|
|
10
|
+
import {safeId} from './protocol';
|
|
11
|
+
import type {DeliveryAggregate,DeliveryAggregateOptions} from './aggregate';
|
|
12
|
+
import type {HistoricalDevelopmentFiles} from './release-history';
|
|
13
|
+
export function captureDevelopmentReleaseHistory(input:{root:string;source:DeliveryAggregateOptions;aggregate:DeliveryAggregate}):HistoricalDevelopmentFiles {
|
|
14
|
+
const root=fs.realpathSync(input.root),a=input.aggregate,plan=parseDeliveryPlan(a.collections[0]?.plan);
|
|
15
|
+
if(input.source.selection!=='development'||a.collections.length!==1||plan.environment!=='dev'||projectRoot(input.source.workspaceRoot,input.source.projectRoot)!==root)throw Error('Historical capture requires original development source');
|
|
16
|
+
safeId(plan.executionId,'executionId');
|
|
17
|
+
const base=`.gate-delivery/history/${plan.executionId}`,readyPath=`${base}/READY.json`;
|
|
18
|
+
const acceptanceFile=`.gate-delivery/development/${plan.executionId}.acceptance.json`,acceptance=JSON.parse(readInputBytes(root,acceptanceFile).toString());
|
|
19
|
+
if(acceptance.status!=='accepted'||acceptance.planHash!==plan.planHash||acceptance.inputsHash!==a.inputsHash||semanticHash(acceptance.runtimeIdentity)!==semanticHash(plan.runtimeIdentity))throw Error('Historical capture requires actual accepted development');
|
|
20
|
+
const original=a.inputs.runtime.package;if(original.name!=='gate-evm-tools'||original.lockLocation!=='node_modules/gate-evm-tools')throw Error('Unsupported historical producer location');
|
|
21
|
+
const files:Array<{path:string;digest:string;base64:string}>=[];
|
|
22
|
+
const visit=(relative:string)=>{const dir=confinedFile(root,`${original.lockLocation}/${relative}`.replace(/\/$/,''),'directory');for(const name of fs.readdirSync(dir).sort()){const rel=relative?`${relative}/${name}`:name;const stat=fs.lstatSync(path.join(dir,name));if(stat.isDirectory()){if(name==='node_modules')continue;visit(rel);}else{const bytes=readInputBytes(root,`${original.lockLocation}/${rel}`);files.push({path:rel,digest:byteHash(bytes),base64:bytes.toString('base64')});}}};visit('');files.sort((a,b)=>a.path<b.path?-1:a.path>b.path?1:0);
|
|
23
|
+
if(semanticHash(files.map(({path,digest})=>({path,digest})))!==semanticHash(original.payload))throw Error('Historical capture must precede producer/runtime replacement');
|
|
24
|
+
const descriptor:HistoricalDevelopmentFiles={aggregateFile:`${base}/aggregate.json`,sourceFile:`${base}/source.json`,acceptanceFile,packageRoot:`${base}/package`,inputsRoot:`${base}/inputs`,archiveFile:`${base}/package.snapshot.json.gz`};
|
|
25
|
+
if(fs.existsSync(developmentPath(root,readyPath))){const ready=JSON.parse(readInputBytes(root,readyPath).toString());if(ready.schema!=='gate-delivery-history-ready'||ready.generation!=='complete'||ready.planHash!==plan.planHash||ready.aggregateHash!==semanticHash(a))throw Error('Conflicting historical capture');for(const f of ready.files)if(byteHash(readInputBytes(root,f.path))!==f.sha256)throw Error('Captured historical file drift');return descriptor;}
|
|
26
|
+
const saved:Array<{path:string;sha256:string}>=[];
|
|
27
|
+
const write=(relative:string,bytes:Buffer)=>{const file=developmentPath(root,relative);fs.mkdirSync(path.dirname(file),{recursive:true,mode:0o700});if(fs.existsSync(file)&&!readInputBytes(root,relative).equals(bytes))throw Error('Partial historical capture conflict');const fd=fs.openSync(file,'w',0o600);try{fs.writeFileSync(fd,bytes);fs.fsyncSync(fd);}finally{fs.closeSync(fd);}saved.push({path:relative,sha256:byteHash(bytes)});};
|
|
28
|
+
for(const file of files)write(`${base}/package/${file.path}`,Buffer.from(file.base64,'base64'));
|
|
29
|
+
for(const name of [`${a.inputs.business.businessRoot}/task.yaml`,`${a.inputs.business.businessRoot}/parameters.yaml`,`${a.inputs.business.businessRoot}/parameters.provenance.json`,'config.yaml','hardhat.config.ts','package-lock.json','contractInfo.json','deploymentInfo.json'])write(`${base}/inputs/${name}`,readInputBytes(root,name));
|
|
30
|
+
write(descriptor.aggregateFile,Buffer.from(canonicalJson(a)+'\n'));write(descriptor.sourceFile,Buffer.from(canonicalJson(input.source)+'\n'));write(descriptor.archiveFile,gzipSync(Buffer.from(canonicalJson({schema:'gate-delivery-package-snapshot',version:1,runtimeIdentity:plan.runtimeIdentity,observedPackage:original,files}))));
|
|
31
|
+
atomicDevelopmentWrite(root,readyPath,canonicalJson({schema:'gate-delivery-history-ready',version:1,generation:'complete',planHash:plan.planHash,aggregateHash:semanticHash(a),descriptor,files:saved})+'\n');return descriptor;
|
|
32
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/** Read-only consumption of R1 evidence. Historical runtime is verified, never executed or relabelled. */
|
|
2
|
+
import {existingCodeCoverage,requiredExistingAddresses} from './existing-code';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import {createHash} from 'node:crypto';
|
|
6
|
+
import {gzipSync,gunzipSync} from 'node:zlib';
|
|
7
|
+
import {Contract,JsonRpcProvider} from 'ethers';
|
|
8
|
+
import {readInputBytes,inputDigest,parseInputDocument} from './input-files';
|
|
9
|
+
import {confinedFile,projectRoot} from './project-files';
|
|
10
|
+
import {parseCanonicalPlan,projectCanonicalDefinitions} from './source';
|
|
11
|
+
import {parseConfigurationDefinition} from './configuration-definition';
|
|
12
|
+
import {parseDeliveryPublicTargets} from './config';
|
|
13
|
+
import {readProjectNetworkSnapshots} from './project';
|
|
14
|
+
import {parseDeliveryPlan} from './plan';
|
|
15
|
+
import {parsePreparationJournal} from './journal';
|
|
16
|
+
import {expectedDevelopmentAssertions} from './development';
|
|
17
|
+
import {parseObservation} from './observations';
|
|
18
|
+
import {observeEoaTransaction} from './eoa-observation';
|
|
19
|
+
import {parseVerificationObservation} from './verification';
|
|
20
|
+
import {compareAbiResults} from './abi';
|
|
21
|
+
import {parseTypedValue} from '../workflow/lib/typedValue';
|
|
22
|
+
import {canonicalJson,deepFreeze,semanticHash} from '../workflow/lib/canonicalData';
|
|
23
|
+
import {readDevelopmentJournal,byteHash} from './materialization';
|
|
24
|
+
import {validateDevelopmentCheckReport,type ExpectedDevelopmentCode} from './check-code';
|
|
25
|
+
import {sameReleaseData as same} from './release-graph';
|
|
26
|
+
import type {DeliveryAggregate,DeliveryAggregateOptions} from './aggregate';
|
|
27
|
+
import {historicalRegistrationFile,validateHistoricalRegistration} from './history-registration';
|
|
28
|
+
export interface HistoricalDevelopmentFiles {aggregateFile:string;sourceFile:string;acceptanceFile:string;packageRoot:string;inputsRoot:string;archiveFile:string}
|
|
29
|
+
export function aggregateInputHash(a:DeliveryAggregate){return semanticHash({version:1,business:a.inputs.business,sourceDefinitions:a.inputs.sourceDefinitions,runtime:a.inputs.runtime,files:a.inputs.files,targets:a.inputs.targets.map(r=>({target:r.target,configuration:r.configuration.configurationRuntimeHash,sourceConfiguration:r.sourceConfiguration.configurationRuntimeHash,compiler:r.compiler.stableDigest,custom:r.custom}))});}
|
|
30
|
+
function decode(raw:any):any{const v=parseTypedValue(raw);switch(v.type){case 'bigint':return BigInt(v.value);case 'number':return Number(v.value);case 'array':return v.value.map(decode);case 'object':return Object.fromEntries(Object.entries(v.value).map(([k,x])=>[k,decode(x)]));default:return v.value;}}
|
|
31
|
+
/** Every mutable historical container is retained with its ORIGINAL digest; allowed deltas are explicit. */
|
|
32
|
+
export function validateHistoricalDevelopmentFiles(input:{root:string;workspaceRoot:string;projectRoot:string;history:HistoricalDevelopmentFiles}){
|
|
33
|
+
const workspace=projectRoot(input.workspaceRoot,'.'),root=projectRoot(workspace,input.projectRoot),{history}=input,files=new Map<string,string>();
|
|
34
|
+
if(fs.realpathSync(input.root)!==root)throw Error('Historical current project root mismatch');
|
|
35
|
+
const read=(relative:string)=>{const bytes=readInputBytes(root,relative);files.set(relative,inputDigest(bytes));return bytes;};
|
|
36
|
+
const aggregate=JSON.parse(read(history.aggregateFile).toString()) as DeliveryAggregate,source=JSON.parse(read(history.sourceFile).toString()) as DeliveryAggregateOptions,acceptance=JSON.parse(read(history.acceptanceFile).toString());
|
|
37
|
+
if(source.projectRoot!==input.projectRoot)throw Error('Historical relative project scope mismatch');
|
|
38
|
+
if(source.selection!=='development'||source.targets.length!==1||aggregate.collections.length!==1||aggregate.inputs.business.targets.length!==1)throw Error('Historical development scope mismatch');
|
|
39
|
+
same(aggregateInputHash(aggregate),aggregate.inputsHash,'Historical aggregate inputs');same(semanticHash(aggregate.inputs.sourceDefinitions),aggregate.sourceDefinitionHash,'Historical source hash');
|
|
40
|
+
const collection=aggregate.collections[0],plan=parseDeliveryPlan(collection.plan),target=aggregate.inputs.business.targets[0];
|
|
41
|
+
if(plan.environment!=='dev'||plan.target!==target.id||source.targets[0].request.network!==plan.target||source.targets[0].executionId!==plan.executionId)throw Error('Historical development identity mismatch');
|
|
42
|
+
for(const key of ['executionId','planHash','target','inputsHash','sourceDefinitionHash','runtimeIdentity'] as const)same(acceptance[key],plan[key],`Historical acceptance ${key}`);
|
|
43
|
+
if(acceptance.version!==1||acceptance.status!=='accepted')throw Error('Missing historical acceptance');
|
|
44
|
+
const readyPath=path.posix.dirname(history.aggregateFile)+'/READY.json',ready=JSON.parse(read(readyPath).toString());
|
|
45
|
+
if(ready.schema!=='gate-delivery-history-ready'||ready.version!==1||ready.generation!=='complete'||ready.planHash!==plan.planHash||ready.aggregateHash!==semanticHash(aggregate)||!Array.isArray(ready.files)||!ready.files.length)throw Error('Historical snapshot generation is not READY');
|
|
46
|
+
same(ready.descriptor,history,'Historical READY descriptor');for(const file of ready.files)if(byteHash(read(file.path))!==file.sha256)throw Error('Historical READY file binding mismatch');
|
|
47
|
+
const original=aggregate.inputs.runtime.package;
|
|
48
|
+
same(aggregate.inputs.runtime.declared,plan.runtimeIdentity,'Historical runtime identity');
|
|
49
|
+
if(original.name!=='gate-evm-tools'||original.version!==plan.runtimeIdentity.version||original.source.identity!==original.integrity)throw Error('Historical producer provenance mismatch');
|
|
50
|
+
const archive=read(history.archiveFile),snapshot=JSON.parse(gunzipSync(archive).toString());
|
|
51
|
+
if(snapshot.schema!=='gate-delivery-package-snapshot'||snapshot.version!==1||!Array.isArray(snapshot.files))throw Error('Invalid historical package snapshot archive');
|
|
52
|
+
const archived=snapshot.files.map((f:any)=>{const bytes=Buffer.from(f.base64,'base64');if(bytes.toString('base64')!==f.base64||byteHash(bytes)!==f.digest)throw Error('Historical snapshot archive bytes mismatch');return {path:f.path,digest:f.digest};});
|
|
53
|
+
same(archived,original.payload,'Historical archive complete payload');same(snapshot.observedPackage,original,'Historical snapshot provenance');same(snapshot.runtimeIdentity,plan.runtimeIdentity,'Historical snapshot runtime');
|
|
54
|
+
const payload:Array<{path:string;digest:string}>=[];
|
|
55
|
+
const visit=(relative:string)=>{const dir=confinedFile(root,`${history.packageRoot}/${relative}`.replace(/\/$/,''),'directory');for(const name of fs.readdirSync(dir).sort()){if(name==='node_modules')throw Error('Historical producer nested package unsupported');const rel=relative?`${relative}/${name}`:name,p=confinedFile(root,`${history.packageRoot}/${rel}`,fs.lstatSync(path.join(dir,name)).isDirectory()?'directory':'file');if(fs.lstatSync(p).isDirectory())visit(rel);else payload.push({path:rel,digest:inputDigest(read(`${history.packageRoot}/${rel}`))});}};
|
|
56
|
+
visit('');payload.sort((a,b)=>a.path<b.path?-1:a.path>b.path?1:0);same(payload,original.payload,'Historical producer actual payload');same(byteHash(payload.map(f=>`${f.path}\0${f.digest}\n`).join('')),original.payloadDigest,'Historical payload digest');
|
|
57
|
+
const digest=createHash('sha256');const hashDir=(dir:string)=>{for(const name of fs.readdirSync(confinedFile(root,`${history.packageRoot}/${dir}`,'directory')).sort()){const rel=`${dir}/${name}`,file=confinedFile(root,`${history.packageRoot}/${rel}`,fs.lstatSync(path.join(root,history.packageRoot,rel)).isDirectory()?'directory':'file');if(fs.lstatSync(file).isDirectory())hashDir(rel);else if(/\.(?:c?js)$/.test(rel)){digest.update(rel);digest.update(read(`${history.packageRoot}/${rel}`));}}};for(const dir of ['dist-runtime','dist','dist-cjs','bin'])hashDir(dir);same(digest.digest('hex'),plan.runtimeIdentity.digest,'Historical executable runtime digest');
|
|
58
|
+
const business=aggregate.inputs.business.businessRoot,mutable=new Set([`${business}/task.yaml`,`${business}/parameters.yaml`,`${business}/parameters.provenance.json`,'config.yaml','hardhat.config.ts']);
|
|
59
|
+
const old=(file:string)=>read(`${history.inputsRoot}/${file}`),now=(file:string)=>read(file);
|
|
60
|
+
const ownPayload=new Set(original.payload.map(file=>`${original.lockLocation}/${file.path}`));
|
|
61
|
+
// The entire old frozen file union is verified. Only owned producer bytes and bounded containers have historical locations.
|
|
62
|
+
for(const file of aggregate.inputs.files){const bytes=ownPayload.has(file.path)?read(`${history.packageRoot}/${file.path.slice(original.lockLocation.length+1)}`):mutable.has(file.path)?old(file.path):now(file.path);if(inputDigest(bytes)!==file.digest)throw Error(`Historical immutable input drift: ${file.path}`);}
|
|
63
|
+
const oldTask=parseInputDocument(old(`${business}/task.yaml`),'yaml') as any,newTask=parseInputDocument(now(`${business}/task.yaml`),'yaml') as any;
|
|
64
|
+
same({...newTask,releaseTargetNetworks:oldTask.releaseTargetNetworks},oldTask,'Historical development task container');
|
|
65
|
+
if(!Array.isArray(newTask.releaseTargetNetworks)||oldTask.releaseTargetNetworks.some((x:string)=>!newTask.releaseTargetNetworks.includes(x)))throw Error('Historical production target removal');
|
|
66
|
+
const prod=new Set<string>(newTask.releaseTargetNetworks);
|
|
67
|
+
for(const file of ['parameters.yaml','parameters.provenance.json']){const before=parseInputDocument(old(`${business}/${file}`),file.endsWith('.json')?'json':'yaml') as any,after=parseInputDocument(now(`${business}/${file}`),file.endsWith('.json')?'json':'yaml') as any;const container=file==='parameters.yaml'?'params':'targets';const projection=(value:any)=>({...value,[container]:Object.fromEntries(Object.entries(value[container]).filter(([k])=>!prod.has(k)))});same(projection(after),projection(before),'Historical dev parameter values/provenance');}
|
|
68
|
+
const oldConfig=parseInputDocument(old('config.yaml'),'yaml') as any,newConfig=parseInputDocument(now('config.yaml'),'yaml') as any;
|
|
69
|
+
same(Object.fromEntries(Object.entries(newConfig).filter(([k])=>!prod.has(k))),Object.fromEntries(Object.entries(oldConfig).filter(([k])=>!prod.has(k))),'Historical development configuration');
|
|
70
|
+
const previous=parseConfigurationDefinition(old('hardhat.config.ts'),plan.target).definition,current=parseConfigurationDefinition(now('hardhat.config.ts'),plan.target).definition;
|
|
71
|
+
// Existing Hardhat networks remain identical; only newly selected production aliases may be added.
|
|
72
|
+
for(const [name,value] of Object.entries(previous.networks))same(current.networks[name],value,'Historical effective network');
|
|
73
|
+
if(Object.keys(current.networks).some(k=>!Object.hasOwn(previous.networks,k)&&!prod.has(k)))throw Error('Unknown added historical network');
|
|
74
|
+
same({...current,networks:previous.networks},previous,'Historical compiler/plugins/configuration');
|
|
75
|
+
same(parseDeliveryPublicTargets(now('config.yaml'),now('hardhat.config.ts'),[{network:plan.target,environment:'dev'}])[0],target,'Historical public dev target');
|
|
76
|
+
// A custom script reading a whole changed container makes the relaxed projection unsafe.
|
|
77
|
+
const dependencyFiles=[...aggregate.inputs.targets.flatMap(t=>t.custom?.files??[]),...aggregate.inputs.business.parameters.flatMap(p=>p.closure?.files??[])];
|
|
78
|
+
for(const file of dependencyFiles)if(inputDigest(now(file.path))!==file.digest)throw Error('Historical custom/producer dependency changed');
|
|
79
|
+
const handoff=source.targets[0].request.sourceRef.path,text=readInputBytes(workspace,handoff).toString(),actual=parseCanonicalPlan(text);if(actual.taskId!==source.targets[0].request.sourceRef.taskId)throw Error('Historical task source identity mismatch');
|
|
80
|
+
const projection=projectCanonicalDefinitions(text,{roots:[source.targets[0].request.sourceRef.planKey],mode:'upstream'}).snapshot;
|
|
81
|
+
const normalize=(v:any)=>{const copy=JSON.parse(canonicalJson(v));for(const t of copy.tasks)if(t.scope?.deployment)t.scope.deployment.releaseTargetNetworks=oldTask.releaseTargetNetworks;return copy;};
|
|
82
|
+
const historical=(aggregate.inputs.sourceDefinitions as any[]);if(historical.length!==1||historical[0].path!==handoff)throw Error('Historical source document mismatch');same(normalize(projection),historical[0].definition,'Historical upstream definition with bounded prod expansion');
|
|
83
|
+
const expected=expectedDevelopmentAssertions(collection,aggregate.inputs.business.steps);
|
|
84
|
+
if(!Array.isArray(acceptance.assertions)||acceptance.assertions.length!==expected.length)throw Error('Missing development business assertions');
|
|
85
|
+
for(const [index,raw] of acceptance.assertions.entries()){const assertion=parseVerificationObservation(raw);same({...assertion,actual:expected[index].actual},expected[index],'Historical complete typed assertion');const comparable=compareAbiResults(assertion.abi,assertion.method,decode(assertion.actual),decode(assertion.expected));if(comparable.actual!==comparable.expected)throw Error('Historical business assertion failed');}
|
|
86
|
+
const preparations=parsePreparationJournal(collection.preparations,plan.transactions,plan.derivedBindings,{target:plan.target,chainId:plan.chainId,expectedStepIds:plan.deploymentBindings.map(b=>b.stepId)});
|
|
87
|
+
if(!plan.transactions.length||!Array.isArray(acceptance.finalized)||acceptance.finalized.length!==plan.transactions.length)throw Error('Missing finalized development transactions');
|
|
88
|
+
const finalized=acceptance.finalized.map((v:any,index:number)=>parseObservation(v,plan,index));if(finalized.some((v:any)=>v.state!=='finalized-success')||new Set(finalized.map((v:any)=>v.transactionHash)).size!==finalized.length)throw Error('Invalid finalized development evidence');
|
|
89
|
+
const journal=readDevelopmentJournal(root,plan.executionId);if(!journal||journal.state!=='committed'||journal.identity!==acceptance.identity||journal.intentHash!==acceptance.materialization?.intentHash)throw Error('Missing committed development materialization');
|
|
90
|
+
read(`.gate-delivery/materialization/${plan.executionId}.json`);
|
|
91
|
+
const historicalRegistration=(name:string)=>{
|
|
92
|
+
const entry=journal.files.find((f:any)=>f.path===name);if(!entry)throw Error('Historical registration baseline missing');
|
|
93
|
+
// The original committed journal and accepted raw report bind these exact baseline bytes.
|
|
94
|
+
validateHistoricalRegistration(name,entry.after,readInputBytes(root,name).toString(),[...prod]);
|
|
95
|
+
const captured=`${history.inputsRoot}/${name}`;
|
|
96
|
+
if(fs.existsSync(path.join(root,captured))&&read(captured).toString()!==entry.after)throw Error('Historical captured registration differs from accepted baseline');
|
|
97
|
+
files.set(name,inputDigest(Buffer.from(entry.after)));return Buffer.from(entry.after);
|
|
98
|
+
};
|
|
99
|
+
for(const file of journal.files)if(byteHash(historicalRegistrationFile(file.path)?historicalRegistration(file.path):now(file.path))!==file.afterHash)throw Error('Current development materialization mismatch');
|
|
100
|
+
const record=JSON.parse(now(acceptance.materialization.recordPath).toString());
|
|
101
|
+
for(const [key,value] of Object.entries({identity:acceptance.identity,executionId:plan.executionId,planHash:plan.planHash,inputsHash:plan.inputsHash,sourceDefinitionHash:plan.sourceDefinitionHash,runtimeIdentity:plan.runtimeIdentity,preparations,finalized,assertions:acceptance.assertions}))same(record[key],value,`Historical deployment record ${key}`);
|
|
102
|
+
if(!Array.isArray(record.changes))throw Error('Missing development registry changes');
|
|
103
|
+
const expectedCode:ExpectedDevelopmentCode[]=[],effective:any={[plan.target]:{}};
|
|
104
|
+
for(const change of record.changes){effective[plan.target][change.contractInfoKey]=change.address;const key=change.contractInfoKey.split(':')[0];expectedCode.push({key,contract:change.actualContract,address:change.implementationAddress??change.address});if(change.proxyKind==='uups')expectedCode.push({key:`${key}_Proxy`,contract:'ERC1967Proxy',address:change.address});}
|
|
105
|
+
const pure=!preparations.length?existingCodeCoverage({target:plan.target,addresses:requiredExistingAddresses(collection),registry:JSON.parse(historicalRegistration('contractInfo.json').toString()),metadata:JSON.parse(historicalRegistration('deploymentInfo.json').toString()),compiler:aggregate.inputs.targets.find(t=>t.target===plan.target)!.compiler,manifests:(acceptance.materialization.manifests??[]).map((m:any)=>({path:m.file,contents:now(m.file).toString()}))}):null;
|
|
106
|
+
if(pure){if(record.changes.length)throw Error('Pure-call history cannot invent deployment changes');Object.assign(effective,pure.effective);expectedCode.push(...pure.expected);same(acceptance.materialization.manifests,pure.manifests,'Historical existing manifests');}
|
|
107
|
+
const code=acceptance.checkCode;if(code?.version!==1||code.executionId!==plan.executionId||code.planHash!==plan.planHash||code.target!==plan.target||typeof code.rawFile!=='string'||!code.rawFile.startsWith(`.gate-delivery/check-code/${plan.executionId}/`))throw Error('Missing real CheckCode identity');
|
|
108
|
+
same(byteHash(historicalRegistration('contractInfo.json')),code.registryHash,'Historical registry');same(byteHash(historicalRegistration('deploymentInfo.json')),code.metadataHash,'Historical deployment metadata');same(byteHash(canonicalJson(effective)+'\n'),code.effectiveHash,'Historical CheckCode effective registry');
|
|
109
|
+
const raw=now(code.rawFile);same(byteHash(raw),code.rawHash,'Historical real raw CheckCode');validateDevelopmentCheckReport(JSON.parse(raw.toString()),plan.target,expectedCode);same(code.artifacts,pure?.artifacts??preparations.map(p=>p.prepared.plan.artifact),'Historical CheckCode artifacts');
|
|
110
|
+
const manifests=acceptance.materialization.manifests;if(!Array.isArray(manifests)||record.changes.some((c:any)=>c.proxyKind==='uups')&&!manifests.length)throw Error('Missing official manifest evidence');for(const m of manifests)same(byteHash(now(m.file)),m.hash,'Historical official manifest');
|
|
111
|
+
return deepFreeze({aggregate,source,acceptance,plan,files:[...files].map(([path,digest])=>({path,digest})),association:{version:1,historicalInputsHash:aggregate.inputsHash,historicalRuntime:plan.runtimeIdentity,historicalSnapshotSha256:byteHash(archive),observedLockIntegrity:original.integrity,installation:'owned-installed-payload-snapshot@1',developmentTarget:plan.target,oldProductionTargets:oldTask.releaseTargetNetworks,currentProductionTargets:newTask.releaseTargetNetworks,rule:'dev-preserving-prod-container-extension@1'}});
|
|
112
|
+
}
|
|
113
|
+
/** Actual read-only receipts and business state. No signing, compilation, mutation or old-runtime execution. */
|
|
114
|
+
export async function verifyHistoricalDevelopmentChain(result:ReturnType<typeof validateHistoricalDevelopmentFiles>,root:string){
|
|
115
|
+
const {plan,acceptance,aggregate}=result,snapshot=readProjectNetworkSnapshots(root,[plan.target])[0],provider=new JsonRpcProvider(snapshot.url,undefined,{staticNetwork:false});
|
|
116
|
+
try{const rpc={request:(method:string,params:readonly unknown[])=>provider.send(method,[...params])};const context={executionId:plan.executionId,planHash:plan.planHash,releaseHash:plan.inputsHash,operator:plan.operator,policyHash:semanticHash({historical:true}),chainId:plan.chainId,target:plan.target,finality:{kind:'confirmations' as const,depth:String(Math.max(1,aggregate.inputs.business.targets[0].finality.confirmations))}};
|
|
117
|
+
for(const [index,observation] of acceptance.finalized.entries())same(await observeEoaTransaction({plan,context,provider:rpc,index,transactionHash:observation.transactionHash}),observation,'Current historical finalized receipt');
|
|
118
|
+
for(const assertion of acceptance.assertions){const contract=new Contract(assertion.address,assertion.abi,provider),actual=await contract.getFunction(assertion.method).staticCall(...decode(assertion.args)),comparison=compareAbiResults(assertion.abi,assertion.method,actual,decode(assertion.expected));if(comparison.actual!==comparison.expected)throw Error('Current historical development business assertion failed');}
|
|
119
|
+
}finally{provider.destroy();}
|
|
120
|
+
}
|