gate-evm-tools 1.0.31 → 1.2.0
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 +34 -20
- package/bin/cli.js +3 -0
- package/bin/delivery.cjs +8 -7
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +26 -2
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/plan/index.d.ts.map +1 -1
- package/dist/commands/plan/index.js +1 -1
- package/dist/commands/plan/index.js.map +1 -1
- package/dist/core/preparation/batch.d.ts +26 -0
- package/dist/core/preparation/batch.d.ts.map +1 -0
- package/dist/core/preparation/batch.js +72 -0
- package/dist/core/preparation/batch.js.map +1 -0
- package/dist/core/preparation/evm.d.ts +23 -4
- package/dist/core/preparation/evm.d.ts.map +1 -1
- package/dist/core/preparation/evm.js +19 -3
- package/dist/core/preparation/evm.js.map +1 -1
- package/dist/core/preparation/evmManifestSync.d.ts +5 -0
- package/dist/core/preparation/evmManifestSync.d.ts.map +1 -1
- package/dist/core/preparation/evmManifestSync.js +15 -7
- package/dist/core/preparation/evmManifestSync.js.map +1 -1
- package/dist/core/preparation/index.d.ts +2 -2
- package/dist/core/preparation/index.d.ts.map +1 -1
- package/dist/core/preparation/manifest.d.ts +2 -0
- package/dist/core/preparation/manifest.d.ts.map +1 -1
- package/dist/core/preparation/manifest.js +2 -2
- 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 +53 -11
- package/dist/core/preparation/normalize.js.map +1 -1
- package/dist/core/preparation/transparent.d.ts +23 -0
- package/dist/core/preparation/transparent.d.ts.map +1 -0
- package/dist/core/preparation/transparent.js +103 -0
- package/dist/core/preparation/transparent.js.map +1 -0
- package/dist/core/preparation/types.d.ts +47 -5
- package/dist/core/preparation/types.d.ts.map +1 -1
- package/dist/core/preparation/zksync.d.ts.map +1 -1
- package/dist/core/preparation/zksync.js +2 -0
- package/dist/core/preparation/zksync.js.map +1 -1
- package/dist/custody/credential.d.ts.map +1 -1
- package/dist/custody/credential.js +1 -6
- package/dist/custody/credential.js.map +1 -1
- package/dist/deployment-evm/index.d.ts +4 -0
- package/dist/deployment-evm/index.d.ts.map +1 -0
- package/dist/deployment-evm/index.js +3 -0
- package/dist/deployment-evm/index.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +5 -0
- package/dist/sync/index.js.map +1 -1
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/workflow/index.d.ts +4 -1
- package/dist/workflow/index.d.ts.map +1 -1
- package/dist/workflow/index.js +2 -0
- package/dist/workflow/index.js.map +1 -1
- package/dist-cjs/core/preparation/batch.js +76 -0
- package/dist-cjs/core/preparation/batch.js.map +1 -0
- package/dist-cjs/core/preparation/evm.js +25 -7
- package/dist-cjs/core/preparation/evm.js.map +1 -1
- package/dist-cjs/core/preparation/evmManifestSync.js +15 -7
- package/dist-cjs/core/preparation/evmManifestSync.js.map +1 -1
- package/dist-cjs/core/preparation/manifest.js +2 -2
- package/dist-cjs/core/preparation/manifest.js.map +1 -1
- package/dist-cjs/core/preparation/normalize.js +53 -11
- package/dist-cjs/core/preparation/normalize.js.map +1 -1
- package/dist-cjs/core/preparation/transparent.js +110 -0
- package/dist-cjs/core/preparation/transparent.js.map +1 -0
- package/dist-cjs/core/preparation/zksync.js +2 -0
- package/dist-cjs/core/preparation/zksync.js.map +1 -1
- package/dist-cjs/custody/credential.js +1 -6
- package/dist-cjs/custody/credential.js.map +1 -1
- package/dist-cjs/deployment-evm/index.js +10 -0
- package/dist-cjs/deployment-evm/index.js.map +1 -0
- package/dist-cjs/sync/index.js +5 -0
- package/dist-cjs/sync/index.js.map +1 -1
- package/dist-cjs/workflow/index.js +11 -1
- package/dist-cjs/workflow/index.js.map +1 -1
- package/dist-runtime/config/hardhatAdapters.js +2 -1
- package/dist-runtime/config/hardhatAdapters.js.map +1 -1
- package/dist-runtime/delivery/aggregate-bootstrap.js +3 -1
- package/dist-runtime/delivery/aggregate-bootstrap.js.map +1 -1
- package/dist-runtime/delivery/aggregate-channel.js +7 -3
- package/dist-runtime/delivery/aggregate-channel.js.map +1 -1
- package/dist-runtime/delivery/aggregate-diagnostics.d.ts +14 -0
- package/dist-runtime/delivery/aggregate-diagnostics.js +73 -0
- package/dist-runtime/delivery/aggregate-diagnostics.js.map +1 -0
- package/dist-runtime/delivery/aggregate-inputs.d.ts +13 -9
- package/dist-runtime/delivery/aggregate-source.js +11 -3
- package/dist-runtime/delivery/aggregate-source.js.map +1 -1
- package/dist-runtime/delivery/aggregate-worker.js +12 -4
- package/dist-runtime/delivery/aggregate-worker.js.map +1 -1
- package/dist-runtime/delivery/aggregate.js +2 -2
- package/dist-runtime/delivery/aggregate.js.map +1 -1
- package/dist-runtime/delivery/business-extension.d.ts +10 -0
- package/dist-runtime/delivery/business-extension.js +38 -0
- package/dist-runtime/delivery/business-extension.js.map +1 -0
- package/dist-runtime/delivery/calldata-archive.d.ts +18 -0
- package/dist-runtime/delivery/calldata-archive.js +31 -0
- package/dist-runtime/delivery/calldata-archive.js.map +1 -0
- package/dist-runtime/delivery/calldata-details.d.ts +47 -0
- package/dist-runtime/delivery/calldata-details.js +94 -0
- package/dist-runtime/delivery/calldata-details.js.map +1 -0
- package/dist-runtime/delivery/calldata-format.d.ts +4 -0
- package/dist-runtime/delivery/calldata-format.js +17 -0
- package/dist-runtime/delivery/calldata-format.js.map +1 -0
- package/dist-runtime/delivery/calldata-preparations.d.ts +13 -0
- package/dist-runtime/delivery/calldata-preparations.js +85 -0
- package/dist-runtime/delivery/calldata-preparations.js.map +1 -0
- package/dist-runtime/delivery/calldata-review.d.ts +44 -0
- package/dist-runtime/delivery/calldata-review.js +131 -0
- package/dist-runtime/delivery/calldata-review.js.map +1 -0
- package/dist-runtime/delivery/codec-pin.d.ts +2 -2
- package/dist-runtime/delivery/codec-pin.js +4 -4
- package/dist-runtime/delivery/codec-pin.js.map +1 -1
- package/dist-runtime/delivery/compiler-files.js +3 -1
- package/dist-runtime/delivery/compiler-files.js.map +1 -1
- package/dist-runtime/delivery/compiler-pins.js +1 -1
- package/dist-runtime/delivery/compiler.js +17 -16
- package/dist-runtime/delivery/compiler.js.map +1 -1
- package/dist-runtime/delivery/config.d.ts +1 -1
- package/dist-runtime/delivery/config.js +27 -2
- package/dist-runtime/delivery/config.js.map +1 -1
- package/dist-runtime/delivery/configuration-definition.d.ts +9 -0
- package/dist-runtime/delivery/configuration-definition.js +33 -6
- package/dist-runtime/delivery/configuration-definition.js.map +1 -1
- package/dist-runtime/delivery/configuration.js +7 -4
- package/dist-runtime/delivery/configuration.js.map +1 -1
- package/dist-runtime/delivery/contract-source.d.ts +14 -0
- package/dist-runtime/delivery/contract-source.js +138 -0
- package/dist-runtime/delivery/contract-source.js.map +1 -0
- package/dist-runtime/delivery/custom-format.js +51 -24
- package/dist-runtime/delivery/custom-format.js.map +1 -1
- package/dist-runtime/delivery/development.d.ts +2 -1
- package/dist-runtime/delivery/development.js +21 -10
- package/dist-runtime/delivery/development.js.map +1 -1
- package/dist-runtime/delivery/eoa.d.ts +1 -0
- package/dist-runtime/delivery/execution-identity.d.ts +15 -0
- package/dist-runtime/delivery/execution-identity.js +33 -0
- package/dist-runtime/delivery/execution-identity.js.map +1 -0
- package/dist-runtime/delivery/existing-code.js +14 -6
- package/dist-runtime/delivery/existing-code.js.map +1 -1
- package/dist-runtime/delivery/history-registration.d.ts +1 -1
- package/dist-runtime/delivery/inputs.js +22 -15
- package/dist-runtime/delivery/inputs.js.map +1 -1
- package/dist-runtime/delivery/journal.js +18 -10
- package/dist-runtime/delivery/journal.js.map +1 -1
- package/dist-runtime/delivery/parameter-defaults.d.ts +10 -0
- package/dist-runtime/delivery/parameter-defaults.js +86 -0
- package/dist-runtime/delivery/parameter-defaults.js.map +1 -0
- package/dist-runtime/delivery/parameters.d.ts +2 -0
- package/dist-runtime/delivery/parameters.js +22 -0
- package/dist-runtime/delivery/parameters.js.map +1 -1
- package/dist-runtime/delivery/planning.d.ts +4 -1
- package/dist-runtime/delivery/planning.js +19 -3
- package/dist-runtime/delivery/planning.js.map +1 -1
- package/dist-runtime/delivery/preparation.js +43 -23
- package/dist-runtime/delivery/preparation.js.map +1 -1
- package/dist-runtime/delivery/production-environment.js +2 -1
- package/dist-runtime/delivery/production-environment.js.map +1 -1
- package/dist-runtime/delivery/production-finalization.js +23 -9
- package/dist-runtime/delivery/production-finalization.js.map +1 -1
- package/dist-runtime/delivery/production-intent.d.ts +2 -0
- package/dist-runtime/delivery/production-intent.js +16 -0
- package/dist-runtime/delivery/production-intent.js.map +1 -0
- package/dist-runtime/delivery/production.d.ts +129 -8
- package/dist-runtime/delivery/production.js +60 -11
- package/dist-runtime/delivery/production.js.map +1 -1
- package/dist-runtime/delivery/project-files.d.ts +3 -3
- package/dist-runtime/delivery/project-files.js +19 -14
- package/dist-runtime/delivery/project-files.js.map +1 -1
- package/dist-runtime/delivery/project-rpc.d.ts +19 -0
- package/dist-runtime/delivery/project-rpc.js +138 -0
- package/dist-runtime/delivery/project-rpc.js.map +1 -0
- package/dist-runtime/delivery/project.d.ts +3 -1
- package/dist-runtime/delivery/project.js +21 -8
- package/dist-runtime/delivery/project.js.map +1 -1
- package/dist-runtime/delivery/public-calldata.d.ts +25 -0
- package/dist-runtime/delivery/public-calldata.js +97 -0
- package/dist-runtime/delivery/public-calldata.js.map +1 -0
- package/dist-runtime/delivery/release-graph.d.ts +7 -3
- package/dist-runtime/delivery/release-graph.js +58 -25
- package/dist-runtime/delivery/release-graph.js.map +1 -1
- package/dist-runtime/delivery/release-history.d.ts +1 -1
- package/dist-runtime/delivery/release-history.js +86 -10
- package/dist-runtime/delivery/release-history.js.map +1 -1
- package/dist-runtime/delivery/release-inputs.d.ts +33 -0
- package/dist-runtime/delivery/release-inputs.js +129 -0
- package/dist-runtime/delivery/release-inputs.js.map +1 -0
- package/dist-runtime/delivery/release.d.ts +38 -14
- package/dist-runtime/delivery/release.js +81 -29
- package/dist-runtime/delivery/release.js.map +1 -1
- package/dist-runtime/delivery/safe.d.ts +1 -0
- package/dist-runtime/delivery/safe.js +13 -2
- package/dist-runtime/delivery/safe.js.map +1 -1
- package/dist-runtime/delivery/same-fork-baseline.d.ts +1 -1
- package/dist-runtime/delivery/same-fork-baseline.js +5 -4
- package/dist-runtime/delivery/same-fork-baseline.js.map +1 -1
- package/dist-runtime/delivery/setup.d.ts +1 -1
- package/dist-runtime/delivery/setup.js +21 -6
- package/dist-runtime/delivery/setup.js.map +1 -1
- package/dist-runtime/delivery/source.d.ts +1 -0
- package/dist-runtime/delivery/source.js +12 -10
- package/dist-runtime/delivery/source.js.map +1 -1
- package/dist-runtime/delivery/task-identity.d.ts +23 -0
- package/dist-runtime/delivery/task-identity.js +109 -0
- package/dist-runtime/delivery/task-identity.js.map +1 -0
- package/dist-runtime/delivery/toolchain.d.ts +3 -0
- package/dist-runtime/delivery/toolchain.js +52 -0
- package/dist-runtime/delivery/toolchain.js.map +1 -0
- package/dist-runtime/delivery/validation.js +7 -2
- package/dist-runtime/delivery/validation.js.map +1 -1
- package/dist-runtime/runtime-identity.json +2 -2
- package/dist-runtime/vendor/plan-codec/index.cjs +97 -20
- package/dist-runtime/vendor/plan-codec/index.d.cts +6 -0
- package/dist-runtime/vendor/plan-codec/provenance.json +9 -8
- package/dist-runtime/workflow/lib/calls.js +1 -0
- package/dist-runtime/workflow/lib/calls.js.map +1 -1
- package/dist-runtime/workflow/lib/checkCodeRunner.js +7 -4
- package/dist-runtime/workflow/lib/checkCodeRunner.js.map +1 -1
- package/dist-runtime/workflow/lib/context.d.ts +1 -0
- package/dist-runtime/workflow/lib/create2.d.ts +4 -26
- package/dist-runtime/workflow/lib/create2.js +2 -67
- package/dist-runtime/workflow/lib/create2.js.map +1 -1
- package/dist-runtime/workflow/lib/deploymentInfo.d.ts +2 -0
- package/dist-runtime/workflow/lib/deploymentInfo.js +6 -0
- package/dist-runtime/workflow/lib/deploymentInfo.js.map +1 -1
- package/dist-runtime/workflow/lib/deploymentRecords.d.ts +2 -0
- package/dist-runtime/workflow/lib/deploymentRecords.js +1 -1
- package/dist-runtime/workflow/lib/deploymentRecords.js.map +1 -1
- package/dist-runtime/workflow/lib/externalExecutionScanner.js +2 -1
- package/dist-runtime/workflow/lib/externalExecutionScanner.js.map +1 -1
- package/dist-runtime/workflow/lib/gateTool.js +2 -2
- package/dist-runtime/workflow/lib/gateTool.js.map +1 -1
- package/dist-runtime/workflow/lib/gateToolSync.d.ts +3 -0
- package/dist-runtime/workflow/lib/gateToolSync.js +5 -0
- package/dist-runtime/workflow/lib/gateToolSync.js.map +1 -1
- package/dist-runtime/workflow/lib/parameters.js +5 -0
- package/dist-runtime/workflow/lib/parameters.js.map +1 -1
- package/dist-runtime/workflow/lib/proxy.d.ts +1 -0
- package/dist-runtime/workflow/lib/proxy.js.map +1 -1
- package/dist-runtime/workflow/run.js +1 -3
- package/dist-runtime/workflow/run.js.map +1 -1
- package/dist-runtime/workflow/steps/deploy.js +53 -0
- package/dist-runtime/workflow/steps/deploy.js.map +1 -1
- package/dist-runtime/workflow/steps/upgrade.js +24 -10
- package/dist-runtime/workflow/steps/upgrade.js.map +1 -1
- package/docs/compiler-qualification.md +8 -2
- package/docs/delivery-aggregate.md +2 -0
- package/docs/delivery-calldata.md +27 -0
- package/docs/delivery-development.md +6 -0
- package/docs/delivery-execution-store.md +1 -1
- package/docs/delivery-inputs.md +55 -6
- package/docs/delivery-parameters.md +1 -1
- package/docs/delivery-release.md +60 -6
- package/docs/delivery-safe.md +7 -4
- package/docs/delivery-setup.md +72 -20
- package/docs/delivery-source.md +8 -8
- package/docs/direct-package-acceptance.md +2 -0
- package/docs/openzeppelin-acceptance.md +86 -0
- package/docs/openzeppelin-baseline.json +27 -0
- package/docs/openzeppelin-integration.md +115 -0
- package/docs/plans/2026-10-28-openzeppelin-toolkit-consolidation.md +396 -0
- package/docs/plans/2026-11-02-transparent-proxy-delivery.md +78 -0
- package/docs/superpowers/plans/2026-08-17-custody-hardhat-signers.md +1 -1
- package/docs/workflow-reference.md +12 -4
- package/docs/workflow-runtime.md +6 -0
- package/package.json +19 -5
- package/runtime/config/hardhatAdapters.ts +2 -1
- package/runtime/delivery/aggregate-bootstrap.ts +3 -1
- package/runtime/delivery/aggregate-channel.ts +6 -3
- package/runtime/delivery/aggregate-diagnostics.ts +63 -0
- package/runtime/delivery/aggregate-source.ts +6 -2
- package/runtime/delivery/aggregate-worker.ts +15 -5
- package/runtime/delivery/aggregate.ts +2 -2
- package/runtime/delivery/business-extension.ts +33 -0
- package/runtime/delivery/calldata-archive.ts +25 -0
- package/runtime/delivery/calldata-details.ts +90 -0
- package/runtime/delivery/calldata-format.ts +14 -0
- package/runtime/delivery/calldata-preparations.ts +76 -0
- package/runtime/delivery/calldata-review.ts +126 -0
- package/runtime/delivery/codec-pin.ts +3 -3
- package/runtime/delivery/compiler-files.ts +3 -1
- package/runtime/delivery/compiler-pins.ts +1 -1
- package/runtime/delivery/compiler.ts +18 -17
- package/runtime/delivery/config.ts +25 -2
- package/runtime/delivery/configuration-definition.ts +34 -7
- package/runtime/delivery/configuration.ts +8 -5
- package/runtime/delivery/contract-source.ts +112 -0
- package/runtime/delivery/custom-format.ts +20 -5
- package/runtime/delivery/development.ts +13 -11
- package/runtime/delivery/execution-identity.ts +32 -0
- package/runtime/delivery/existing-code.ts +7 -6
- package/runtime/delivery/inputs.ts +18 -11
- package/runtime/delivery/journal.ts +14 -10
- package/runtime/delivery/parameter-defaults.ts +75 -0
- package/runtime/delivery/parameters.ts +18 -0
- package/runtime/delivery/planning.ts +19 -5
- package/runtime/delivery/preparation.ts +17 -1
- package/runtime/delivery/production-environment.ts +2 -1
- package/runtime/delivery/production-finalization.ts +19 -10
- package/runtime/delivery/production-intent.ts +14 -0
- package/runtime/delivery/production.ts +51 -11
- package/runtime/delivery/project-files.ts +16 -11
- package/runtime/delivery/project-rpc.ts +116 -0
- package/runtime/delivery/project.ts +19 -7
- package/runtime/delivery/public-calldata.ts +74 -0
- package/runtime/delivery/release-graph.ts +44 -14
- package/runtime/delivery/release-history.ts +66 -8
- package/runtime/delivery/release-inputs.ts +107 -0
- package/runtime/delivery/release.ts +56 -18
- package/runtime/delivery/safe.ts +14 -3
- package/runtime/delivery/same-fork-baseline.ts +5 -4
- package/runtime/delivery/setup.ts +20 -8
- package/runtime/delivery/source.ts +10 -10
- package/runtime/delivery/task-identity.ts +85 -0
- package/runtime/delivery/toolchain.ts +48 -0
- package/runtime/delivery/validation.ts +7 -2
- package/runtime/vendor/plan-codec/index.cjs +97 -20
- package/runtime/vendor/plan-codec/index.d.cts +6 -0
- package/runtime/vendor/plan-codec/provenance.json +9 -8
- package/runtime/workflow/lib/calls.ts +1 -0
- package/runtime/workflow/lib/checkCodeRunner.ts +7 -3
- package/runtime/workflow/lib/context.ts +1 -0
- package/runtime/workflow/lib/create2.ts +7 -108
- package/runtime/workflow/lib/deploymentInfo.ts +8 -0
- package/runtime/workflow/lib/deploymentRecords.ts +3 -1
- package/runtime/workflow/lib/externalExecutionScanner.ts +2 -1
- package/runtime/workflow/lib/gateTool.ts +2 -2
- package/runtime/workflow/lib/gateToolSync.ts +8 -0
- package/runtime/workflow/lib/parameters.ts +4 -0
- package/runtime/workflow/lib/proxy.ts +1 -0
- package/runtime/workflow/run.ts +1 -2
- package/runtime/workflow/steps/deploy.ts +42 -0
- package/runtime/workflow/steps/upgrade.ts +19 -11
- package/bin/workflow.cjs +0 -19
|
@@ -5,12 +5,13 @@ export interface SameForkInitialPreparation { request: GateToolPreparationReques
|
|
|
5
5
|
/** Stable initial preparation and full prior layout commitment. Auxiliary compiler randomness is excluded. */
|
|
6
6
|
export function sameForkBaselineDigest(initial: SameForkInitialPreparation, oldLayoutHash: string): string {
|
|
7
7
|
const request = normalizePreparationRequest(initial.request), plan = normalizePreparationPlan(initial.plan);
|
|
8
|
-
if (request.kind !== 'uups-placeholder-deploy' || plan.kind !== request.kind || plan.requestHash !== hashPreparationRequest(request)
|
|
9
|
-
|| plan.target !== request.target || !/^[a-f0-9]{64}$/.test(oldLayoutHash)) throw new Error('Invalid same-fork initial preparation');
|
|
8
|
+
if ((request.kind !== 'uups-placeholder-deploy' && request.kind !== 'transparent-deploy') || plan.kind !== request.kind || plan.requestHash !== hashPreparationRequest(request)
|
|
9
|
+
|| plan.proxyKind !== request.proxyKind || plan.target !== request.target || !/^[a-f0-9]{64}$/.test(oldLayoutHash)) throw new Error('Invalid same-fork initial preparation');
|
|
10
10
|
return semanticHash({kind:'same-fork',request,plan,oldLayoutHash});
|
|
11
11
|
}
|
|
12
|
-
export function matchesSameForkInitial(initial: SameForkInitialPreparation, target: string, chainId: string, proxy: string, implementation?: string): boolean {
|
|
13
|
-
return initial.request.kind === 'uups-placeholder-deploy' && initial.request.target === target && initial.plan.target === target && initial.plan.chainId === chainId
|
|
12
|
+
export function matchesSameForkInitial(initial: SameForkInitialPreparation, target: string, chainId: string, proxy: string, implementation?: string, proxyKind?: 'uups' | 'transparent'): boolean {
|
|
13
|
+
return (initial.request.kind === 'uups-placeholder-deploy' || initial.request.kind === 'transparent-deploy') && initial.request.target === target && initial.plan.target === target && initial.plan.chainId === chainId
|
|
14
|
+
&& initial.plan.proxyKind === initial.request.proxyKind && (proxyKind === undefined || initial.request.proxyKind === proxyKind)
|
|
14
15
|
&& initial.plan.deployments.some(d => d.role === 'proxy' && d.address.toLowerCase() === proxy.toLowerCase())
|
|
15
16
|
&& (implementation === undefined || initial.plan.deployments.some(d => d.role === 'implementation' && d.address.toLowerCase() === implementation.toLowerCase()));
|
|
16
17
|
}
|
|
@@ -4,16 +4,20 @@ import crypto from 'node:crypto';
|
|
|
4
4
|
import { createRequire } from 'node:module';
|
|
5
5
|
import { spawnSync } from 'node:child_process';
|
|
6
6
|
import YAML from 'yaml';
|
|
7
|
+
import { REVIEWED_DELIVERY_OVERRIDES } from './toolchain';
|
|
7
8
|
import { object } from './protocol';
|
|
8
|
-
import {
|
|
9
|
-
import { configDocument, validateDeliveryTarget, type DeliveryTarget } from './config';
|
|
10
|
-
export { readProjectNetworkSnapshots } from './project';
|
|
9
|
+
import { deliveryProjectMarker, projectRoot, readFile, confinedFile, stat, integratedConfig, readPublicProjectNetworkSnapshots, projectSourcesDirectory } from './project';
|
|
10
|
+
import { configDocument, parseDeliveryPublicTargets, validateDeliveryTarget, type DeliveryTarget } from './config';
|
|
11
|
+
export { readProjectNetworkSnapshots, readPublicProjectNetworkSnapshots } from './project';
|
|
11
12
|
export { loadDeliveryTarget } from './config';
|
|
12
13
|
export { configureDeliveryEnvironment } from './manifest';
|
|
13
14
|
export type { DeliveryTarget, DeliveryTargetConfig } from './config';
|
|
14
15
|
|
|
15
16
|
const TOOLCHAIN: Record<string, string> = { hardhat: '2.26.3', ethers: '6.15.0', '@nomicfoundation/hardhat-ethers': '3.1.0', typescript: '5.9.3', 'ts-node': '10.9.2' };
|
|
16
|
-
|
|
17
|
+
// Resolve our identity from the executing package, including an explicitly installed tarball.
|
|
18
|
+
const toolIdentity = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../../package.json'), 'utf8'));
|
|
19
|
+
if (toolIdentity.name !== 'gate-evm-tools' || typeof toolIdentity.version !== 'string') throw new Error('Invalid GateTool package identity');
|
|
20
|
+
const DEPENDENCIES: Record<string, string> = { 'gate-evm-tools': toolIdentity.version, '@openzeppelin/hardhat-upgrades': '3.9.1', '@openzeppelin/upgrades-core': '1.44.2', '@openzeppelin/contracts': '5.4.0' };
|
|
17
21
|
export interface DeliverySetupOptions {
|
|
18
22
|
workspaceRoot: string;
|
|
19
23
|
projectRoot: string;
|
|
@@ -65,10 +69,14 @@ function preflight(input: DeliverySetupOptions): { result: DeliveryInspection; w
|
|
|
65
69
|
const targets = input.targets.map(validateDeliveryTarget);
|
|
66
70
|
if (new Set(targets.map(target => target.network)).size !== targets.length) throw new Error('Duplicate selected target');
|
|
67
71
|
const root = projectRoot(input.workspaceRoot, input.projectRoot);
|
|
68
|
-
|
|
72
|
+
deliveryProjectMarker(root);
|
|
69
73
|
const before = new Map<string, string | undefined>();
|
|
70
74
|
for (const file of ['.gate-template.json', 'package.json', 'hardhat.config.ts', 'config.yaml', 'contractInfo.json']) before.set(file, readFile(root, file));
|
|
71
75
|
const pkg = object(JSON.parse(before.get('package.json') ?? 'null'), 'package.json');
|
|
76
|
+
const overrides = pkg.overrides === undefined ? {} : object(pkg.overrides, 'package overrides');
|
|
77
|
+
for (const [name, version] of Object.entries(REVIEWED_DELIVERY_OVERRIDES)) {
|
|
78
|
+
if (overrides[name] !== undefined && overrides[name] !== version) throw new Error(`Reviewed delivery dependency override conflict: ${name}`);
|
|
79
|
+
}
|
|
72
80
|
const declarations: Record<string, unknown> = {};
|
|
73
81
|
for (const section of ['dependencies', 'devDependencies']) {
|
|
74
82
|
const entries = pkg[section] === undefined ? {} : object(pkg[section], section);
|
|
@@ -89,7 +97,7 @@ function preflight(input: DeliverySetupOptions): { result: DeliveryInspection; w
|
|
|
89
97
|
const localTool = name === 'gate-evm-tools' && input.toolPackage === undefined && typeof declared === 'string' && /^file:.*\.tgz$/.test(declared);
|
|
90
98
|
if ((name in TOOLCHAIN && declared === undefined) || (declared !== undefined && declared !== version && !localTool)) throw new Error(`Dependency declaration conflict for ${name}: expected ${version}`);
|
|
91
99
|
}
|
|
92
|
-
const networks =
|
|
100
|
+
const networks = readPublicProjectNetworkSnapshots(root, targets.map(target => target.network));
|
|
93
101
|
const source = before.get('hardhat.config.ts')!;
|
|
94
102
|
const withPlugin = integratedConfig(source); // Check integration conflicts even when dependencies are missing.
|
|
95
103
|
const doc = configDocument(root);
|
|
@@ -106,6 +114,9 @@ function preflight(input: DeliverySetupOptions): { result: DeliveryInspection; w
|
|
|
106
114
|
confinedFile(root, target.openzeppelin!.manifestDir, 'directory');
|
|
107
115
|
merge([network], target);
|
|
108
116
|
}
|
|
117
|
+
// Validate the same effective facilities used by input qualification, while keeping inherited
|
|
118
|
+
// addresses in their profiles so later base edits propagate to non-overridden targets.
|
|
119
|
+
parseDeliveryPublicTargets(Buffer.from(doc.toString()), Buffer.from(source), targets);
|
|
109
120
|
if (before.get('contractInfo.json') !== undefined) object(JSON.parse(before.get('contractInfo.json')!), 'contractInfo.json');
|
|
110
121
|
const dependencies: DeliveryInspection['dependencies'] = [];
|
|
111
122
|
const projectRequire = createRequire(path.join(root, 'package.json'));
|
|
@@ -140,10 +151,11 @@ function preflight(input: DeliverySetupOptions): { result: DeliveryInspection; w
|
|
|
140
151
|
}
|
|
141
152
|
const writes = new Map<string, string>();
|
|
142
153
|
const missing = Object.entries(required).filter(([name]) => declarations[name] === undefined);
|
|
143
|
-
|
|
154
|
+
const missingOverrides = Object.entries(REVIEWED_DELIVERY_OVERRIDES).some(([name]) => overrides[name] === undefined);
|
|
155
|
+
if (missing.length || missingOverrides) {
|
|
144
156
|
const dev = { ...(pkg.devDependencies as Record<string, unknown> ?? {}) };
|
|
145
157
|
for (const [name, version] of missing) dev[name] = version;
|
|
146
|
-
writes.set('package.json', JSON.stringify({ ...pkg, devDependencies: dev }, null, 2) + '\n');
|
|
158
|
+
writes.set('package.json', JSON.stringify({ ...pkg, devDependencies: dev, overrides: { ...overrides, ...REVIEWED_DELIVERY_OVERRIDES } }, null, 2) + '\n');
|
|
147
159
|
}
|
|
148
160
|
if (changedYaml) writes.set('config.yaml', doc.toString());
|
|
149
161
|
if (before.get('contractInfo.json') === undefined) writes.set('contractInfo.json', '{}\n');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Actual-file source binding only. This API grants no host approval or execution authority. */
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import { createHash } from 'node:crypto';
|
|
4
|
-
import {
|
|
4
|
+
import { deliveryProjectMarker, projectRoot, confinedFile } from './project-files';
|
|
5
5
|
import { object, parseDeliveryRequest, validateDeliveryRpc, type DeliveryRequest, type ChainIdProvider, type ProjectNetworkSnapshot } from './protocol';
|
|
6
6
|
import { loadPlanCodec } from './codec';
|
|
7
7
|
import type { Plan, PlanTask, DefinitionSelection, DefinitionSnapshot, DeepReadonly } from '../vendor/plan-codec/index.cjs';
|
|
@@ -37,11 +37,9 @@ export function parseCanonicalPlan(text: string): Plan { return loadPlanCodec().
|
|
|
37
37
|
export function projectCanonicalDefinitions(text: string, selection: DefinitionSelection): ReturnType<ReturnType<typeof loadPlanCodec>['projectDefinitions']> {
|
|
38
38
|
return loadPlanCodec().projectDefinitions(text, selection);
|
|
39
39
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
'prod-execution': ['release-prepare', 'release-execute', 'release-verify'],
|
|
44
|
-
};
|
|
40
|
+
export function deploymentPurpose(task: Pick<PlanTask, 'step' | 'scope'>) {
|
|
41
|
+
return loadPlanCodec().deploymentPurpose(task);
|
|
42
|
+
}
|
|
45
43
|
function sameRelease(actual: unknown, expected: DeliveryRequest['releaseRef']): boolean {
|
|
46
44
|
if (expected === undefined) return actual === undefined;
|
|
47
45
|
if (!actual || typeof actual !== 'object' || Array.isArray(actual)) return false;
|
|
@@ -78,7 +76,7 @@ function readSource(input: Omit<DeliverySourceOptions, 'sourceRoots'> & { source
|
|
|
78
76
|
const request = parseDeliveryRequest(input.request);
|
|
79
77
|
const workspace = projectRoot(input.workspaceRoot, '.');
|
|
80
78
|
const root = projectRoot(workspace, input.projectRoot);
|
|
81
|
-
|
|
79
|
+
deliveryProjectMarker(root);
|
|
82
80
|
const bytes = actualSource(workspace, request.sourceRef.path);
|
|
83
81
|
const text = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
|
|
84
82
|
if (input.sourceRoots === undefined) (require('./input-files') as typeof import('./input-files')).assertUnambiguousHandoff(text);
|
|
@@ -89,15 +87,17 @@ function readSource(input: Omit<DeliverySourceOptions, 'sourceRoots'> & { source
|
|
|
89
87
|
const invocation = entries.find(({ task }) => task.planKey === request.sourceRef.planKey);
|
|
90
88
|
if (!invocation || invocation.task.rev !== request.sourceRef.rev) throw new Error('sourceRef planKey/rev does not match actual handoff');
|
|
91
89
|
if (plan.lanes[invocation.lane].state !== 'enabled' || invocation.task.status === 'cancelled') throw new Error('Invocation task is disabled or cancelled');
|
|
90
|
+
const requirementIssue = codec.deploymentRequirementIssue(plan, invocation.task);
|
|
91
|
+
if (requirementIssue) throw new Error(requirementIssue);
|
|
92
92
|
const deployment = object(invocation.task.scope?.deployment, 'invocation scope.deployment');
|
|
93
93
|
if (deployment.projectRoot !== input.projectRoot) throw new Error('Invocation projectRoot mismatch');
|
|
94
94
|
if (deployment.chainFamily !== 'evm' || deployment.framework !== 'hardhat2') throw new Error('Invocation requires an EVM Hardhat2 deployment');
|
|
95
|
-
if (
|
|
95
|
+
if (deploymentPurpose(invocation.task) !== request.purpose) throw new Error('Invocation purpose mismatch');
|
|
96
96
|
if (deployment.environment !== request.environment || deployment.targetNetwork !== request.network) throw new Error('Invocation environment/targetNetwork mismatch');
|
|
97
97
|
if (!Array.isArray(deployment.allowedActions) || !deployment.allowedActions.includes(request.mode)) throw new Error('Invocation mode is not in allowedActions');
|
|
98
98
|
if (!sameRelease(deployment.releaseRef, request.releaseRef)) throw new Error('Invocation releaseRef mismatch');
|
|
99
99
|
const sourceRoots = input.sourceRoots ?? (request.purpose === 'prod-execution'
|
|
100
|
-
? entries.filter(({ task }) => task
|
|
100
|
+
? entries.filter(({ task }) => deploymentPurpose(task) === 'prod-qualification'
|
|
101
101
|
&& (task.scope?.deployment as Record<string, unknown> | undefined)?.projectRoot === input.projectRoot
|
|
102
102
|
&& (task.scope?.deployment as Record<string, unknown> | undefined)?.deploymentId === deployment.deploymentId).map(({ task }) => task.planKey)
|
|
103
103
|
: [invocation.task.planKey]);
|
|
@@ -109,7 +109,7 @@ function readSource(input: Omit<DeliverySourceOptions, 'sourceRoots'> & { source
|
|
|
109
109
|
}
|
|
110
110
|
let production: ReturnType<typeof codec.projectDefinitions> | undefined;
|
|
111
111
|
if (request.purpose === 'prod-execution') {
|
|
112
|
-
const roots = entries.filter(({ task }) =>
|
|
112
|
+
const roots = entries.filter(({ task }) => deploymentPurpose(task) === 'prod-execution'
|
|
113
113
|
&& task.scope?.deployment && (task.scope.deployment as Record<string, unknown>).projectRoot === input.projectRoot
|
|
114
114
|
&& sameRelease((task.scope.deployment as Record<string, unknown>).releaseRef, request.releaseRef)).map(({ task }) => task.planKey);
|
|
115
115
|
production = codec.projectDefinitions(text, { roots, mode: 'full' });
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/** Allocate a round only after its concrete requirement revision is confirmed. */
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import { randomBytes } from 'node:crypto';
|
|
4
|
+
import { parseCanonicalPlan, projectCanonicalDefinitions, deploymentPurpose } from './source';
|
|
5
|
+
import { projectRoot, deliveryProjectMarker, confinedFile, stat } from './project-files';
|
|
6
|
+
import { readInputBytes, assertUnambiguousHandoff } from './input-files';
|
|
7
|
+
import { withDevelopmentFileLock, atomicDevelopmentWrite, fileBytes } from './materialization';
|
|
8
|
+
import { exactObject, semanticHash, canonicalJson } from '../workflow/lib/canonicalData';
|
|
9
|
+
import { safeId, portablePath, object } from './protocol';
|
|
10
|
+
|
|
11
|
+
export interface DeploymentRequirementRef { planKey: string; rev: number }
|
|
12
|
+
export function parseDeploymentRequirementRef(raw: unknown): DeploymentRequirementRef {
|
|
13
|
+
const ref = exactObject(raw, ['planKey', 'rev'], 'requirementRef');
|
|
14
|
+
safeId(ref.planKey, 'requirementRef.planKey');
|
|
15
|
+
if (!Number.isSafeInteger(ref.rev) || (ref.rev as number) < 1) throw Error('Invalid requirement revision');
|
|
16
|
+
return { planKey: ref.planKey as string, rev: ref.rev as number };
|
|
17
|
+
}
|
|
18
|
+
export interface CreateDeliveryTaskOptions {
|
|
19
|
+
workspaceRoot: string; projectRoot: string; handoff: string; taskId: string;
|
|
20
|
+
requirementRef: DeploymentRequirementRef; businessSlug: string; referenceDeploymentId?: string;
|
|
21
|
+
}
|
|
22
|
+
/** A reservation creates metadata only. The deployment Agent supplies executable content afterwards. */
|
|
23
|
+
export async function createDeliveryTask(input: CreateDeliveryTaskOptions) {
|
|
24
|
+
object(input, 'create deployment task', ['workspaceRoot', 'projectRoot', 'handoff', 'taskId', 'requirementRef', 'businessSlug', 'referenceDeploymentId']);
|
|
25
|
+
const root = projectRoot(input.workspaceRoot, input.projectRoot), workspace = projectRoot(input.workspaceRoot, '.');
|
|
26
|
+
deliveryProjectMarker(root);
|
|
27
|
+
portablePath(input.handoff, 'handoff'); safeId(input.taskId, 'taskId');
|
|
28
|
+
const ref = parseDeploymentRequirementRef(input.requirementRef);
|
|
29
|
+
if (typeof input.businessSlug !== 'string' || !/^[a-z0-9][a-z0-9-]{0,63}$/.test(input.businessSlug)) throw Error('businessSlug must be a short lowercase business name');
|
|
30
|
+
if (input.referenceDeploymentId !== undefined) safeId(input.referenceDeploymentId, 'referenceDeploymentId');
|
|
31
|
+
return withDevelopmentFileLock(root, async () => {
|
|
32
|
+
const text = readInputBytes(workspace, input.handoff).toString(); assertUnambiguousHandoff(text);
|
|
33
|
+
const plan = parseCanonicalPlan(text);
|
|
34
|
+
if (plan.taskId !== input.taskId) throw Error('Requirement taskId mismatch');
|
|
35
|
+
const requirement = Object.values(plan.tasks).flat().find(t => t.planKey === ref.planKey);
|
|
36
|
+
if (!requirement || requirement.rev !== ref.rev || requirement.requirementConfirmation?.rev !== ref.rev
|
|
37
|
+
|| requirement.status === 'cancelled' || deploymentPurpose(requirement) !== 'analysis'
|
|
38
|
+
|| (requirement.scope?.deployment as any)?.projectRoot !== input.projectRoot) throw Error('Deployment requirement is unconfirmed or stale');
|
|
39
|
+
const d = requirement.scope!.deployment as any;
|
|
40
|
+
if (!d.requiredOperations?.length || !d.developmentNetwork || !Array.isArray(d.releaseTargetNetworks)) throw Error('Confirmed requirement scope is incomplete');
|
|
41
|
+
const identity = semanticHash({ taskId: input.taskId, projectRoot: input.projectRoot, requirementRef: ref });
|
|
42
|
+
const requirementHash = semanticHash(projectCanonicalDefinitions(text, { roots: [ref.planKey], mode: 'upstream' }).snapshot);
|
|
43
|
+
const registry = `.gate-delivery/deployment-requests/${identity}.json`;
|
|
44
|
+
const requestIdentity = { taskId: input.taskId, requirementRef: ref, requirementHash,
|
|
45
|
+
referenceDeploymentId: input.referenceDeploymentId ?? null };
|
|
46
|
+
let record: any;
|
|
47
|
+
const existing = fileBytes(root, registry);
|
|
48
|
+
if (existing !== null) {
|
|
49
|
+
record = JSON.parse(existing);
|
|
50
|
+
if (canonicalJson(record.requestIdentity) !== canonicalJson(requestIdentity)) throw Error('Confirmed requirement identity conflict');
|
|
51
|
+
safeId(record.deploymentId, 'reserved deploymentId');
|
|
52
|
+
} else {
|
|
53
|
+
const known = new Set(Object.values(plan.tasks).flat().map(t => (t.scope?.deployment as any)?.deploymentId).filter(Boolean));
|
|
54
|
+
const history = fileBytes(workspace, input.handoff.includes('/') ? `${input.handoff.slice(0, input.handoff.lastIndexOf('/'))}/handoff-ledger.jsonl` : 'handoff-ledger.jsonl');
|
|
55
|
+
if (history) for (const line of history.split('\n').filter(Boolean)) {
|
|
56
|
+
const item = JSON.parse(line);
|
|
57
|
+
for (const entry of item.tasks ?? []) { const id = entry.task?.scope?.deployment?.deploymentId; if (id) known.add(id); }
|
|
58
|
+
}
|
|
59
|
+
const date = new Date().toISOString().slice(0, 10).replaceAll('-', '');
|
|
60
|
+
let deploymentId: string;
|
|
61
|
+
do { deploymentId = `${input.businessSlug}-${date}-${randomBytes(4).toString('hex')}`; }
|
|
62
|
+
while (known.has(deploymentId) || stat(confinedFile(root, `scripts/tasks/${deploymentId}`, 'directory')));
|
|
63
|
+
record = { version: 1, deploymentId, releaseId: `${deploymentId}-release`, requestIdentity, state: 'reserved' };
|
|
64
|
+
// Publish reservation before creating the package, so a retry uses the same ID.
|
|
65
|
+
atomicDevelopmentWrite(root, registry, canonicalJson(record) + '\n');
|
|
66
|
+
}
|
|
67
|
+
const businessRoot = `scripts/tasks/${record.deploymentId}`;
|
|
68
|
+
const directory = confinedFile(root, businessRoot, 'directory');
|
|
69
|
+
const marker = `${businessRoot}/.request.json`;
|
|
70
|
+
const markerBytes = canonicalJson({ identity }) + '\n';
|
|
71
|
+
const previousMarker = fileBytes(root, marker);
|
|
72
|
+
if (stat(directory) && previousMarker !== markerBytes && fs.readdirSync(directory).length) throw Error('Reserved deployment directory is occupied; refusing to overwrite');
|
|
73
|
+
if (previousMarker !== null && previousMarker !== markerBytes) throw Error('Deployment reservation ownership mismatch');
|
|
74
|
+
if (previousMarker === null) atomicDevelopmentWrite(root, marker, markerBytes);
|
|
75
|
+
const metadata = { version: 1, id: record.deploymentId, requirementRef: ref,
|
|
76
|
+
developmentNetwork: d.developmentNetwork, releaseTargetNetworks: d.releaseTargetNetworks,
|
|
77
|
+
...(input.referenceDeploymentId ? { referenceDeploymentId: input.referenceDeploymentId } : {}) };
|
|
78
|
+
const taskPath = `${businessRoot}/task.yaml`, bytes = canonicalJson(metadata) + '\n';
|
|
79
|
+
const previous = fileBytes(root, taskPath);
|
|
80
|
+
if (previous !== null && previous !== bytes) throw Error('Reserved task metadata changed; refusing to overwrite');
|
|
81
|
+
if (previous === null) atomicDevelopmentWrite(root, taskPath, bytes);
|
|
82
|
+
if (record.state !== 'complete') atomicDevelopmentWrite(root, registry, canonicalJson({ ...record, state: 'complete' }) + '\n');
|
|
83
|
+
return { status: 'created' as const, deploymentId: record.deploymentId as string, releaseId: record.releaseId as string, businessRoot, specPath: taskPath, requirementRef: ref };
|
|
84
|
+
});
|
|
85
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { compilerDependencyPins } from './compiler-dependency-pins';
|
|
2
|
+
|
|
3
|
+
/** Reviewed compiler adapter dependency selections; payload checks remain authoritative.
|
|
4
|
+
* Range-scoped entries preserve distinct dependency majors. Setup never overrides a conflicting project choice. */
|
|
5
|
+
export const REVIEWED_DELIVERY_OVERRIDES: Record<string, string> = {
|
|
6
|
+
"axios": "1.20.0",
|
|
7
|
+
"@aws-sdk/client-lambda": "3.1152.0",
|
|
8
|
+
"@aws-sdk/core": "3.978.3",
|
|
9
|
+
"@aws-sdk/credential-provider-env": "3.972.74",
|
|
10
|
+
"@aws-sdk/credential-provider-http": "3.972.76",
|
|
11
|
+
"@aws-sdk/credential-provider-ini": "3.973.19",
|
|
12
|
+
"@aws-sdk/credential-provider-login": "3.972.81",
|
|
13
|
+
"@aws-sdk/credential-provider-node": "3.972.86",
|
|
14
|
+
"@aws-sdk/credential-provider-process": "3.972.74",
|
|
15
|
+
"@aws-sdk/credential-provider-sso": "3.973.18",
|
|
16
|
+
"@aws-sdk/credential-provider-web-identity": "3.972.80",
|
|
17
|
+
"@aws-sdk/nested-clients": "3.997.48",
|
|
18
|
+
"@aws-sdk/signature-v4-multi-region": "3.996.48",
|
|
19
|
+
"@aws-sdk/token-providers": "3.1150.0",
|
|
20
|
+
"@aws-sdk/types": "3.974.6",
|
|
21
|
+
"@smithy/types": "4.19.0",
|
|
22
|
+
"@smithy/signature-v4": "5.7.4",
|
|
23
|
+
"@smithy/fetch-http-handler": "5.8.0",
|
|
24
|
+
"@smithy/credential-provider-imds": "4.5.2",
|
|
25
|
+
"@smithy/core": "3.36.0",
|
|
26
|
+
"@smithy/node-http-handler": "4.12.1",
|
|
27
|
+
"bowser": "2.14.1",
|
|
28
|
+
"follow-redirects": "1.16.1",
|
|
29
|
+
"undici@>=5 <6": "5.29.0",
|
|
30
|
+
"undici@>=6 <7": "6.29.0",
|
|
31
|
+
"tslib@>=1 <2": "1.14.1",
|
|
32
|
+
"tslib@>=2 <3": "2.7.0",
|
|
33
|
+
"semver@>=5 <6": "5.7.2",
|
|
34
|
+
"semver@>=6 <7": "6.3.1",
|
|
35
|
+
"semver@>=7 <8": "7.8.5",
|
|
36
|
+
"ansi-regex@>=6 <7": "6.4.0"
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// OZ's compiler adapter follows floating AWS/Smithy ranges. Freeze that reviewed
|
|
40
|
+
// family closure so a fresh npm resolution cannot select unqualified payloads.
|
|
41
|
+
// Other project dependencies keep their original constraints and payload checks.
|
|
42
|
+
for (const key of Object.keys(compilerDependencyPins)) {
|
|
43
|
+
if (!key.startsWith('@aws-sdk/') && !key.startsWith('@smithy/')) continue;
|
|
44
|
+
const at = key.lastIndexOf('@'), name = key.slice(0, at), version = key.slice(at + 1);
|
|
45
|
+
const existing = REVIEWED_DELIVERY_OVERRIDES[name];
|
|
46
|
+
if (existing && existing !== version) throw new Error('Ambiguous reviewed compiler dependency: ' + name);
|
|
47
|
+
REVIEWED_DELIVERY_OVERRIDES[name] = version;
|
|
48
|
+
}
|
|
@@ -118,13 +118,16 @@ export function createDeliveryValidation(
|
|
|
118
118
|
const args = first
|
|
119
119
|
? (first.constructorArgs ?? [])
|
|
120
120
|
: step.kind === "deploy"
|
|
121
|
-
? (step.args ?? [])
|
|
121
|
+
? (proxy ? (proxy.constructorArgs ?? []) : (step.args ?? []))
|
|
122
122
|
: (step.constructorArgs ??
|
|
123
123
|
(typeof proxy === "object"
|
|
124
124
|
? proxy?.constructorArgs
|
|
125
125
|
: undefined) ??
|
|
126
126
|
[]);
|
|
127
127
|
await argumentsFor(name as string, null, args, true);
|
|
128
|
+
if (step.kind === "deploy" && proxy?.kind === "transparent" && proxy.initializer !== false) {
|
|
129
|
+
await argumentsFor(name as string, String(proxy.initializer), step.args ?? [], true);
|
|
130
|
+
}
|
|
128
131
|
const init = (first?.call ?? step.call) as
|
|
129
132
|
| Record<string, unknown>
|
|
130
133
|
| undefined;
|
|
@@ -169,7 +172,9 @@ export function createDeliveryValidation(
|
|
|
169
172
|
true,
|
|
170
173
|
)
|
|
171
174
|
: declaredCreate2;
|
|
172
|
-
|
|
175
|
+
// Transparent proxy prediction depends on the prepared implementation salt/address.
|
|
176
|
+
// Its actual constructor and policies are independently checked by preparation semantics.
|
|
177
|
+
if (step.kind === "deploy" && create2 && proxy?.kind !== "transparent") {
|
|
173
178
|
const a = await read(first ? ERC1967_PROXY : (name as string));
|
|
174
179
|
const constructor = resolve(
|
|
175
180
|
first
|
|
@@ -28,8 +28,11 @@ __export(read_only_exports, {
|
|
|
28
28
|
SCHEMA_V1: () => SCHEMA_V1,
|
|
29
29
|
SKILL_NAME: () => SKILL_NAME,
|
|
30
30
|
TASK_STATUSES: () => TASK_STATUSES,
|
|
31
|
+
deploymentPurpose: () => deploymentPurpose,
|
|
32
|
+
deploymentRequirementIssue: () => deploymentRequirementIssue,
|
|
31
33
|
detectSchema: () => detectSchema,
|
|
32
34
|
parsePlan: () => parsePlan,
|
|
35
|
+
productionActionAllowed: () => productionActionAllowed,
|
|
33
36
|
projectDefinitions: () => projectDefinitions,
|
|
34
37
|
skillNames: () => skillNames,
|
|
35
38
|
toolRefs: () => toolRefs,
|
|
@@ -39,7 +42,7 @@ module.exports = __toCommonJS(read_only_exports);
|
|
|
39
42
|
|
|
40
43
|
// builtin-skills/gateflow-plan/scripts/lib/evm-contract.mjs
|
|
41
44
|
var PROJECT_FIELDS = ["chainFamily", "framework", "projectRoot", "templateProfile", "templateVersion", "mode"];
|
|
42
|
-
var DEPLOYMENT_FIELDS = ["chainFamily", "framework", "projectRoot", "deploymentId", "specPath", "sourceCodeRef", "requiredOperations", "developmentNetwork", "releaseTargetNetworks", "environment", "targetNetwork", "allowedActions", "releaseRef"];
|
|
45
|
+
var DEPLOYMENT_FIELDS = ["purpose", "chainFamily", "framework", "projectRoot", "deploymentId", "specPath", "sourceCodeRef", "requiredOperations", "developmentNetwork", "releaseTargetNetworks", "environment", "targetNetwork", "allowedActions", "releaseRef", "requirementRef", "productionRequirementRef", "referenceDeploymentId"];
|
|
43
46
|
var ANALYSIS_STEPS = ["deployment-request", "deployment-plan", "script"];
|
|
44
47
|
var STEP_ACTIONS = {
|
|
45
48
|
deploy: ["simulate", "execute", "reconcile", "verify"],
|
|
@@ -49,11 +52,53 @@ var STEP_ACTIONS = {
|
|
|
49
52
|
"release-execute": ["execute", "export-calldata", "reconcile"],
|
|
50
53
|
"release-verify": ["verify"]
|
|
51
54
|
};
|
|
55
|
+
var PURPOSE_ACTIONS = {
|
|
56
|
+
"dev-execution": ["simulate", "execute", "reconcile", "verify"],
|
|
57
|
+
"prod-qualification": ["simulate", "verify"],
|
|
58
|
+
"prod-execution": ["simulate", "execute", "export-calldata", "reconcile", "verify"]
|
|
59
|
+
};
|
|
60
|
+
function deploymentPurpose(task) {
|
|
61
|
+
const explicit = task.scope?.deployment?.purpose;
|
|
62
|
+
if (explicit !== void 0) return explicit;
|
|
63
|
+
if (ANALYSIS_STEPS.includes(task.step)) return "analysis";
|
|
64
|
+
if (["deploy", "check-code"].includes(task.step)) return "dev-execution";
|
|
65
|
+
if (task.step === "deploy-test") return "prod-qualification";
|
|
66
|
+
if (["release-prepare", "release-execute", "release-verify"].includes(task.step)) return "prod-execution";
|
|
67
|
+
return void 0;
|
|
68
|
+
}
|
|
69
|
+
function productionActionAllowed(task, intent) {
|
|
70
|
+
const d = task.scope?.deployment;
|
|
71
|
+
const action = intent === "prepare" ? "simulate" : intent;
|
|
72
|
+
return deploymentPurpose(task) === "prod-execution" && d?.environment === "prod" && !!d.releaseRef && Array.isArray(d.allowedActions) && d.allowedActions.includes(action);
|
|
73
|
+
}
|
|
52
74
|
var OPERATIONS = ["deploy", "upgrade", "call", "view", "check", "custom"];
|
|
53
75
|
var isObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
76
|
+
function deploymentRequirementIssue(plan, task) {
|
|
77
|
+
const d = task.scope?.deployment;
|
|
78
|
+
if (!d || deploymentPurpose(task) === "analysis") return null;
|
|
79
|
+
const ref = d.requirementRef;
|
|
80
|
+
if (!ref) return "部署实施前必须引用本轮已确认的需求(requirementRef)";
|
|
81
|
+
const request = Object.values(plan.tasks).flat().find((t) => t.planKey === ref.planKey);
|
|
82
|
+
if (!request || request.status === "cancelled" || deploymentPurpose(request) !== "analysis" || request.scope?.deployment?.projectRoot !== d.projectRoot || request.rev !== ref.rev || request.requirementConfirmation?.rev !== ref.rev) return "本轮部署需求尚未确认或确认修订已失效";
|
|
83
|
+
const r = request.scope.deployment;
|
|
84
|
+
if (d.productionRequirementRef !== void 0) {
|
|
85
|
+
if (!["prod-qualification", "prod-execution"].includes(deploymentPurpose(task))) return "生产补充确认只用于 prod 资格或执行任务";
|
|
86
|
+
const extra = d.productionRequirementRef;
|
|
87
|
+
const production = Object.values(plan.tasks).flat().find((t) => t.planKey === extra.planKey);
|
|
88
|
+
const p = production?.scope?.deployment;
|
|
89
|
+
if (!production || production.status === "cancelled" || deploymentPurpose(production) !== "analysis" || production.rev !== extra.rev || production.requirementConfirmation?.rev !== extra.rev || p?.projectRoot !== d.projectRoot || p?.deploymentId !== d.deploymentId || JSON.stringify(p.requirementRef) !== JSON.stringify(ref)) return "本轮生产补充需求尚未确认或绑定已失效";
|
|
90
|
+
if (!task.dependsOn.includes(production.planKey)) return "生产任务必须依赖其补充需求确认任务";
|
|
91
|
+
if (p.developmentNetwork !== r.developmentNetwork || d.developmentNetwork !== r.developmentNetwork || p.sourceCodeRef !== d.sourceCodeRef || JSON.stringify(p.releaseTargetNetworks) !== JSON.stringify(d.releaseTargetNetworks) || !d.requiredOperations?.every((operation) => p.requiredOperations?.includes(operation) && r.requiredOperations?.includes(operation))) return "生产补充需求只能扩充 prod 网络与参数,不能改变原部署动作或源码";
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
if (r.developmentNetwork !== d.developmentNetwork || JSON.stringify(r.releaseTargetNetworks) !== JSON.stringify(d.releaseTargetNetworks) || !d.requiredOperations?.every((operation) => r.requiredOperations?.includes(operation))) return "部署动作或网络超出本轮确认范围";
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
54
97
|
function validateEvmContracts(plan, fail3) {
|
|
55
98
|
const releases = /* @__PURE__ */ new Map();
|
|
56
99
|
const projects = /* @__PURE__ */ new Map();
|
|
100
|
+
const requirementRounds = /* @__PURE__ */ new Map();
|
|
101
|
+
const roundRequirements = /* @__PURE__ */ new Map();
|
|
57
102
|
const object = (value, where, fields) => {
|
|
58
103
|
if (!isObject(value)) fail3(`${where} 必须是对象`);
|
|
59
104
|
for (const field of Object.keys(value)) if (!fields.includes(field)) fail3(`${where}.${field} 是未知字段`);
|
|
@@ -101,7 +146,7 @@ function validateEvmContracts(plan, fail3) {
|
|
|
101
146
|
if (explicitEvmProject || evmProject && (project !== void 0 || task.step === "project-setup")) {
|
|
102
147
|
const p = object(project, `${where}.project`, PROJECT_FIELDS);
|
|
103
148
|
identity(p, `${where}.project`);
|
|
104
|
-
if (p.templateProfile !== "
|
|
149
|
+
if (p.templateProfile !== "full") fail3(`${where}.project.templateProfile 必须是 full`);
|
|
105
150
|
if (p.templateVersion !== 1) fail3(`${where}.project.templateVersion 必须是 1`);
|
|
106
151
|
if (!["create", "resume"].includes(p.mode)) fail3(`${where}.project.mode 必须是 create 或 resume`);
|
|
107
152
|
const metadata2 = JSON.stringify([p.chainFamily, p.framework, p.templateProfile, p.templateVersion]);
|
|
@@ -113,29 +158,38 @@ function validateEvmContracts(plan, fail3) {
|
|
|
113
158
|
const w = `${where}.deployment`;
|
|
114
159
|
const d = object(task.scope?.deployment, w, DEPLOYMENT_FIELDS);
|
|
115
160
|
identity(d, w);
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if (
|
|
119
|
-
if (
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
161
|
+
const initialAnalysis = d.purpose === "analysis" || d.purpose === void 0 && task.step === "deployment-request";
|
|
162
|
+
if (!initialAnalysis || d.deploymentId !== void 0) identifier(d.deploymentId, `${w}.deploymentId`);
|
|
163
|
+
if (!initialAnalysis || d.specPath !== void 0) relativePath(d.specPath, `${w}.specPath`);
|
|
164
|
+
if (!initialAnalysis || d.sourceCodeRef !== void 0) text(d.sourceCodeRef, `${w}.sourceCodeRef`);
|
|
165
|
+
if (!initialAnalysis || d.requiredOperations !== void 0) strings(d.requiredOperations, `${w}.requiredOperations`, OPERATIONS, 1);
|
|
166
|
+
if (!initialAnalysis || d.developmentNetwork !== void 0) identifier(d.developmentNetwork, `${w}.developmentNetwork`, true);
|
|
167
|
+
if (!initialAnalysis || d.releaseTargetNetworks !== void 0) strings(d.releaseTargetNetworks, `${w}.releaseTargetNetworks`);
|
|
168
|
+
for (const network of d.releaseTargetNetworks ?? []) identifier(network, `${w}.releaseTargetNetworks`, true);
|
|
169
|
+
if (d.referenceDeploymentId !== void 0) identifier(d.referenceDeploymentId, `${w}.referenceDeploymentId`);
|
|
170
|
+
for (const field of ["requirementRef", "productionRequirementRef"]) if (d[field] !== void 0) {
|
|
171
|
+
const ref2 = object(d[field], `${w}.${field}`, ["planKey", "rev"]);
|
|
172
|
+
identifier(ref2.planKey, `${w}.${field}.planKey`);
|
|
173
|
+
if (!Number.isSafeInteger(ref2.rev) || ref2.rev < 1) fail3(`${w}.${field}.rev 必须是正整数`);
|
|
174
|
+
}
|
|
175
|
+
const purpose = deploymentPurpose(task);
|
|
176
|
+
if (d.productionRequirementRef !== void 0 && !["prod-qualification", "prod-execution"].includes(purpose)) fail3(`${w}.productionRequirementRef 只用于 prod 任务`);
|
|
177
|
+
if (!["analysis", ...Object.keys(PURPOSE_ACTIONS)].includes(purpose)) fail3(`${w} 不支持步骤 ${task.step};purpose 必须明确部署用途`);
|
|
178
|
+
if (purpose === "analysis") {
|
|
124
179
|
for (const field of ["environment", "targetNetwork", "allowedActions", "releaseRef"]) {
|
|
125
180
|
if (d[field] !== void 0) fail3(`${w}.${field} 只能用于执行任务`);
|
|
126
181
|
}
|
|
127
182
|
continue;
|
|
128
183
|
}
|
|
129
|
-
const actions = STEP_ACTIONS[task.step];
|
|
130
|
-
|
|
131
|
-
const environment = ["deploy", "check-code"].includes(task.step) ? "dev" : "prod";
|
|
184
|
+
const actions = d.purpose === void 0 ? STEP_ACTIONS[task.step] : PURPOSE_ACTIONS[purpose];
|
|
185
|
+
const environment = purpose === "dev-execution" ? "dev" : "prod";
|
|
132
186
|
if (d.environment !== environment) fail3(`${w}.environment 在 ${task.step} 中必须是 ${environment}`);
|
|
133
187
|
identifier(d.targetNetwork, `${w}.targetNetwork`, true);
|
|
134
188
|
if (environment === "dev" ? d.targetNetwork !== d.developmentNetwork : !d.releaseTargetNetworks.includes(d.targetNetwork)) {
|
|
135
189
|
fail3(`${w}.targetNetwork 与已声明的 ${environment} 网络不一致`);
|
|
136
190
|
}
|
|
137
191
|
strings(d.allowedActions, `${w}.allowedActions`, actions, 1);
|
|
138
|
-
if (
|
|
192
|
+
if (purpose !== "prod-execution") {
|
|
139
193
|
if (d.releaseRef !== void 0) fail3(`${w}.releaseRef 只用于正式发布任务`);
|
|
140
194
|
continue;
|
|
141
195
|
}
|
|
@@ -150,6 +204,18 @@ function validateEvmContracts(plan, fail3) {
|
|
|
150
204
|
releases.set(releaseKey, metadata);
|
|
151
205
|
}
|
|
152
206
|
}
|
|
207
|
+
for (const task of Object.values(plan.tasks).flat()) {
|
|
208
|
+
const d = task.scope?.deployment;
|
|
209
|
+
if (!d?.requirementRef || deploymentPurpose(task) === "analysis") continue;
|
|
210
|
+
const requirement = JSON.stringify([d.projectRoot, d.requirementRef.planKey, d.requirementRef.rev]);
|
|
211
|
+
const round = JSON.stringify([d.projectRoot, d.deploymentId]);
|
|
212
|
+
const existingRound = requirementRounds.get(requirement);
|
|
213
|
+
if (existingRound !== void 0 && existingRound !== d.deploymentId) fail3(`任务 ${task.planKey}.scope.deployment 同一需求修订必须复用 deploymentId=${existingRound},不能因脚本准备、模拟或执行阶段另建部署轮次`);
|
|
214
|
+
const existingRequirement = roundRequirements.get(round);
|
|
215
|
+
if (existingRequirement !== void 0 && existingRequirement !== requirement) fail3(`任务 ${task.planKey}.scope.deployment 同一 deploymentId 必须引用同一需求修订;新业务轮次使用新 deploymentId`);
|
|
216
|
+
requirementRounds.set(requirement, d.deploymentId);
|
|
217
|
+
roundRequirements.set(round, requirement);
|
|
218
|
+
}
|
|
153
219
|
}
|
|
154
220
|
|
|
155
221
|
// builtin-skills/gateflow-plan/scripts/lib/yaml-lite.mjs
|
|
@@ -386,8 +452,8 @@ var TASK_STATUSES = ["pending", "running", "blocked", "completed", "failed", "ca
|
|
|
386
452
|
var FAILURE_CATEGORIES = ["execution_error", "acceptance_failed", "review_rejected", "input_missing"];
|
|
387
453
|
var CONTRACT_FIELDS = ["objective", "acceptance", "dependsOn", "step", "scope", "parameters", "expectedArtifacts", "allowedChanges"];
|
|
388
454
|
var TOOL_FIELDS = ["tools", "toolsOptional", "skills"];
|
|
389
|
-
var DEF_FIELDS = [...CONTRACT_FIELDS, ...TOOL_FIELDS];
|
|
390
|
-
var PROGRESS_FIELDS = ["status", "adoptedRev", "blockedReason", "cancelReason", "result", "previousResult"];
|
|
455
|
+
var DEF_FIELDS = [...CONTRACT_FIELDS, ...TOOL_FIELDS, "executionNotes"];
|
|
456
|
+
var PROGRESS_FIELDS = ["status", "adoptedRev", "blockedReason", "cancelReason", "result", "previousResult", "requirementConfirmation"];
|
|
391
457
|
var TASK_ORDER = ["no", "planKey", "rev", "title", ...DEF_FIELDS, ...PROGRESS_FIELDS];
|
|
392
458
|
var PlanError = class extends Error {
|
|
393
459
|
constructor(message, code = "invalid") {
|
|
@@ -508,11 +574,11 @@ function parseResult(v, where) {
|
|
|
508
574
|
}
|
|
509
575
|
fail2(`${where}.kind 必须是 success 或 failure`);
|
|
510
576
|
}
|
|
511
|
-
var TOOL_REF = /^(?:plugin:[A-Za-z0-9][A-Za-z0-9._-]{0,99}|mcp:[A-Za-z0-9][A-Za-z0-9._-]{0,99}(?:\/[A-Za-z0-9][A-Za-z0-9._-]{0,99})
|
|
577
|
+
var TOOL_REF = /^(?:plugin:[A-Za-z0-9][A-Za-z0-9._-]{0,99}|mcp:[A-Za-z0-9][A-Za-z0-9._-]{0,99}(?:\/[A-Za-z0-9][A-Za-z0-9._-]{0,99})?|host:[A-Za-z0-9][A-Za-z0-9._-]{0,99})$/;
|
|
512
578
|
function toolRefs(v, where) {
|
|
513
579
|
const refs = strArray(v, where);
|
|
514
580
|
refs.forEach((ref, i) => {
|
|
515
|
-
if (!TOOL_REF.test(ref)) fail2(`${where}[${i}] 不是有效的工具引用:"${ref}"(plugin:<id
|
|
581
|
+
if (!TOOL_REF.test(ref)) fail2(`${where}[${i}] 不是有效的工具引用:"${ref}"(plugin:<id>、mcp:<服务器>[/<工具>] 或 host:<本机 Codex 的 MCP>)`);
|
|
516
582
|
});
|
|
517
583
|
if (new Set(refs).size !== refs.length) fail2(`${where} 有重复的工具`);
|
|
518
584
|
return refs;
|
|
@@ -544,6 +610,7 @@ function parseTaskDef(raw, where) {
|
|
|
544
610
|
t.parameters = raw.parameters;
|
|
545
611
|
}
|
|
546
612
|
if (raw.expectedArtifacts !== void 0) t.expectedArtifacts = strArray(raw.expectedArtifacts, `${where}.expectedArtifacts`);
|
|
613
|
+
if (raw.executionNotes !== void 0) t.executionNotes = strArray(raw.executionNotes, `${where}.executionNotes`);
|
|
547
614
|
if (raw.allowedChanges !== void 0) t.allowedChanges = strArray(raw.allowedChanges, `${where}.allowedChanges`);
|
|
548
615
|
if (raw.tools !== void 0) t.tools = toolRefs(raw.tools, `${where}.tools`);
|
|
549
616
|
if (raw.toolsOptional !== void 0) t.toolsOptional = toolRefs(raw.toolsOptional, `${where}.toolsOptional`);
|
|
@@ -567,6 +634,12 @@ function parseTask(raw, where) {
|
|
|
567
634
|
}
|
|
568
635
|
if (raw.blockedReason !== void 0) t.blockedReason = str(raw.blockedReason, `${where}.blockedReason`);
|
|
569
636
|
if (raw.cancelReason !== void 0) t.cancelReason = str(raw.cancelReason, `${where}.cancelReason`);
|
|
637
|
+
if (raw.requirementConfirmation !== void 0) {
|
|
638
|
+
const c = raw.requirementConfirmation;
|
|
639
|
+
if (!isObject2(c) || Object.keys(c).some((k) => !["rev", "confirmedAt"].includes(k))) fail2(`${where}.requirementConfirmation 无效`);
|
|
640
|
+
t.requirementConfirmation = { rev: posInt(c.rev, `${where}.requirementConfirmation.rev`), confirmedAt: str(c.confirmedAt, `${where}.requirementConfirmation.confirmedAt`) };
|
|
641
|
+
if (c.rev > t.rev || !Number.isFinite(Date.parse(c.confirmedAt))) fail2(`${where}.requirementConfirmation 修订或时间无效`);
|
|
642
|
+
}
|
|
570
643
|
const result = parseResult(raw.result, `${where}.result`);
|
|
571
644
|
if (result) t.result = result;
|
|
572
645
|
const previous = parseResult(raw.previousResult, `${where}.previousResult`);
|
|
@@ -747,7 +820,6 @@ function parsePlan(text) {
|
|
|
747
820
|
|
|
748
821
|
// builtin-skills/gateflow-plan/scripts/lib/read-only.mjs
|
|
749
822
|
var DEFINITION_CONTRACT = "gateflow-plan/definition@1";
|
|
750
|
-
var RELEASE_STEPS = /* @__PURE__ */ new Set(["release-prepare", "release-execute", "release-verify"]);
|
|
751
823
|
function freeze(value) {
|
|
752
824
|
if (value && typeof value === "object") {
|
|
753
825
|
Object.values(value).forEach(freeze);
|
|
@@ -774,9 +846,11 @@ function projectDefinitions(text, selection) {
|
|
|
774
846
|
if (selected.has(key2)) return;
|
|
775
847
|
const entry = byKey.get(key2);
|
|
776
848
|
if (!entry) throw new PlanError(`Definition root/dependency missing: ${key2}`);
|
|
777
|
-
if (selection.mode === "upstream" &&
|
|
849
|
+
if (selection.mode === "upstream" && deploymentPurpose(entry.task) === "prod-execution") throw new PlanError(`Upstream definitions cannot include generated release task: ${key2}`);
|
|
778
850
|
selected.add(key2);
|
|
779
851
|
entry.task.dependsOn.forEach(visit);
|
|
852
|
+
const requirement = entry.task.scope?.deployment?.requirementRef;
|
|
853
|
+
if (requirement) visit(requirement.planKey);
|
|
780
854
|
};
|
|
781
855
|
roots.forEach(visit);
|
|
782
856
|
const entries = line.filter(({ task }) => selected.has(task.planKey));
|
|
@@ -811,8 +885,11 @@ function projectDefinitions(text, selection) {
|
|
|
811
885
|
SCHEMA_V1,
|
|
812
886
|
SKILL_NAME,
|
|
813
887
|
TASK_STATUSES,
|
|
888
|
+
deploymentPurpose,
|
|
889
|
+
deploymentRequirementIssue,
|
|
814
890
|
detectSchema,
|
|
815
891
|
parsePlan,
|
|
892
|
+
productionActionAllowed,
|
|
816
893
|
projectDefinitions,
|
|
817
894
|
skillNames,
|
|
818
895
|
toolRefs,
|
|
@@ -11,6 +11,7 @@ export interface PlanTask {
|
|
|
11
11
|
step?: string; scope?: Record<string, unknown>; parameters?: unknown[]; expectedArtifacts?: string[]; allowedChanges?: string[]
|
|
12
12
|
tools?: string[]; toolsOptional?: string[]; skills?: string[]; status: typeof TASK_STATUSES[number]; adoptedRev?: number
|
|
13
13
|
blockedReason?: string; cancelReason?: string; result?: Record<string, unknown>; previousResult?: Record<string, unknown>
|
|
14
|
+
requirementConfirmation?: { rev: number; confirmedAt: string }
|
|
14
15
|
}
|
|
15
16
|
export interface PlanLane { name: string; state: 'enabled' | 'disabled'; reason?: string; skill?: string; steps?: { id: string; name: string }[] }
|
|
16
17
|
export interface Plan {
|
|
@@ -30,3 +31,8 @@ export function projectDefinitions(text: string, selection: DefinitionSelection)
|
|
|
30
31
|
export function skillNames(value: unknown, where: string): string[]
|
|
31
32
|
export function toolRefs(value: unknown, where: string): string[]
|
|
32
33
|
export function validateEvmContracts(plan: { flow?: string; lanes: Record<string, { skill?: string }>; tasks: Record<string, { planKey: string; step?: string; scope?: Record<string, unknown> }[]> }, fail: (message: string) => never): void
|
|
34
|
+
|
|
35
|
+
export type DeploymentPurpose = 'analysis' | 'dev-execution' | 'prod-qualification' | 'prod-execution'
|
|
36
|
+
export function deploymentPurpose(task: {step?: string; scope?: Record<string, unknown>}): DeploymentPurpose | undefined
|
|
37
|
+
export function productionActionAllowed(task: {step?: string; scope?: Record<string, unknown>}, intent: string): boolean
|
|
38
|
+
export function deploymentRequirementIssue(plan: { tasks: Record<string, {planKey:string;rev:number;status:string;step?:string;scope?:Record<string,unknown>;requirementConfirmation?:{rev:number;confirmedAt:string}}[]> }, task: Pick<PlanTask, 'step' | 'scope' | 'dependsOn'>): string | null
|
|
@@ -4,21 +4,22 @@
|
|
|
4
4
|
"version": 1,
|
|
5
5
|
"schema": "gateflow-plan/v2",
|
|
6
6
|
"definitionContract": "gateflow-plan/definition@1",
|
|
7
|
-
"sourceCommit": "
|
|
7
|
+
"sourceCommit": "ee0f90991ca1a94c3f58c8893df16d0c8c41b230",
|
|
8
|
+
"sourceMode": "working-tree",
|
|
8
9
|
"sources": {
|
|
9
|
-
"builtin-skills/gateflow-plan/scripts/lib/evm-contract.mjs": "
|
|
10
|
-
"builtin-skills/gateflow-plan/scripts/lib/handoff-v2.mjs": "
|
|
11
|
-
"builtin-skills/gateflow-plan/scripts/lib/read-only.d.mts": "
|
|
12
|
-
"builtin-skills/gateflow-plan/scripts/lib/read-only.mjs": "
|
|
10
|
+
"builtin-skills/gateflow-plan/scripts/lib/evm-contract.mjs": "c41dd9e6d630ea033001dd0922911bf365ff2baaa894107f6a80a3019eca1c17",
|
|
11
|
+
"builtin-skills/gateflow-plan/scripts/lib/handoff-v2.mjs": "05c89b794b65d6c73dc2427df8dc1b21f06c377c30f2c3baf8517459b8df56e0",
|
|
12
|
+
"builtin-skills/gateflow-plan/scripts/lib/read-only.d.mts": "716d1252adf79d5c7e6c3b7ed17984203ae3e1853695dc04fa9e769c9ac24c50",
|
|
13
|
+
"builtin-skills/gateflow-plan/scripts/lib/read-only.mjs": "1cb928d76ce14b07028efe002e624d91d36168494b5cc2cc0ba35153a311ff3e",
|
|
13
14
|
"builtin-skills/gateflow-plan/scripts/lib/yaml-lite.mjs": "b53b8322b27bb73bbbf2a4254be4698ee43ec79c27828068954afd6d05902784",
|
|
14
|
-
"scripts/build-plan-codec.mjs": "
|
|
15
|
+
"scripts/build-plan-codec.mjs": "048e647687da5a55a9f1899af510b9f1b0eb0872876e5eef278ede89c53c5d75"
|
|
15
16
|
},
|
|
16
17
|
"builder": {
|
|
17
18
|
"name": "esbuild",
|
|
18
19
|
"version": "0.21.5"
|
|
19
20
|
},
|
|
20
21
|
"artifacts": {
|
|
21
|
-
"index.cjs": "
|
|
22
|
-
"index.d.cts": "
|
|
22
|
+
"index.cjs": "1014b59dad45b47510602791e426eaf2ee6d58720583670134fa14431b935d0d",
|
|
23
|
+
"index.d.cts": "716d1252adf79d5c7e6c3b7ed17984203ae3e1853695dc04fa9e769c9ac24c50"
|
|
23
24
|
}
|
|
24
25
|
}
|
|
@@ -252,6 +252,7 @@ export const runContractWriteCalls = async (
|
|
|
252
252
|
operation: 0,
|
|
253
253
|
...(zkSync ? { scheme: "zksync-eravm" as const, factoryDeps: [] } : {}),
|
|
254
254
|
});
|
|
255
|
+
context.calldataReview?.record(planned, { abi: resolved.contract.interface.fragments, method: call.method, args });
|
|
255
256
|
if (planned.executionAction === "replay") {
|
|
256
257
|
context.reporter.result("execution", {
|
|
257
258
|
stepId: planned.stepId,
|