@jinn-network/client 0.1.2 → 0.1.3-canary.2d6b2676
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/CHANGELOG.md +20 -0
- package/CONTRIBUTING.md +8 -2
- package/README.md +68 -42
- package/deployments/deployment-jinn-mvi-l1-sepolia-fast.json +36 -0
- package/deployments/deployment-jinn-mvi-l1-sepolia.json +36 -0
- package/deployments/deployment-jinn-mvi-l2-baseSepolia.json +12 -0
- package/deployments/deployment-phase1b-mech-baseSepolia-fast.json +3 -3
- package/deployments/deployment-stolas-l2-baseSepolia-fast.json +1 -1
- package/dist/adapters/adapter.d.ts +7 -7
- package/dist/adapters/claim-registry/client.d.ts +9 -0
- package/dist/adapters/claim-registry/client.js +22 -2
- package/dist/adapters/claim-registry/client.js.map +1 -1
- package/dist/adapters/local/adapter.d.ts +4 -4
- package/dist/adapters/local/adapter.js +10 -10
- package/dist/adapters/local/adapter.js.map +1 -1
- package/dist/adapters/mech/adapter.d.ts +8 -6
- package/dist/adapters/mech/adapter.js +159 -95
- package/dist/adapters/mech/adapter.js.map +1 -1
- package/dist/adapters/mech/contracts.d.ts +8 -6
- package/dist/adapters/mech/contracts.js +119 -15
- package/dist/adapters/mech/contracts.js.map +1 -1
- package/dist/adapters/mech/ipfs.d.ts +66 -12
- package/dist/adapters/mech/ipfs.js +165 -30
- package/dist/adapters/mech/ipfs.js.map +1 -1
- package/dist/adapters/mech/safe-revert.d.ts +39 -0
- package/dist/adapters/mech/safe-revert.js +130 -0
- package/dist/adapters/mech/safe-revert.js.map +1 -0
- package/dist/adapters/mech/safe.js +48 -22
- package/dist/adapters/mech/safe.js.map +1 -1
- package/dist/adapters/mech/types.d.ts +8 -0
- package/dist/adapters/mech/types.js.map +1 -1
- package/dist/agent/agent-ws.d.ts +55 -0
- package/dist/agent/agent-ws.js +288 -0
- package/dist/agent/agent-ws.js.map +1 -0
- package/dist/agent/auto-mode-detect.d.ts +6 -0
- package/dist/agent/auto-mode-detect.js +44 -0
- package/dist/agent/auto-mode-detect.js.map +1 -0
- package/dist/agent/operator-claude.d.ts +22 -0
- package/dist/agent/operator-claude.js +130 -0
- package/dist/agent/operator-claude.js.map +1 -0
- package/dist/api/admin-endpoint.d.ts +12 -0
- package/dist/api/admin-endpoint.js +71 -0
- package/dist/api/admin-endpoint.js.map +1 -0
- package/dist/api/bootstrap-endpoint.d.ts +16 -0
- package/dist/api/bootstrap-endpoint.js +78 -0
- package/dist/api/bootstrap-endpoint.js.map +1 -0
- package/dist/api/events-endpoint.d.ts +9 -0
- package/dist/api/events-endpoint.js +46 -0
- package/dist/api/events-endpoint.js.map +1 -0
- package/dist/api/fleet-build.d.ts +1 -1
- package/dist/api/fleet-build.js +17 -8
- package/dist/api/fleet-build.js.map +1 -1
- package/dist/api/gather-status.js +6 -2
- package/dist/api/gather-status.js.map +1 -1
- package/dist/api/handshake.d.ts +17 -0
- package/dist/api/handshake.js +28 -0
- package/dist/api/handshake.js.map +1 -0
- package/dist/api/history-build.d.ts +2 -2
- package/dist/api/history-build.js +3 -3
- package/dist/api/history-build.js.map +1 -1
- package/dist/api/peers.js +21 -6
- package/dist/api/peers.js.map +1 -1
- package/dist/api/portfolio-v0-build.d.ts +16 -10
- package/dist/api/portfolio-v0-build.js +36 -31
- package/dist/api/portfolio-v0-build.js.map +1 -1
- package/dist/api/portfolio-v0-doctor.js +1 -1
- package/dist/api/portfolio-v0-doctor.js.map +1 -1
- package/dist/api/rewards-build.js +3 -8
- package/dist/api/rewards-build.js.map +1 -1
- package/dist/api/server.d.ts +55 -1
- package/dist/api/server.js +243 -17
- package/dist/api/server.js.map +1 -1
- package/dist/api/setup-endpoints.d.ts +34 -0
- package/dist/api/setup-endpoints.js +188 -0
- package/dist/api/setup-endpoints.js.map +1 -0
- package/dist/api/status-build.d.ts +10 -2
- package/dist/api/status-build.js +44 -9
- package/dist/api/status-build.js.map +1 -1
- package/dist/api/status-rollup-build.d.ts +46 -1
- package/dist/api/status-rollup-build.js +168 -5
- package/dist/api/status-rollup-build.js.map +1 -1
- package/dist/api/ui-token.d.ts +5 -0
- package/dist/api/ui-token.js +36 -0
- package/dist/api/ui-token.js.map +1 -0
- package/dist/build-info.d.ts +32 -0
- package/dist/build-info.js +69 -0
- package/dist/build-info.js.map +1 -0
- package/dist/build-info.json +6 -0
- package/dist/build-meta.json +1 -1
- package/dist/cli/command.d.ts +9 -0
- package/dist/cli/commands/balance.d.ts +7 -0
- package/dist/cli/commands/balance.js +38 -32
- package/dist/cli/commands/balance.js.map +1 -1
- package/dist/cli/commands/bootstrap.d.ts +13 -1
- package/dist/cli/commands/bootstrap.js +150 -132
- package/dist/cli/commands/bootstrap.js.map +1 -1
- package/dist/cli/commands/claim-rewards.js +14 -2
- package/dist/cli/commands/claim-rewards.js.map +1 -1
- package/dist/cli/commands/conformance.d.ts +12 -0
- package/dist/cli/commands/conformance.js +140 -0
- package/dist/cli/commands/conformance.js.map +1 -0
- package/dist/cli/commands/create.d.ts +22 -0
- package/dist/cli/commands/create.js +226 -0
- package/dist/cli/commands/create.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +34 -1
- package/dist/cli/commands/doctor.js +138 -123
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/fleet-scale.d.ts +19 -1
- package/dist/cli/commands/fleet-scale.js +379 -361
- package/dist/cli/commands/fleet-scale.js.map +1 -1
- package/dist/cli/commands/fleet.d.ts +7 -0
- package/dist/cli/commands/fleet.js +39 -33
- package/dist/cli/commands/fleet.js.map +1 -1
- package/dist/cli/commands/fund-requirements.d.ts +14 -1
- package/dist/cli/commands/fund-requirements.js +183 -174
- package/dist/cli/commands/fund-requirements.js.map +1 -1
- package/dist/cli/commands/harnesses.d.ts +18 -0
- package/dist/cli/commands/harnesses.js +208 -0
- package/dist/cli/commands/harnesses.js.map +1 -0
- package/dist/cli/commands/history.d.ts +10 -1
- package/dist/cli/commands/history.js +68 -59
- package/dist/cli/commands/history.js.map +1 -1
- package/dist/cli/commands/init.js +4 -1
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/integrations.d.ts +13 -0
- package/dist/cli/commands/{plugin-install.js → integrations.js} +240 -33
- package/dist/cli/commands/integrations.js.map +1 -0
- package/dist/cli/commands/logs.d.ts +6 -1
- package/dist/cli/commands/logs.js +77 -70
- package/dist/cli/commands/logs.js.map +1 -1
- package/dist/cli/commands/migrate-agent-id.d.ts +26 -0
- package/dist/cli/commands/migrate-agent-id.js +165 -0
- package/dist/cli/commands/migrate-agent-id.js.map +1 -0
- package/dist/cli/commands/quickstart.d.ts +51 -1
- package/dist/cli/commands/quickstart.js +514 -296
- package/dist/cli/commands/quickstart.js.map +1 -1
- package/dist/cli/commands/rewards.d.ts +7 -0
- package/dist/cli/commands/rewards.js +46 -40
- package/dist/cli/commands/rewards.js.map +1 -1
- package/dist/cli/commands/run.d.ts +14 -1
- package/dist/cli/commands/run.js +233 -91
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/commands/solver-nets.js +207 -0
- package/dist/cli/commands/solver-nets.js.map +1 -0
- package/dist/cli/commands/solver-plugins.d.ts +9 -0
- package/dist/cli/commands/solver-plugins.js +184 -0
- package/dist/cli/commands/solver-plugins.js.map +1 -0
- package/dist/cli/commands/status.d.ts +10 -0
- package/dist/cli/commands/status.js +97 -34
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/tasks.js +365 -0
- package/dist/cli/commands/tasks.js.map +1 -0
- package/dist/cli/commands/ui.d.ts +3 -0
- package/dist/cli/commands/ui.js +45 -0
- package/dist/cli/commands/ui.js.map +1 -0
- package/dist/cli/commands/update.d.ts +5 -0
- package/dist/cli/commands/update.js +110 -105
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/commands/version.js +3 -1
- package/dist/cli/commands/version.js.map +1 -1
- package/dist/cli/commands/withdraw.d.ts +21 -1
- package/dist/cli/commands/withdraw.js +175 -159
- package/dist/cli/commands/withdraw.js.map +1 -1
- package/dist/cli/execution-context.d.ts +1 -1
- package/dist/cli/execution-context.js +4 -3
- package/dist/cli/execution-context.js.map +1 -1
- package/dist/cli/help.js +8 -1
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.js +24 -6
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/open-browser.d.ts +1 -0
- package/dist/cli/open-browser.js +18 -0
- package/dist/cli/open-browser.js.map +1 -0
- package/dist/cli/password.d.ts +3 -3
- package/dist/cli/password.js +6 -6
- package/dist/cli/password.js.map +1 -1
- package/dist/config.d.ts +1232 -53
- package/dist/config.js +558 -24
- package/dist/config.js.map +1 -1
- package/dist/conformance/checks/artifacts.d.ts +37 -0
- package/dist/conformance/checks/artifacts.js +110 -0
- package/dist/conformance/checks/artifacts.js.map +1 -0
- package/dist/conformance/checks/envelope-schema.d.ts +17 -0
- package/dist/conformance/checks/envelope-schema.js +36 -0
- package/dist/conformance/checks/envelope-schema.js.map +1 -0
- package/dist/conformance/checks/hash-signature.d.ts +26 -0
- package/dist/conformance/checks/hash-signature.js +70 -0
- package/dist/conformance/checks/hash-signature.js.map +1 -0
- package/dist/conformance/checks/payload.d.ts +19 -0
- package/dist/conformance/checks/payload.js +52 -0
- package/dist/conformance/checks/payload.js.map +1 -0
- package/dist/conformance/checks/secret-scrub.d.ts +33 -0
- package/dist/conformance/checks/secret-scrub.js +118 -0
- package/dist/conformance/checks/secret-scrub.js.map +1 -0
- package/dist/conformance/checks/source-runtime.d.ts +43 -0
- package/dist/conformance/checks/source-runtime.js +68 -0
- package/dist/conformance/checks/source-runtime.js.map +1 -0
- package/dist/conformance/checks/source-static.d.ts +61 -0
- package/dist/conformance/checks/source-static.js +311 -0
- package/dist/conformance/checks/source-static.js.map +1 -0
- package/dist/conformance/checks/trajectory-chain.d.ts +18 -0
- package/dist/conformance/checks/trajectory-chain.js +51 -0
- package/dist/conformance/checks/trajectory-chain.js.map +1 -0
- package/dist/conformance/checks/trajectory-profile.d.ts +17 -0
- package/dist/conformance/checks/trajectory-profile.js +51 -0
- package/dist/conformance/checks/trajectory-profile.js.map +1 -0
- package/dist/conformance/checks/trajectory-schema.d.ts +20 -0
- package/dist/conformance/checks/trajectory-schema.js +40 -0
- package/dist/conformance/checks/trajectory-schema.js.map +1 -0
- package/dist/conformance/checks/verdict.d.ts +44 -0
- package/dist/conformance/checks/verdict.js +122 -0
- package/dist/conformance/checks/verdict.js.map +1 -0
- package/dist/conformance/harness.d.ts +32 -0
- package/dist/conformance/harness.js +227 -0
- package/dist/conformance/harness.js.map +1 -0
- package/dist/conformance/types.d.ts +88 -0
- package/dist/conformance/types.js +31 -0
- package/dist/conformance/types.js.map +1 -0
- package/dist/corpus/acquire.d.ts +37 -0
- package/dist/corpus/acquire.js +155 -0
- package/dist/corpus/acquire.js.map +1 -0
- package/dist/corpus/cache.d.ts +14 -0
- package/dist/corpus/cache.js +18 -0
- package/dist/corpus/cache.js.map +1 -0
- package/dist/corpus/fetch.d.ts +9 -0
- package/dist/corpus/fetch.js +24 -0
- package/dist/corpus/fetch.js.map +1 -0
- package/dist/corpus/index.d.ts +16 -0
- package/dist/corpus/index.js +78 -0
- package/dist/corpus/index.js.map +1 -0
- package/dist/corpus/query.d.ts +17 -0
- package/dist/corpus/query.js +108 -0
- package/dist/corpus/query.js.map +1 -0
- package/dist/corpus/route-resolver.d.ts +16 -0
- package/dist/corpus/route-resolver.js +20 -0
- package/dist/corpus/route-resolver.js.map +1 -0
- package/dist/corpus/types.d.ts +108 -0
- package/dist/corpus/types.js +50 -0
- package/dist/corpus/types.js.map +1 -0
- package/dist/daemon/balance-topup-loop.js +2 -1
- package/dist/daemon/balance-topup-loop.js.map +1 -1
- package/dist/daemon/creator.d.ts +5 -5
- package/dist/daemon/creator.js +8 -11
- package/dist/daemon/creator.js.map +1 -1
- package/dist/daemon/daemon.d.ts +84 -29
- package/dist/daemon/daemon.js +181 -63
- package/dist/daemon/daemon.js.map +1 -1
- package/dist/daemon/delivery-watcher.js +34 -4
- package/dist/daemon/delivery-watcher.js.map +1 -1
- package/dist/daemon/jinn-claim-loop-canonical.d.ts +207 -0
- package/dist/daemon/jinn-claim-loop-canonical.js +296 -0
- package/dist/daemon/jinn-claim-loop-canonical.js.map +1 -0
- package/dist/daemon/jinn-claim-loop-mock.d.ts +61 -0
- package/dist/daemon/jinn-claim-loop-mock.js +122 -0
- package/dist/daemon/jinn-claim-loop-mock.js.map +1 -0
- package/dist/daemon/jinn-claim-loop.d.ts +123 -0
- package/dist/daemon/jinn-claim-loop.js +256 -0
- package/dist/daemon/jinn-claim-loop.js.map +1 -0
- package/dist/daemon/reward-claim-loop.d.ts +2 -0
- package/dist/daemon/reward-claim-loop.js +32 -27
- package/dist/daemon/reward-claim-loop.js.map +1 -1
- package/dist/dashboard/assets/index-Bxlk5qpa.js +68 -0
- package/dist/dashboard/assets/index-DQ3u_vP5.css +32 -0
- package/dist/dashboard/index.html +18 -74
- package/dist/earning/agent-wallet-binding.d.ts +133 -0
- package/dist/earning/agent-wallet-binding.js +202 -0
- package/dist/earning/agent-wallet-binding.js.map +1 -0
- package/dist/earning/bootstrap.d.ts +64 -0
- package/dist/earning/bootstrap.js +325 -32
- package/dist/earning/bootstrap.js.map +1 -1
- package/dist/earning/contracts.d.ts +323 -0
- package/dist/earning/contracts.js +276 -0
- package/dist/earning/contracts.js.map +1 -1
- package/dist/earning/evidence-simhash.d.ts +1 -1
- package/dist/earning/funding-plan.d.ts +90 -0
- package/dist/earning/funding-plan.js +203 -0
- package/dist/earning/funding-plan.js.map +1 -0
- package/dist/earning/migrate-agent-id.d.ts +130 -0
- package/dist/earning/migrate-agent-id.js +257 -0
- package/dist/earning/migrate-agent-id.js.map +1 -0
- package/dist/earning/orphan-sweep.d.ts +14 -0
- package/dist/earning/orphan-sweep.js +63 -2
- package/dist/earning/orphan-sweep.js.map +1 -1
- package/dist/earning/reconcile.d.ts +2 -0
- package/dist/earning/reconcile.js +30 -0
- package/dist/earning/reconcile.js.map +1 -1
- package/dist/earning/stolas-claim.d.ts +86 -6
- package/dist/earning/stolas-claim.js +123 -9
- package/dist/earning/stolas-claim.js.map +1 -1
- package/dist/earning/store.d.ts +39 -0
- package/dist/earning/store.js +72 -1
- package/dist/earning/store.js.map +1 -1
- package/dist/earning/testnet-setup-migration.d.ts +32 -0
- package/dist/earning/testnet-setup-migration.js +214 -0
- package/dist/earning/testnet-setup-migration.js.map +1 -0
- package/dist/earning/types.d.ts +53 -9
- package/dist/earning/types.js +51 -2
- package/dist/earning/types.js.map +1 -1
- package/dist/earning/viem-clients.d.ts +20 -0
- package/dist/earning/viem-clients.js +32 -1
- package/dist/earning/viem-clients.js.map +1 -1
- package/dist/erc8004/abis.d.ts +381 -0
- package/dist/erc8004/abis.js +238 -0
- package/dist/erc8004/abis.js.map +1 -0
- package/dist/erc8004/addresses.d.ts +40 -0
- package/dist/erc8004/addresses.js +64 -0
- package/dist/erc8004/addresses.js.map +1 -0
- package/dist/erc8004/identity.d.ts +202 -0
- package/dist/erc8004/identity.js +305 -0
- package/dist/erc8004/identity.js.map +1 -0
- package/dist/erc8004/index.d.ts +13 -0
- package/dist/erc8004/index.js +20 -0
- package/dist/erc8004/index.js.map +1 -0
- package/dist/erc8004/reputation.d.ts +349 -0
- package/dist/erc8004/reputation.js +464 -0
- package/dist/erc8004/reputation.js.map +1 -0
- package/dist/erc8004/subgraph.d.ts +46 -0
- package/dist/erc8004/subgraph.js +37 -0
- package/dist/erc8004/subgraph.js.map +1 -0
- package/dist/erc8004/validation.d.ts +145 -0
- package/dist/erc8004/validation.js +219 -0
- package/dist/erc8004/validation.js.map +1 -0
- package/dist/errors/persisted-bootstrap-error.d.ts +4 -0
- package/dist/errors/persisted-bootstrap-error.js +50 -0
- package/dist/errors/persisted-bootstrap-error.js.map +1 -0
- package/dist/events/emitter.d.ts +12 -0
- package/dist/events/emitter.js +23 -0
- package/dist/events/emitter.js.map +1 -0
- package/dist/events/ring-buffer.d.ts +25 -0
- package/dist/events/ring-buffer.js +46 -0
- package/dist/events/ring-buffer.js.map +1 -0
- package/dist/events/types.d.ts +42 -0
- package/dist/events/types.js +28 -0
- package/dist/events/types.js.map +1 -0
- package/dist/harnesses/capability/index.d.ts +82 -0
- package/dist/harnesses/capability/index.js +12 -0
- package/dist/harnesses/capability/index.js.map +1 -0
- package/dist/harnesses/capability/scoped-rpc.d.ts +12 -0
- package/dist/harnesses/capability/scoped-rpc.js +34 -0
- package/dist/harnesses/capability/scoped-rpc.js.map +1 -0
- package/dist/harnesses/capability/scoped-secrets.d.ts +8 -0
- package/dist/harnesses/capability/scoped-secrets.js +10 -0
- package/dist/harnesses/capability/scoped-secrets.js.map +1 -0
- package/dist/harnesses/capability/scoped-signer.d.ts +46 -0
- package/dist/harnesses/capability/scoped-signer.js +73 -0
- package/dist/harnesses/capability/scoped-signer.js.map +1 -0
- package/dist/harnesses/engine/canonical-json.d.ts +1 -0
- package/dist/harnesses/engine/canonical-json.js +66 -0
- package/dist/harnesses/engine/canonical-json.js.map +1 -0
- package/dist/{restorer → harnesses}/engine/claim.d.ts +7 -7
- package/dist/{restorer → harnesses}/engine/claim.js +14 -7
- package/dist/harnesses/engine/claim.js.map +1 -0
- package/dist/{restorer → harnesses}/engine/delivery.d.ts +3 -1
- package/dist/{restorer → harnesses}/engine/delivery.js +8 -8
- package/dist/harnesses/engine/delivery.js.map +1 -0
- package/dist/harnesses/engine/engine.d.ts +341 -0
- package/dist/harnesses/engine/engine.js +1203 -0
- package/dist/harnesses/engine/engine.js.map +1 -0
- package/dist/harnesses/engine/envelope-assembly.d.ts +72 -0
- package/dist/harnesses/engine/envelope-assembly.js +60 -0
- package/dist/harnesses/engine/envelope-assembly.js.map +1 -0
- package/dist/harnesses/engine/packaging.d.ts +87 -0
- package/dist/{restorer → harnesses}/engine/packaging.js +83 -57
- package/dist/harnesses/engine/packaging.js.map +1 -0
- package/dist/harnesses/engine/persistence.d.ts +172 -0
- package/dist/{restorer → harnesses}/engine/persistence.js +78 -71
- package/dist/harnesses/engine/persistence.js.map +1 -0
- package/dist/harnesses/engine/recovery.d.ts +22 -0
- package/dist/{restorer → harnesses}/engine/recovery.js +5 -5
- package/dist/harnesses/engine/recovery.js.map +1 -0
- package/dist/harnesses/engine/registry.d.ts +53 -0
- package/dist/harnesses/engine/registry.js +62 -0
- package/dist/harnesses/engine/registry.js.map +1 -0
- package/dist/{restorer → harnesses}/engine/signing.d.ts +1 -1
- package/dist/{restorer → harnesses}/engine/signing.js +1 -1
- package/dist/harnesses/engine/signing.js.map +1 -0
- package/dist/{restorer → harnesses}/engine/state.d.ts +8 -8
- package/dist/{restorer → harnesses}/engine/state.js +23 -23
- package/dist/harnesses/engine/state.js.map +1 -0
- package/dist/harnesses/engine/validate-manifest.d.ts +23 -0
- package/dist/harnesses/engine/validate-manifest.js +49 -0
- package/dist/harnesses/engine/validate-manifest.js.map +1 -0
- package/dist/harnesses/engine/verification-stub.d.ts +18 -0
- package/dist/harnesses/engine/verification-stub.js +18 -0
- package/dist/harnesses/engine/verification-stub.js.map +1 -0
- package/dist/harnesses/external-impls/index.d.ts +3 -0
- package/dist/harnesses/external-impls/index.js +2 -0
- package/dist/harnesses/external-impls/index.js.map +1 -0
- package/dist/harnesses/external-impls/loader.d.ts +50 -0
- package/dist/harnesses/external-impls/loader.js +139 -0
- package/dist/harnesses/external-impls/loader.js.map +1 -0
- package/dist/harnesses/external-impls/package-hash.d.ts +26 -0
- package/dist/harnesses/external-impls/package-hash.js +102 -0
- package/dist/harnesses/external-impls/package-hash.js.map +1 -0
- package/dist/harnesses/external-impls/types.d.ts +42 -0
- package/dist/harnesses/external-impls/types.js +10 -0
- package/dist/harnesses/external-impls/types.js.map +1 -0
- package/dist/harnesses/impls/claude-code-learner/adapters/claude-code.d.ts +38 -0
- package/dist/harnesses/impls/claude-code-learner/adapters/claude-code.js +159 -0
- package/dist/harnesses/impls/claude-code-learner/adapters/claude-code.js.map +1 -0
- package/dist/harnesses/impls/claude-code-learner/harness.d.ts +22 -0
- package/dist/harnesses/impls/claude-code-learner/harness.js +44 -0
- package/dist/harnesses/impls/claude-code-learner/harness.js.map +1 -0
- package/dist/harnesses/impls/claude-code-learner/harvest.d.ts +19 -0
- package/dist/harnesses/impls/claude-code-learner/harvest.js +146 -0
- package/dist/harnesses/impls/claude-code-learner/harvest.js.map +1 -0
- package/dist/harnesses/impls/claude-code-learner/index.d.ts +14 -0
- package/dist/harnesses/impls/claude-code-learner/index.js +13 -0
- package/dist/harnesses/impls/claude-code-learner/index.js.map +1 -0
- package/dist/harnesses/impls/claude-code-learner/plugin-path.d.ts +14 -0
- package/dist/harnesses/impls/claude-code-learner/plugin-path.js +30 -0
- package/dist/harnesses/impls/claude-code-learner/plugin-path.js.map +1 -0
- package/dist/harnesses/impls/claude-code-learner/test-utils/fake-plugin-outputs.d.ts +19 -0
- package/dist/harnesses/impls/claude-code-learner/test-utils/fake-plugin-outputs.js +111 -0
- package/dist/harnesses/impls/claude-code-learner/test-utils/fake-plugin-outputs.js.map +1 -0
- package/dist/harnesses/impls/claude-code-learner/test-utils/noop-adapter.d.ts +22 -0
- package/dist/harnesses/impls/claude-code-learner/test-utils/noop-adapter.js +35 -0
- package/dist/harnesses/impls/claude-code-learner/test-utils/noop-adapter.js.map +1 -0
- package/dist/harnesses/impls/claude-code-learner/types.d.ts +102 -0
- package/dist/harnesses/impls/claude-code-learner/types.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/claude-mcp-hyperliquid/api-wallet.d.ts +1 -1
- package/dist/harnesses/impls/claude-mcp-hyperliquid/api-wallet.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/claude-mcp-hyperliquid/index.d.ts +16 -14
- package/dist/{restorer → harnesses}/impls/claude-mcp-hyperliquid/index.js +62 -61
- package/dist/harnesses/impls/claude-mcp-hyperliquid/index.js.map +1 -0
- package/dist/harnesses/impls/claude-mcp-hyperliquid/mcp-tools.js.map +1 -0
- package/dist/harnesses/impls/claude-mcp-hyperliquid/safety-rails.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/claude-mcp-hyperliquid/session-orchestrator.d.ts +7 -0
- package/dist/{restorer → harnesses}/impls/claude-mcp-hyperliquid/session-orchestrator.js +38 -0
- package/dist/harnesses/impls/claude-mcp-hyperliquid/session-orchestrator.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/claude-mcp-prediction/index.d.ts +11 -11
- package/dist/{restorer → harnesses}/impls/claude-mcp-prediction/index.js +26 -16
- package/dist/harnesses/impls/claude-mcp-prediction/index.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/claude-mcp-prediction/mcp-tools.js +1 -1
- package/dist/harnesses/impls/claude-mcp-prediction/mcp-tools.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/claude-mcp-prediction/prompt.d.ts +2 -2
- package/dist/{restorer → harnesses}/impls/claude-mcp-prediction/prompt.js +5 -5
- package/dist/harnesses/impls/claude-mcp-prediction/prompt.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/claude-mcp-prediction/session-orchestrator.d.ts +9 -2
- package/dist/harnesses/impls/claude-mcp-prediction/session-orchestrator.js +21 -0
- package/dist/harnesses/impls/claude-mcp-prediction/session-orchestrator.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/claude-mcp-prediction/types.d.ts +3 -3
- package/dist/harnesses/impls/claude-mcp-prediction/types.js +6 -0
- package/dist/harnesses/impls/claude-mcp-prediction/types.js.map +1 -0
- package/dist/harnesses/impls/claude-mcp-prediction-apy/index.d.ts +36 -0
- package/dist/{restorer → harnesses}/impls/claude-mcp-prediction-apy/index.js +22 -15
- package/dist/harnesses/impls/claude-mcp-prediction-apy/index.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/claude-mcp-prediction-apy/mcp-tools.js +1 -1
- package/dist/harnesses/impls/claude-mcp-prediction-apy/mcp-tools.js.map +1 -0
- package/dist/harnesses/impls/claude-mcp-prediction-apy/prompt.d.ts +7 -0
- package/dist/{restorer → harnesses}/impls/claude-mcp-prediction-apy/prompt.js +5 -5
- package/dist/harnesses/impls/claude-mcp-prediction-apy/prompt.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/claude-mcp-prediction-apy/session-orchestrator.d.ts +10 -0
- package/dist/harnesses/impls/claude-mcp-prediction-apy/session-orchestrator.js +19 -0
- package/dist/harnesses/impls/claude-mcp-prediction-apy/session-orchestrator.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/claude-mcp-prediction-apy/types.d.ts +1 -1
- package/dist/harnesses/impls/claude-mcp-prediction-apy/types.js +6 -0
- package/dist/harnesses/impls/claude-mcp-prediction-apy/types.js.map +1 -0
- package/dist/harnesses/impls/claude-mcp-shared/single-session-orchestrator.d.ts +84 -0
- package/dist/{restorer/impls/claude-mcp-prediction/session-orchestrator.js → harnesses/impls/claude-mcp-shared/single-session-orchestrator.js} +85 -16
- package/dist/harnesses/impls/claude-mcp-shared/single-session-orchestrator.js.map +1 -0
- package/dist/harnesses/impls/evaluation-context.d.ts +23 -0
- package/dist/harnesses/impls/evaluation-context.js +25 -0
- package/dist/harnesses/impls/evaluation-context.js.map +1 -0
- package/dist/harnesses/impls/index.d.ts +74 -0
- package/dist/{restorer → harnesses}/impls/index.js +32 -7
- package/dist/harnesses/impls/index.js.map +1 -0
- package/dist/harnesses/impls/legacy-claude/index.d.ts +66 -0
- package/dist/{restorer → harnesses}/impls/legacy-claude/index.js +47 -19
- package/dist/harnesses/impls/legacy-claude/index.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/portfolio-v0-evaluator/canonical-metrics.d.ts +2 -2
- package/dist/{restorer → harnesses}/impls/portfolio-v0-evaluator/canonical-metrics.js +2 -2
- package/dist/harnesses/impls/portfolio-v0-evaluator/canonical-metrics.js.map +1 -0
- package/dist/harnesses/impls/portfolio-v0-evaluator/checks/availability.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/portfolio-v0-evaluator/checks/consistency.d.ts +1 -1
- package/dist/{restorer → harnesses}/impls/portfolio-v0-evaluator/checks/consistency.js +1 -1
- package/dist/harnesses/impls/portfolio-v0-evaluator/checks/consistency.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/portfolio-v0-evaluator/checks/eligibility.d.ts +2 -2
- package/dist/{restorer → harnesses}/impls/portfolio-v0-evaluator/checks/eligibility.js +2 -2
- package/dist/harnesses/impls/portfolio-v0-evaluator/checks/eligibility.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/portfolio-v0-evaluator/checks/integrity.d.ts +2 -2
- package/dist/{restorer → harnesses}/impls/portfolio-v0-evaluator/checks/integrity.js +2 -2
- package/dist/harnesses/impls/portfolio-v0-evaluator/checks/integrity.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/portfolio-v0-evaluator/checks/spec.d.ts +2 -2
- package/dist/{restorer → harnesses}/impls/portfolio-v0-evaluator/checks/spec.js +2 -2
- package/dist/harnesses/impls/portfolio-v0-evaluator/checks/spec.js.map +1 -0
- package/dist/harnesses/impls/portfolio-v0-evaluator/index.d.ts +44 -0
- package/dist/{restorer → harnesses}/impls/portfolio-v0-evaluator/index.js +217 -88
- package/dist/harnesses/impls/portfolio-v0-evaluator/index.js.map +1 -0
- package/dist/harnesses/impls/portfolio-v0-evaluator/score.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/portfolio-v0-evaluator/types.d.ts +1 -1
- package/dist/harnesses/impls/portfolio-v0-evaluator/types.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/prediction-apy-v0-baseline/index.d.ts +10 -8
- package/dist/{restorer → harnesses}/impls/prediction-apy-v0-baseline/index.js +15 -8
- package/dist/harnesses/impls/prediction-apy-v0-baseline/index.js.map +1 -0
- package/dist/harnesses/impls/prediction-apy-v0-baseline/strategy.js.map +1 -0
- package/dist/harnesses/impls/prediction-apy-v0-baseline/types.js.map +1 -0
- package/dist/harnesses/impls/prediction-apy-v0-evaluator/canonical-metrics.d.ts +6 -0
- package/dist/harnesses/impls/prediction-apy-v0-evaluator/canonical-metrics.js +11 -0
- package/dist/harnesses/impls/prediction-apy-v0-evaluator/canonical-metrics.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/prediction-apy-v0-evaluator/index.d.ts +9 -9
- package/dist/harnesses/impls/prediction-apy-v0-evaluator/index.js +346 -0
- package/dist/harnesses/impls/prediction-apy-v0-evaluator/index.js.map +1 -0
- package/dist/harnesses/impls/prediction-apy-v0-evaluator/parse-submission.d.ts +16 -0
- package/dist/harnesses/impls/prediction-apy-v0-evaluator/parse-submission.js +22 -0
- package/dist/harnesses/impls/prediction-apy-v0-evaluator/parse-submission.js.map +1 -0
- package/dist/harnesses/impls/prediction-apy-v0-evaluator/score.js.map +1 -0
- package/dist/harnesses/impls/prediction-apy-v0-evaluator/types.js.map +1 -0
- package/dist/harnesses/impls/prediction-v0-baseline/index.d.ts +33 -0
- package/dist/{restorer → harnesses}/impls/prediction-v0-baseline/index.js +25 -16
- package/dist/harnesses/impls/prediction-v0-baseline/index.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/prediction-v0-baseline/strategy.d.ts +2 -2
- package/dist/{restorer → harnesses}/impls/prediction-v0-baseline/strategy.js +2 -2
- package/dist/harnesses/impls/prediction-v0-baseline/strategy.js.map +1 -0
- package/dist/harnesses/impls/prediction-v0-baseline/types.d.ts +7 -0
- package/dist/harnesses/impls/prediction-v0-baseline/types.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/prediction-v0-evaluator/canonical-metrics.d.ts +2 -2
- package/dist/harnesses/impls/prediction-v0-evaluator/canonical-metrics.js.map +1 -0
- package/dist/harnesses/impls/prediction-v0-evaluator/checks/availability.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/prediction-v0-evaluator/checks/eligibility.d.ts +1 -1
- package/dist/harnesses/impls/prediction-v0-evaluator/checks/eligibility.js.map +1 -0
- package/dist/harnesses/impls/prediction-v0-evaluator/checks/integrity.d.ts +15 -0
- package/dist/{restorer → harnesses}/impls/prediction-v0-evaluator/checks/integrity.js +12 -12
- package/dist/harnesses/impls/prediction-v0-evaluator/checks/integrity.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/prediction-v0-evaluator/checks/spec.d.ts +2 -2
- package/dist/harnesses/impls/prediction-v0-evaluator/checks/spec.js.map +1 -0
- package/dist/{restorer → harnesses}/impls/prediction-v0-evaluator/index.d.ts +10 -10
- package/dist/harnesses/impls/prediction-v0-evaluator/index.js +342 -0
- package/dist/harnesses/impls/prediction-v0-evaluator/index.js.map +1 -0
- package/dist/harnesses/impls/prediction-v0-evaluator/score.js.map +1 -0
- package/dist/harnesses/impls/prediction-v0-evaluator/types.js +2 -0
- package/dist/harnesses/impls/prediction-v0-evaluator/types.js.map +1 -0
- package/dist/harnesses/manifest/index.d.ts +3 -0
- package/dist/harnesses/manifest/index.js +3 -0
- package/dist/harnesses/manifest/index.js.map +1 -0
- package/dist/harnesses/manifest/load.d.ts +7 -0
- package/dist/harnesses/manifest/load.js +49 -0
- package/dist/harnesses/manifest/load.js.map +1 -0
- package/dist/harnesses/manifest/types.d.ts +75 -0
- package/dist/harnesses/manifest/types.js +8 -0
- package/dist/harnesses/manifest/types.js.map +1 -0
- package/dist/harnesses/manifest/verify.d.ts +15 -0
- package/dist/harnesses/manifest/verify.js +53 -0
- package/dist/harnesses/manifest/verify.js.map +1 -0
- package/dist/harnesses/types.d.ts +263 -0
- package/dist/{restorer → harnesses}/types.js +3 -3
- package/dist/harnesses/types.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/main.d.ts +5 -2
- package/dist/main.js +793 -96
- package/dist/main.js.map +1 -1
- package/dist/mcp/acquire-artifact.d.ts +39 -0
- package/dist/mcp/acquire-artifact.js +163 -0
- package/dist/mcp/acquire-artifact.js.map +1 -0
- package/dist/mcp/operator-server.d.ts +21 -4
- package/dist/mcp/operator-server.js +505 -30
- package/dist/mcp/operator-server.js.map +1 -1
- package/dist/mcp/search-artifacts.d.ts +31 -0
- package/dist/mcp/search-artifacts.js +40 -0
- package/dist/mcp/search-artifacts.js.map +1 -0
- package/dist/mcp/server.d.ts +4 -4
- package/dist/mcp/server.js +110 -64
- package/dist/mcp/server.js.map +1 -1
- package/dist/observability/emit-event.d.ts +2 -2
- package/dist/observability/emit-event.js +2 -2
- package/dist/observability/emit-event.js.map +1 -1
- package/dist/operator-errors.js +4 -5
- package/dist/operator-errors.js.map +1 -1
- package/dist/plugins/digest.d.ts +1 -0
- package/dist/plugins/digest.js +28 -0
- package/dist/plugins/digest.js.map +1 -0
- package/dist/plugins/index.d.ts +6 -0
- package/dist/plugins/index.js +6 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/manifest.d.ts +7 -0
- package/dist/plugins/manifest.js +22 -0
- package/dist/plugins/manifest.js.map +1 -0
- package/dist/plugins/registry.d.ts +9 -0
- package/dist/plugins/registry.js +24 -0
- package/dist/plugins/registry.js.map +1 -0
- package/dist/plugins/resolvers.d.ts +2 -0
- package/dist/plugins/resolvers.js +87 -0
- package/dist/plugins/resolvers.js.map +1 -0
- package/dist/plugins/types.d.ts +39 -0
- package/dist/plugins/types.js +2 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/plugins/validator.d.ts +3 -0
- package/dist/plugins/validator.js +44 -0
- package/dist/plugins/validator.js.map +1 -0
- package/dist/preflight/claude-auth.d.ts +11 -11
- package/dist/preflight/claude-auth.js +18 -32
- package/dist/preflight/claude-auth.js.map +1 -1
- package/dist/runner/claude.d.ts +3 -3
- package/dist/runner/claude.js +62 -26
- package/dist/runner/claude.js.map +1 -1
- package/dist/runner/runner.d.ts +29 -2
- package/dist/runner/simple.d.ts +2 -2
- package/dist/runner/simple.js +2 -2
- package/dist/runner/simple.js.map +1 -1
- package/dist/scripts/fix-node-pty.mjs +62 -0
- package/dist/setup-mode.d.ts +34 -0
- package/dist/setup-mode.js +49 -0
- package/dist/setup-mode.js.map +1 -0
- package/dist/solver-nets/registry.d.ts +33 -0
- package/dist/solver-nets/registry.js +66 -0
- package/dist/solver-nets/registry.js.map +1 -0
- package/dist/solver-types/constants.js.map +1 -0
- package/dist/solver-types/index.d.ts +38 -0
- package/dist/solver-types/index.js +57 -0
- package/dist/solver-types/index.js.map +1 -0
- package/dist/solver-types/learner-loop-test.d.ts +2 -0
- package/dist/solver-types/learner-loop-test.js +39 -0
- package/dist/solver-types/learner-loop-test.js.map +1 -0
- package/dist/solver-types/portfolio-v0.d.ts +2 -0
- package/dist/solver-types/portfolio-v0.js +13 -0
- package/dist/solver-types/portfolio-v0.js.map +1 -0
- package/dist/solver-types/prediction-apy-v0-auto.d.ts +21 -0
- package/dist/solver-types/prediction-apy-v0-auto.js +80 -0
- package/dist/solver-types/prediction-apy-v0-auto.js.map +1 -0
- package/dist/{intents → solver-types}/prediction-apy-v0-template.d.ts +2 -2
- package/dist/{intents → solver-types}/prediction-apy-v0-template.js +2 -2
- package/dist/solver-types/prediction-apy-v0-template.js.map +1 -0
- package/dist/solver-types/prediction-apy-v0.d.ts +3 -0
- package/dist/solver-types/prediction-apy-v0.js +25 -0
- package/dist/solver-types/prediction-apy-v0.js.map +1 -0
- package/dist/{intents → solver-types}/prediction-v0-auto.d.ts +17 -7
- package/dist/{intents → solver-types}/prediction-v0-auto.js +41 -8
- package/dist/solver-types/prediction-v0-auto.js.map +1 -0
- package/dist/{intents → solver-types}/prediction-v0-template.d.ts +9 -9
- package/dist/{intents → solver-types}/prediction-v0-template.js +10 -10
- package/dist/solver-types/prediction-v0-template.js.map +1 -0
- package/dist/solver-types/prediction-v0.d.ts +3 -0
- package/dist/{intents/kinds → solver-types}/prediction-v0.js +11 -6
- package/dist/solver-types/prediction-v0.js.map +1 -0
- package/dist/solver-types/solver-type.d.ts +55 -0
- package/dist/solver-types/solver-type.js +6 -0
- package/dist/solver-types/solver-type.js.map +1 -0
- package/dist/store/store.d.ts +97 -21
- package/dist/store/store.js +228 -45
- package/dist/store/store.js.map +1 -1
- package/dist/tasks/posting-service.d.ts +22 -0
- package/dist/tasks/posting-service.js +143 -0
- package/dist/tasks/posting-service.js.map +1 -0
- package/dist/tasks/signing.d.ts +4 -0
- package/dist/tasks/signing.js +18 -0
- package/dist/tasks/signing.js.map +1 -0
- package/dist/tasks/sources.d.ts +46 -0
- package/dist/tasks/sources.js +42 -0
- package/dist/tasks/sources.js.map +1 -0
- package/dist/templates/harnesses/alternative-harness/README.md.tmpl +44 -0
- package/dist/templates/harnesses/alternative-harness/gitignore.tmpl +3 -0
- package/dist/templates/harnesses/alternative-harness/jinn.manifest.json.tmpl +22 -0
- package/dist/templates/harnesses/alternative-harness/package.json.tmpl +26 -0
- package/dist/templates/harnesses/alternative-harness/src/coordinator.ts.tmpl +50 -0
- package/dist/templates/harnesses/alternative-harness/src/harness.ts.tmpl +31 -0
- package/dist/templates/harnesses/alternative-harness/src/index.ts.tmpl +44 -0
- package/dist/templates/harnesses/alternative-harness/src/mock-harness.ts.tmpl +41 -0
- package/dist/templates/harnesses/alternative-harness/src/phases/debrief.ts.tmpl +28 -0
- package/dist/templates/harnesses/alternative-harness/src/phases/execute.ts.tmpl +33 -0
- package/dist/templates/harnesses/alternative-harness/src/phases/improve.ts.tmpl +31 -0
- package/dist/templates/harnesses/alternative-harness/src/phases/memory.ts.tmpl +31 -0
- package/dist/templates/harnesses/alternative-harness/src/phases/orient.ts.tmpl +21 -0
- package/dist/templates/harnesses/alternative-harness/src/phases/plan.ts.tmpl +25 -0
- package/dist/templates/harnesses/alternative-harness/src/phases/strategize.ts.tmpl +29 -0
- package/dist/templates/harnesses/alternative-harness/test/coordinator.test.ts.tmpl +53 -0
- package/dist/templates/harnesses/alternative-harness/test/unit.test.ts.tmpl +55 -0
- package/dist/templates/harnesses/alternative-harness/tsconfig.json.tmpl +16 -0
- package/dist/templates/harnesses/evaluator/README.md.tmpl +36 -0
- package/dist/templates/harnesses/evaluator/gitignore.tmpl +3 -0
- package/dist/templates/harnesses/evaluator/jinn.manifest.json.tmpl +22 -0
- package/dist/templates/harnesses/evaluator/package.json.tmpl +26 -0
- package/dist/templates/harnesses/evaluator/src/index.ts.tmpl +35 -0
- package/dist/templates/harnesses/evaluator/test/unit.test.ts.tmpl +49 -0
- package/dist/templates/harnesses/evaluator/tsconfig.json.tmpl +16 -0
- package/dist/templates/harnesses/forecaster/README.md.tmpl +25 -0
- package/dist/templates/harnesses/forecaster/gitignore.tmpl +5 -0
- package/dist/templates/harnesses/forecaster/jinn.manifest.json.tmpl +22 -0
- package/dist/templates/harnesses/forecaster/package.json.tmpl +26 -0
- package/dist/templates/harnesses/forecaster/src/index.ts.tmpl +33 -0
- package/dist/templates/harnesses/forecaster/test/unit.test.ts.tmpl +42 -0
- package/dist/templates/harnesses/forecaster/tsconfig.json.tmpl +16 -0
- package/dist/trajectory/collector.d.ts +49 -0
- package/dist/trajectory/collector.js +86 -0
- package/dist/trajectory/collector.js.map +1 -0
- package/dist/trajectory/emit.d.ts +27 -0
- package/dist/trajectory/emit.js +40 -0
- package/dist/trajectory/emit.js.map +1 -0
- package/dist/trajectory/hash-chain.d.ts +18 -0
- package/dist/trajectory/hash-chain.js +23 -0
- package/dist/trajectory/hash-chain.js.map +1 -0
- package/dist/trajectory/index.d.ts +22 -0
- package/dist/trajectory/index.js +23 -0
- package/dist/trajectory/index.js.map +1 -0
- package/dist/trajectory/schema.d.ts +14 -14
- package/dist/trajectory/secret-scrub.d.ts +32 -0
- package/dist/trajectory/secret-scrub.js +51 -0
- package/dist/trajectory/secret-scrub.js.map +1 -0
- package/dist/trajectory/span-profile.d.ts +27 -0
- package/dist/trajectory/span-profile.js +51 -0
- package/dist/trajectory/span-profile.js.map +1 -0
- package/dist/trajectory/wrappers/http.d.ts +37 -0
- package/dist/trajectory/wrappers/http.js +85 -0
- package/dist/trajectory/wrappers/http.js.map +1 -0
- package/dist/trajectory/wrappers/mcp.d.ts +17 -0
- package/dist/trajectory/wrappers/mcp.js +58 -0
- package/dist/trajectory/wrappers/mcp.js.map +1 -0
- package/dist/trajectory/wrappers/subprocess.d.ts +32 -0
- package/dist/trajectory/wrappers/subprocess.js +70 -0
- package/dist/trajectory/wrappers/subprocess.js.map +1 -0
- package/dist/tx-retry.js +23 -9
- package/dist/tx-retry.js.map +1 -1
- package/dist/types/envelope.d.ts +1619 -0
- package/dist/types/envelope.js +121 -0
- package/dist/types/envelope.js.map +1 -0
- package/dist/types/index.d.ts +4 -4
- package/dist/types/index.js +4 -4
- package/dist/types/index.js.map +1 -1
- package/dist/types/payloads/index.d.ts +11 -0
- package/dist/types/payloads/index.js +46 -0
- package/dist/types/payloads/index.js.map +1 -0
- package/dist/types/payloads/portfolio-v0.d.ts +481 -0
- package/dist/types/payloads/portfolio-v0.js +94 -0
- package/dist/types/payloads/portfolio-v0.js.map +1 -0
- package/dist/types/payloads/prediction-apy-v0.d.ts +231 -0
- package/dist/types/payloads/prediction-apy-v0.js +63 -0
- package/dist/types/payloads/prediction-apy-v0.js.map +1 -0
- package/dist/types/payloads/prediction-v0.d.ts +262 -0
- package/dist/types/payloads/prediction-v0.js +73 -0
- package/dist/types/payloads/prediction-v0.js.map +1 -0
- package/dist/types/portfolio.d.ts +31 -698
- package/dist/types/portfolio.js +20 -110
- package/dist/types/portfolio.js.map +1 -1
- package/dist/types/prediction-apy.d.ts +26 -366
- package/dist/types/prediction-apy.js +12 -68
- package/dist/types/prediction-apy.js.map +1 -1
- package/dist/types/prediction.d.ts +40 -416
- package/dist/types/prediction.js +9 -83
- package/dist/types/prediction.js.map +1 -1
- package/dist/types/task-document.d.ts +498 -0
- package/dist/types/task-document.js +69 -0
- package/dist/types/task-document.js.map +1 -0
- package/dist/types/task.d.ts +455 -0
- package/dist/types/task.js +58 -0
- package/dist/types/task.js.map +1 -0
- package/dist/types/window.d.ts +12 -0
- package/dist/types/window.js +6 -0
- package/dist/types/window.js.map +1 -0
- package/dist/util/path-safety.d.ts +21 -0
- package/dist/util/path-safety.js +28 -0
- package/dist/util/path-safety.js.map +1 -0
- package/dist/util/redact-rpc-urls.d.ts +5 -0
- package/dist/util/redact-rpc-urls.js +9 -0
- package/dist/util/redact-rpc-urls.js.map +1 -0
- package/dist/venues/hyperliquid/account-value.d.ts +1 -1
- package/dist/venues/hyperliquid/account-value.js +1 -1
- package/dist/x402/acquire.d.ts +14 -3
- package/dist/x402/acquire.js +28 -11
- package/dist/x402/acquire.js.map +1 -1
- package/dist/x402/handler.d.ts +15 -3
- package/dist/x402/handler.js +67 -24
- package/dist/x402/handler.js.map +1 -1
- package/package.json +38 -13
- package/plugins/claude-code-learner/.claude-plugin/plugin.json +9 -0
- package/plugins/claude-code-learner/AGENTS.md +30 -0
- package/plugins/claude-code-learner/CLAUDE.md +31 -0
- package/plugins/claude-code-learner/README.md +58 -0
- package/plugins/claude-code-learner/agents/analyst.md +69 -0
- package/plugins/claude-code-learner/agents/consolidator.md +95 -0
- package/plugins/claude-code-learner/agents/explorer.md +54 -0
- package/plugins/claude-code-learner/agents/planner.md +88 -0
- package/plugins/claude-code-learner/agents/promoter.md +114 -0
- package/plugins/claude-code-learner/agents/step-worker.md +48 -0
- package/plugins/claude-code-learner/agents/strategist.md +86 -0
- package/plugins/claude-code-learner/hooks/hooks.json +16 -0
- package/plugins/claude-code-learner/hooks/session-start +38 -0
- package/plugins/claude-code-learner/skills/coordinator/SKILL.md +111 -0
- package/plugins/claude-code-learner/skills/debrief/SKILL.md +63 -0
- package/plugins/claude-code-learner/skills/execute/SKILL.md +87 -0
- package/plugins/claude-code-learner/skills/improve/SKILL.md +53 -0
- package/plugins/claude-code-learner/skills/memory-consolidation/SKILL.md +49 -0
- package/plugins/claude-code-learner/skills/orient/SKILL.md +71 -0
- package/plugins/claude-code-learner/skills/plan/SKILL.md +50 -0
- package/plugins/claude-code-learner/skills/strategize/SKILL.md +53 -0
- package/plugins/jinn-prediction-plugin/.claude-plugin/plugin.json +89 -0
- package/plugins/jinn-prediction-plugin/mcp/polymarket-server.mjs +2 -0
- package/plugins/jinn-prediction-plugin/schemas/prediction-v0-solution.schema.json +12 -0
- package/plugins/jinn-prediction-plugin/schemas/prediction-v0-task.schema.json +25 -0
- package/plugins/jinn-prediction-plugin/schemas/prediction-v0-verdict.schema.json +11 -0
- package/plugins/jinn-prediction-plugin/skills/base-rate-forecasting/SKILL.md +3 -0
- package/plugins/jinn-prediction-plugin/skills/calibration/SKILL.md +3 -0
- package/skills/jinn-operator/SKILL.md +120 -101
- package/templates/harnesses/alternative-harness/README.md.tmpl +44 -0
- package/templates/harnesses/alternative-harness/gitignore.tmpl +3 -0
- package/templates/harnesses/alternative-harness/jinn.manifest.json.tmpl +22 -0
- package/templates/harnesses/alternative-harness/package.json.tmpl +26 -0
- package/templates/harnesses/alternative-harness/src/coordinator.ts.tmpl +50 -0
- package/templates/harnesses/alternative-harness/src/harness.ts.tmpl +31 -0
- package/templates/harnesses/alternative-harness/src/index.ts.tmpl +44 -0
- package/templates/harnesses/alternative-harness/src/mock-harness.ts.tmpl +41 -0
- package/templates/harnesses/alternative-harness/src/phases/debrief.ts.tmpl +28 -0
- package/templates/harnesses/alternative-harness/src/phases/execute.ts.tmpl +33 -0
- package/templates/harnesses/alternative-harness/src/phases/improve.ts.tmpl +31 -0
- package/templates/harnesses/alternative-harness/src/phases/memory.ts.tmpl +31 -0
- package/templates/harnesses/alternative-harness/src/phases/orient.ts.tmpl +21 -0
- package/templates/harnesses/alternative-harness/src/phases/plan.ts.tmpl +25 -0
- package/templates/harnesses/alternative-harness/src/phases/strategize.ts.tmpl +29 -0
- package/templates/harnesses/alternative-harness/test/coordinator.test.ts.tmpl +53 -0
- package/templates/harnesses/alternative-harness/test/unit.test.ts.tmpl +55 -0
- package/templates/harnesses/alternative-harness/tsconfig.json.tmpl +16 -0
- package/templates/harnesses/evaluator/README.md.tmpl +36 -0
- package/templates/harnesses/evaluator/gitignore.tmpl +3 -0
- package/templates/harnesses/evaluator/jinn.manifest.json.tmpl +22 -0
- package/templates/harnesses/evaluator/package.json.tmpl +26 -0
- package/templates/harnesses/evaluator/src/index.ts.tmpl +35 -0
- package/templates/harnesses/evaluator/test/unit.test.ts.tmpl +49 -0
- package/templates/harnesses/evaluator/tsconfig.json.tmpl +16 -0
- package/templates/harnesses/forecaster/README.md.tmpl +25 -0
- package/templates/harnesses/forecaster/gitignore.tmpl +5 -0
- package/templates/harnesses/forecaster/jinn.manifest.json.tmpl +22 -0
- package/templates/harnesses/forecaster/package.json.tmpl +26 -0
- package/templates/harnesses/forecaster/src/index.ts.tmpl +33 -0
- package/templates/harnesses/forecaster/test/unit.test.ts.tmpl +42 -0
- package/templates/harnesses/forecaster/tsconfig.json.tmpl +16 -0
- package/dist/bin/jinn-mcp.d.ts +0 -2
- package/dist/bin/jinn-mcp.js +0 -10
- package/dist/bin/jinn-mcp.js.map +0 -1
- package/dist/cli/commands/intents.d.ts +0 -17
- package/dist/cli/commands/intents.js +0 -489
- package/dist/cli/commands/intents.js.map +0 -1
- package/dist/cli/commands/plugin-install.js.map +0 -1
- package/dist/cli/commands/submit-intent.js +0 -245
- package/dist/cli/commands/submit-intent.js.map +0 -1
- package/dist/cli/intent-registry-access.d.ts +0 -62
- package/dist/cli/intent-registry-access.js +0 -165
- package/dist/cli/intent-registry-access.js.map +0 -1
- package/dist/discovery/registry.d.ts +0 -97
- package/dist/discovery/registry.js +0 -177
- package/dist/discovery/registry.js.map +0 -1
- package/dist/discovery/subgraph.d.ts +0 -37
- package/dist/discovery/subgraph.js +0 -87
- package/dist/discovery/subgraph.js.map +0 -1
- package/dist/intents/kinds/constants.js.map +0 -1
- package/dist/intents/kinds/index.d.ts +0 -28
- package/dist/intents/kinds/index.js +0 -50
- package/dist/intents/kinds/index.js.map +0 -1
- package/dist/intents/kinds/portfolio-v0.d.ts +0 -2
- package/dist/intents/kinds/portfolio-v0.js +0 -13
- package/dist/intents/kinds/portfolio-v0.js.map +0 -1
- package/dist/intents/kinds/prediction-apy-v0.d.ts +0 -3
- package/dist/intents/kinds/prediction-apy-v0.js +0 -21
- package/dist/intents/kinds/prediction-apy-v0.js.map +0 -1
- package/dist/intents/kinds/prediction-v0.d.ts +0 -3
- package/dist/intents/kinds/prediction-v0.js.map +0 -1
- package/dist/intents/kinds/spec-kind.d.ts +0 -38
- package/dist/intents/kinds/spec-kind.js +0 -6
- package/dist/intents/kinds/spec-kind.js.map +0 -1
- package/dist/intents/posting-service.d.ts +0 -26
- package/dist/intents/posting-service.js +0 -218
- package/dist/intents/posting-service.js.map +0 -1
- package/dist/intents/prediction-apy-v0-auto.d.ts +0 -11
- package/dist/intents/prediction-apy-v0-auto.js +0 -46
- package/dist/intents/prediction-apy-v0-auto.js.map +0 -1
- package/dist/intents/prediction-apy-v0-template.js.map +0 -1
- package/dist/intents/prediction-v0-auto.js.map +0 -1
- package/dist/intents/prediction-v0-template.js.map +0 -1
- package/dist/intents/sources.d.ts +0 -39
- package/dist/intents/sources.js +0 -42
- package/dist/intents/sources.js.map +0 -1
- package/dist/restorer/engine/canonical-json.d.ts +0 -18
- package/dist/restorer/engine/canonical-json.js +0 -59
- package/dist/restorer/engine/canonical-json.js.map +0 -1
- package/dist/restorer/engine/claim.js.map +0 -1
- package/dist/restorer/engine/delivery.js.map +0 -1
- package/dist/restorer/engine/engine.d.ts +0 -213
- package/dist/restorer/engine/engine.js +0 -769
- package/dist/restorer/engine/engine.js.map +0 -1
- package/dist/restorer/engine/manifest-assembly.d.ts +0 -67
- package/dist/restorer/engine/manifest-assembly.js +0 -79
- package/dist/restorer/engine/manifest-assembly.js.map +0 -1
- package/dist/restorer/engine/packaging.d.ts +0 -87
- package/dist/restorer/engine/packaging.js.map +0 -1
- package/dist/restorer/engine/persistence.d.ts +0 -170
- package/dist/restorer/engine/persistence.js.map +0 -1
- package/dist/restorer/engine/recovery.d.ts +0 -22
- package/dist/restorer/engine/recovery.js.map +0 -1
- package/dist/restorer/engine/registry.d.ts +0 -62
- package/dist/restorer/engine/registry.js +0 -73
- package/dist/restorer/engine/registry.js.map +0 -1
- package/dist/restorer/engine/signing.js.map +0 -1
- package/dist/restorer/engine/state.js.map +0 -1
- package/dist/restorer/impls/claude-mcp-hyperliquid/api-wallet.js.map +0 -1
- package/dist/restorer/impls/claude-mcp-hyperliquid/index.js.map +0 -1
- package/dist/restorer/impls/claude-mcp-hyperliquid/mcp-tools.js.map +0 -1
- package/dist/restorer/impls/claude-mcp-hyperliquid/safety-rails.js.map +0 -1
- package/dist/restorer/impls/claude-mcp-hyperliquid/session-orchestrator.js.map +0 -1
- package/dist/restorer/impls/claude-mcp-prediction/index.js.map +0 -1
- package/dist/restorer/impls/claude-mcp-prediction/mcp-tools.js.map +0 -1
- package/dist/restorer/impls/claude-mcp-prediction/prompt.js.map +0 -1
- package/dist/restorer/impls/claude-mcp-prediction/session-orchestrator.js.map +0 -1
- package/dist/restorer/impls/claude-mcp-prediction/types.js +0 -6
- package/dist/restorer/impls/claude-mcp-prediction/types.js.map +0 -1
- package/dist/restorer/impls/claude-mcp-prediction-apy/index.d.ts +0 -34
- package/dist/restorer/impls/claude-mcp-prediction-apy/index.js.map +0 -1
- package/dist/restorer/impls/claude-mcp-prediction-apy/mcp-tools.js.map +0 -1
- package/dist/restorer/impls/claude-mcp-prediction-apy/prompt.d.ts +0 -7
- package/dist/restorer/impls/claude-mcp-prediction-apy/prompt.js.map +0 -1
- package/dist/restorer/impls/claude-mcp-prediction-apy/session-orchestrator.js +0 -128
- package/dist/restorer/impls/claude-mcp-prediction-apy/session-orchestrator.js.map +0 -1
- package/dist/restorer/impls/claude-mcp-prediction-apy/types.js +0 -6
- package/dist/restorer/impls/claude-mcp-prediction-apy/types.js.map +0 -1
- package/dist/restorer/impls/evaluation-context.d.ts +0 -16
- package/dist/restorer/impls/evaluation-context.js +0 -18
- package/dist/restorer/impls/evaluation-context.js.map +0 -1
- package/dist/restorer/impls/index.d.ts +0 -46
- package/dist/restorer/impls/index.js.map +0 -1
- package/dist/restorer/impls/legacy-claude/index.d.ts +0 -52
- package/dist/restorer/impls/legacy-claude/index.js.map +0 -1
- package/dist/restorer/impls/portfolio-v0-evaluator/canonical-metrics.js.map +0 -1
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/availability.js.map +0 -1
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/consistency.js.map +0 -1
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/eligibility.js.map +0 -1
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/integrity.js.map +0 -1
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/spec.js.map +0 -1
- package/dist/restorer/impls/portfolio-v0-evaluator/index.d.ts +0 -44
- package/dist/restorer/impls/portfolio-v0-evaluator/index.js.map +0 -1
- package/dist/restorer/impls/portfolio-v0-evaluator/score.js.map +0 -1
- package/dist/restorer/impls/portfolio-v0-evaluator/types.js.map +0 -1
- package/dist/restorer/impls/prediction-apy-v0-baseline/index.js.map +0 -1
- package/dist/restorer/impls/prediction-apy-v0-baseline/strategy.js.map +0 -1
- package/dist/restorer/impls/prediction-apy-v0-baseline/types.js.map +0 -1
- package/dist/restorer/impls/prediction-apy-v0-evaluator/canonical-metrics.d.ts +0 -6
- package/dist/restorer/impls/prediction-apy-v0-evaluator/canonical-metrics.js +0 -11
- package/dist/restorer/impls/prediction-apy-v0-evaluator/canonical-metrics.js.map +0 -1
- package/dist/restorer/impls/prediction-apy-v0-evaluator/index.js +0 -208
- package/dist/restorer/impls/prediction-apy-v0-evaluator/index.js.map +0 -1
- package/dist/restorer/impls/prediction-apy-v0-evaluator/parse-submission.d.ts +0 -7
- package/dist/restorer/impls/prediction-apy-v0-evaluator/parse-submission.js +0 -29
- package/dist/restorer/impls/prediction-apy-v0-evaluator/parse-submission.js.map +0 -1
- package/dist/restorer/impls/prediction-apy-v0-evaluator/score.js.map +0 -1
- package/dist/restorer/impls/prediction-apy-v0-evaluator/types.js.map +0 -1
- package/dist/restorer/impls/prediction-v0-baseline/index.d.ts +0 -31
- package/dist/restorer/impls/prediction-v0-baseline/index.js.map +0 -1
- package/dist/restorer/impls/prediction-v0-baseline/strategy.js.map +0 -1
- package/dist/restorer/impls/prediction-v0-baseline/types.d.ts +0 -7
- package/dist/restorer/impls/prediction-v0-baseline/types.js.map +0 -1
- package/dist/restorer/impls/prediction-v0-evaluator/canonical-metrics.js.map +0 -1
- package/dist/restorer/impls/prediction-v0-evaluator/checks/availability.js.map +0 -1
- package/dist/restorer/impls/prediction-v0-evaluator/checks/eligibility.js.map +0 -1
- package/dist/restorer/impls/prediction-v0-evaluator/checks/integrity.d.ts +0 -13
- package/dist/restorer/impls/prediction-v0-evaluator/checks/integrity.js.map +0 -1
- package/dist/restorer/impls/prediction-v0-evaluator/checks/spec.js.map +0 -1
- package/dist/restorer/impls/prediction-v0-evaluator/index.js +0 -234
- package/dist/restorer/impls/prediction-v0-evaluator/index.js.map +0 -1
- package/dist/restorer/impls/prediction-v0-evaluator/score.js.map +0 -1
- package/dist/restorer/impls/prediction-v0-evaluator/types.js.map +0 -1
- package/dist/restorer/types.d.ts +0 -194
- package/dist/restorer/types.js.map +0 -1
- package/dist/types/desired-state.d.ts +0 -94
- package/dist/types/desired-state.js +0 -36
- package/dist/types/desired-state.js.map +0 -1
- /package/dist/cli/commands/{plugin-install.d.ts → solver-nets.d.ts} +0 -0
- /package/dist/cli/commands/{submit-intent.d.ts → tasks.d.ts} +0 -0
- /package/dist/{restorer/impls/prediction-apy-v0-baseline → harnesses/impls/claude-code-learner}/types.js +0 -0
- /package/dist/{restorer → harnesses}/impls/claude-mcp-hyperliquid/api-wallet.js +0 -0
- /package/dist/{restorer → harnesses}/impls/claude-mcp-hyperliquid/mcp-tools.d.ts +0 -0
- /package/dist/{restorer → harnesses}/impls/claude-mcp-hyperliquid/mcp-tools.js +0 -0
- /package/dist/{restorer → harnesses}/impls/claude-mcp-hyperliquid/safety-rails.d.ts +0 -0
- /package/dist/{restorer → harnesses}/impls/claude-mcp-hyperliquid/safety-rails.js +0 -0
- /package/dist/{restorer → harnesses}/impls/claude-mcp-prediction/mcp-tools.d.ts +0 -0
- /package/dist/{restorer → harnesses}/impls/claude-mcp-prediction-apy/mcp-tools.d.ts +0 -0
- /package/dist/{restorer → harnesses}/impls/portfolio-v0-evaluator/checks/availability.d.ts +0 -0
- /package/dist/{restorer → harnesses}/impls/portfolio-v0-evaluator/checks/availability.js +0 -0
- /package/dist/{restorer → harnesses}/impls/portfolio-v0-evaluator/score.d.ts +0 -0
- /package/dist/{restorer → harnesses}/impls/portfolio-v0-evaluator/score.js +0 -0
- /package/dist/{restorer → harnesses}/impls/portfolio-v0-evaluator/types.js +0 -0
- /package/dist/{restorer → harnesses}/impls/prediction-apy-v0-baseline/strategy.d.ts +0 -0
- /package/dist/{restorer → harnesses}/impls/prediction-apy-v0-baseline/strategy.js +0 -0
- /package/dist/{restorer → harnesses}/impls/prediction-apy-v0-baseline/types.d.ts +0 -0
- /package/dist/{restorer/impls/prediction-apy-v0-evaluator → harnesses/impls/prediction-apy-v0-baseline}/types.js +0 -0
- /package/dist/{restorer → harnesses}/impls/prediction-apy-v0-evaluator/score.d.ts +0 -0
- /package/dist/{restorer → harnesses}/impls/prediction-apy-v0-evaluator/score.js +0 -0
- /package/dist/{restorer → harnesses}/impls/prediction-apy-v0-evaluator/types.d.ts +0 -0
- /package/dist/{restorer/impls/prediction-v0-baseline → harnesses/impls/prediction-apy-v0-evaluator}/types.js +0 -0
- /package/dist/{restorer/impls/prediction-v0-evaluator → harnesses/impls/prediction-v0-baseline}/types.js +0 -0
- /package/dist/{restorer → harnesses}/impls/prediction-v0-evaluator/canonical-metrics.js +0 -0
- /package/dist/{restorer → harnesses}/impls/prediction-v0-evaluator/checks/availability.d.ts +0 -0
- /package/dist/{restorer → harnesses}/impls/prediction-v0-evaluator/checks/availability.js +0 -0
- /package/dist/{restorer → harnesses}/impls/prediction-v0-evaluator/checks/eligibility.js +0 -0
- /package/dist/{restorer → harnesses}/impls/prediction-v0-evaluator/checks/spec.js +0 -0
- /package/dist/{restorer → harnesses}/impls/prediction-v0-evaluator/score.d.ts +0 -0
- /package/dist/{restorer → harnesses}/impls/prediction-v0-evaluator/score.js +0 -0
- /package/dist/{restorer → harnesses}/impls/prediction-v0-evaluator/types.d.ts +0 -0
- /package/dist/{intents/kinds → solver-types}/constants.d.ts +0 -0
- /package/dist/{intents/kinds → solver-types}/constants.js +0 -0
|
@@ -0,0 +1,1203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Harness engine — main TaskEngine class.
|
|
3
|
+
*
|
|
4
|
+
* §6.3, §6.5 of spec/2026-04-17-portfolio-v0-design.md
|
|
5
|
+
*
|
|
6
|
+
* Orchestrates the state machine lifecycle for each observed task.
|
|
7
|
+
* Transition method bodies are stubs; subsequent tasks fill them in.
|
|
8
|
+
*/
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
11
|
+
import { TaskRunPersistence } from './persistence.js';
|
|
12
|
+
import { TaskRunState, MissingEvidenceHashError } from './state.js';
|
|
13
|
+
import { executeTwoLayerClaim, releaseClaimedNotStarted, } from './claim.js';
|
|
14
|
+
import { provisionWorkingDir, provisionImplStateDir, walkArtifacts, uploadArtifacts, } from './packaging.js';
|
|
15
|
+
import { assembleAndSignEnvelope, } from './envelope-assembly.js';
|
|
16
|
+
import { deliverAndClaim, } from './delivery.js';
|
|
17
|
+
import { SkippableError } from '../types.js';
|
|
18
|
+
import { submitEvaluatorFeedback } from '../../erc8004/index.js';
|
|
19
|
+
import { TrajectoryCollector, emitTrajectory } from '../../trajectory/index.js';
|
|
20
|
+
import { buildInfo } from '../../build-info.js';
|
|
21
|
+
// ── Sentinel error ────────────────────────────────────────────────────────────
|
|
22
|
+
export class NotImplementedError extends Error {
|
|
23
|
+
transitionName;
|
|
24
|
+
constructor(transitionName) {
|
|
25
|
+
super(`[NotImplemented] ${transitionName} — fill in via subsequent task`);
|
|
26
|
+
this.name = 'NotImplementedError';
|
|
27
|
+
this.transitionName = transitionName;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// ── TaskEngine ─────────────────────────────────────────────────────────
|
|
31
|
+
export class TaskEngine {
|
|
32
|
+
persistence;
|
|
33
|
+
paths;
|
|
34
|
+
claimDeps;
|
|
35
|
+
packagingDeps;
|
|
36
|
+
envelopeDeps;
|
|
37
|
+
deliveryDeps;
|
|
38
|
+
implRegistry;
|
|
39
|
+
solverNetRegistry;
|
|
40
|
+
identityPublisher;
|
|
41
|
+
reputationFeedback;
|
|
42
|
+
operatorConfig;
|
|
43
|
+
/** Local SQLite-backed store; used to emit `restoration-result` /
|
|
44
|
+
* `evaluation-verdict` artifact rows when a cycle completes via a
|
|
45
|
+
* deterministic impl (the legacy claude/MCP path writes them itself). */
|
|
46
|
+
store;
|
|
47
|
+
// Transient storage for impl output between runImpl and pack transitions.
|
|
48
|
+
// Keyed by requestId; cleared after successful pack.
|
|
49
|
+
solutionOutputs = new Map();
|
|
50
|
+
// Transient storage for trajectory collectors produced in runImpl.
|
|
51
|
+
// emitTrajectory is deferred to pack() so that artifact spans can be added
|
|
52
|
+
// before the trajectory is finalised and uploaded (Task 16 bidirectional linkage).
|
|
53
|
+
// Keyed by requestId; cleared after successful pack.
|
|
54
|
+
// Protected (not private) to allow test subclasses to inject collectors.
|
|
55
|
+
trajectoryCollectors = new Map();
|
|
56
|
+
// Transient storage for trajectory CID+sha256 refs produced by runImpl.
|
|
57
|
+
// Keyed by requestId; cleared after successful pack.
|
|
58
|
+
trajectoryRefs = new Map();
|
|
59
|
+
runtimePluginsByRequest = new Map();
|
|
60
|
+
/** Set by stop(); causes runTickLoop to exit at the next iteration. */
|
|
61
|
+
stopped = false;
|
|
62
|
+
constructor(opts) {
|
|
63
|
+
this.persistence = new TaskRunPersistence(opts.store.db);
|
|
64
|
+
this.store = opts.store;
|
|
65
|
+
this.paths = opts.paths;
|
|
66
|
+
this.claimDeps = opts.claimDeps;
|
|
67
|
+
this.packagingDeps = opts.packagingDeps;
|
|
68
|
+
this.envelopeDeps = opts.envelopeDeps;
|
|
69
|
+
this.deliveryDeps = opts.deliveryDeps;
|
|
70
|
+
this.implRegistry = opts.implRegistry;
|
|
71
|
+
this.solverNetRegistry = opts.solverNetRegistry;
|
|
72
|
+
this.identityPublisher = opts.identityPublisher;
|
|
73
|
+
this.reputationFeedback = opts.reputationFeedback;
|
|
74
|
+
this.operatorConfig = opts.operatorConfig;
|
|
75
|
+
}
|
|
76
|
+
// ── Public API ──────────────────────────────────────────────────────────────
|
|
77
|
+
/**
|
|
78
|
+
* Called when an task is observed from an on-chain event.
|
|
79
|
+
* Persists a DISCOVERED row. Idempotent: if the row already exists, no-op.
|
|
80
|
+
*/
|
|
81
|
+
async observe(input) {
|
|
82
|
+
const existing = this.persistence.getByRequestId(input.requestId);
|
|
83
|
+
if (!existing) {
|
|
84
|
+
this.persistence.insertDiscovered(input);
|
|
85
|
+
console.log(`[harness-engine] observed task ${input.requestId} solverType=${input.solverType ?? 'null'}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Recover all in-flight tasks from persisted state.
|
|
90
|
+
* Called at daemon startup before beginning normal event processing.
|
|
91
|
+
* Returns a per-task report for each task attempted.
|
|
92
|
+
*/
|
|
93
|
+
async recoverInFlight() {
|
|
94
|
+
const inflight = this.persistence.getInFlight();
|
|
95
|
+
const results = await Promise.allSettled(inflight.map((task) => this._recoverOne(task)));
|
|
96
|
+
const reports = results.map((result, i) => {
|
|
97
|
+
const requestId = inflight[i].requestId;
|
|
98
|
+
if (result.status === 'fulfilled') {
|
|
99
|
+
return { requestId, outcome: 'ok' };
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
const error = result.reason instanceof Error
|
|
103
|
+
? result.reason.message
|
|
104
|
+
: String(result.reason);
|
|
105
|
+
return { requestId, outcome: 'failed', error };
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
const okCount = reports.filter((r) => r.outcome === 'ok').length;
|
|
109
|
+
console.log(`[harness-engine] recovery: ${okCount}/${reports.length} tasks resumed`);
|
|
110
|
+
return reports;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Periodic tick: advance every in-flight task by one transition.
|
|
114
|
+
* Called by `runTickLoop` so that tasks which entered a non-event-driven
|
|
115
|
+
* state (e.g. CLAIMED waiting for windowStartTs) get re-driven without
|
|
116
|
+
* waiting for a daemon restart or a fresh marketplace event.
|
|
117
|
+
*
|
|
118
|
+
* Errors from individual tasks are logged but do not stop the loop.
|
|
119
|
+
*/
|
|
120
|
+
async tick() {
|
|
121
|
+
const inflight = this.persistence.getInFlight();
|
|
122
|
+
const results = await Promise.allSettled(inflight.map((task) => this.process(task.requestId)));
|
|
123
|
+
for (let i = 0; i < results.length; i++) {
|
|
124
|
+
const r = results[i];
|
|
125
|
+
if (r.status === 'rejected') {
|
|
126
|
+
const requestId = inflight[i].requestId;
|
|
127
|
+
const reason = r.reason instanceof Error ? r.reason.message : String(r.reason);
|
|
128
|
+
console.warn(`[harness-engine] tick: process(${requestId}) failed: ${reason}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Drive `tick()` on a fixed interval until `stop()` is called.
|
|
134
|
+
* Errors thrown by tick() itself are logged and do not stop the loop.
|
|
135
|
+
*/
|
|
136
|
+
async runTickLoop(intervalMs) {
|
|
137
|
+
while (!this.stopped) {
|
|
138
|
+
try {
|
|
139
|
+
await this.tick();
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
console.error('[harness-engine] tick loop error (continuing):', err instanceof Error ? err.message : err);
|
|
143
|
+
}
|
|
144
|
+
if (this.stopped)
|
|
145
|
+
break;
|
|
146
|
+
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/** Signal `runTickLoop` to exit at the next iteration. */
|
|
150
|
+
stop() {
|
|
151
|
+
this.stopped = true;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Process a single task: dispatch by current state to the appropriate
|
|
155
|
+
* transition. Drives one state transition per call.
|
|
156
|
+
*
|
|
157
|
+
* Called both by recovery and by the ongoing event-processing loop.
|
|
158
|
+
*/
|
|
159
|
+
async process(requestId) {
|
|
160
|
+
const task = this.persistence.getByRequestId(requestId);
|
|
161
|
+
if (!task) {
|
|
162
|
+
throw new Error(`process: task not found: ${requestId}`);
|
|
163
|
+
}
|
|
164
|
+
switch (task.state) {
|
|
165
|
+
case TaskRunState.DISCOVERED:
|
|
166
|
+
await this._runTransition(task, () => this.claim(task));
|
|
167
|
+
break;
|
|
168
|
+
case TaskRunState.CLAIMED: {
|
|
169
|
+
// Advance to WAITING — persist-before-invoke principle.
|
|
170
|
+
const oldState = task.state;
|
|
171
|
+
this.persistence.transition(task.requestId, TaskRunState.WAITING);
|
|
172
|
+
console.log(`[harness-engine] ${requestId} ${oldState} → ${TaskRunState.WAITING}`);
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
case TaskRunState.WAITING: {
|
|
176
|
+
const advance = this.dataDrivenAdvance(task);
|
|
177
|
+
if (advance !== null) {
|
|
178
|
+
this.persistence.transition(task.requestId, advance);
|
|
179
|
+
console.log(`[harness-engine] ${requestId} ${task.state} → ${advance}`);
|
|
180
|
+
await this._runTransition(this.persistence.getOrThrow(requestId), () => this.takePreSnapshot(this.persistence.getOrThrow(requestId)));
|
|
181
|
+
// takePreSnapshot transitions PRE_SNAPSHOT → RUNNING. Re-dispatch on
|
|
182
|
+
// the post-transition state so RUNNING fires in the same pass (jinn-mono-sae).
|
|
183
|
+
const after = this.persistence.getByRequestId(task.requestId);
|
|
184
|
+
if (after && after.state === TaskRunState.RUNNING) {
|
|
185
|
+
await this.process(task.requestId);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// else: not yet time — caller is responsible for scheduling retry
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
case TaskRunState.PRE_SNAPSHOT: {
|
|
192
|
+
const advance = this.dataDrivenAdvance(task);
|
|
193
|
+
if (advance !== null) {
|
|
194
|
+
// Snapshot already captured (e.g. recovered from crash mid-transition)
|
|
195
|
+
this.persistence.transition(task.requestId, advance);
|
|
196
|
+
console.log(`[harness-engine] ${requestId} ${task.state} → ${advance}`);
|
|
197
|
+
await this._runTransition(this.persistence.getOrThrow(requestId), () => this.runImpl(this.persistence.getOrThrow(requestId)));
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
await this._runTransition(task, () => this.takePreSnapshot(task));
|
|
201
|
+
// takePreSnapshot transitions PRE_SNAPSHOT → RUNNING internally.
|
|
202
|
+
// Re-dispatch on the post-transition state so the RUNNING case fires
|
|
203
|
+
// in the same pass (jinn-mono-sae fix). Without this, tasks stall
|
|
204
|
+
// at RUNNING until the next tick/restart and runImpl never executes.
|
|
205
|
+
const after = this.persistence.getByRequestId(task.requestId);
|
|
206
|
+
if (after && after.state === TaskRunState.RUNNING) {
|
|
207
|
+
await this.process(task.requestId);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
case TaskRunState.RUNNING:
|
|
213
|
+
await this._runTransition(task, () => this.runImpl(task));
|
|
214
|
+
break;
|
|
215
|
+
case TaskRunState.POST_SNAPSHOT: {
|
|
216
|
+
const advance = this.dataDrivenAdvance(task);
|
|
217
|
+
if (advance !== null) {
|
|
218
|
+
this.persistence.transition(task.requestId, advance);
|
|
219
|
+
console.log(`[harness-engine] ${requestId} ${task.state} → ${advance}`);
|
|
220
|
+
await this._runTransition(this.persistence.getOrThrow(requestId), () => this.pack(this.persistence.getOrThrow(requestId)));
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
await this._runTransition(task, () => this.takePostSnapshot(task));
|
|
224
|
+
}
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
case TaskRunState.PACKAGING:
|
|
228
|
+
await this._runTransition(task, () => this.pack(task));
|
|
229
|
+
break;
|
|
230
|
+
case TaskRunState.DELIVERING:
|
|
231
|
+
await this._runTransition(task, () => this.deliver(task));
|
|
232
|
+
break;
|
|
233
|
+
case TaskRunState.COMPLETE:
|
|
234
|
+
case TaskRunState.FAILED:
|
|
235
|
+
// Terminal — nothing to do.
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// ── Transition stubs ────────────────────────────────────────────────────────
|
|
240
|
+
// Stubs throw NotImplementedError. claim() is implemented here; others are
|
|
241
|
+
// filled in by subsequent tasks.
|
|
242
|
+
/**
|
|
243
|
+
* Two-layer claim: ClaimRegistry + Marketplace.
|
|
244
|
+
*
|
|
245
|
+
* Idempotent on resume: checks ClaimRegistry for a pre-existing claim before
|
|
246
|
+
* sending any on-chain transaction.
|
|
247
|
+
*
|
|
248
|
+
* Advances state DISCOVERED → CLAIMED on success.
|
|
249
|
+
* Marks FAILED if either layer cannot be claimed.
|
|
250
|
+
*
|
|
251
|
+
* Requires claimDeps to be injected via constructor options. Falls back to
|
|
252
|
+
* NotImplementedError if claimDeps is absent (development / test mode).
|
|
253
|
+
*/
|
|
254
|
+
async claim(task) {
|
|
255
|
+
if (!this.claimDeps) {
|
|
256
|
+
throw new NotImplementedError('claim');
|
|
257
|
+
}
|
|
258
|
+
// ── Pre-claim impl gate ─────────────────────────────────────────────────
|
|
259
|
+
// Refuse to claim tasks whose impl is either unregistered (operator has
|
|
260
|
+
// opted out via config.harnesses.disabled[]) or not ready (external deps
|
|
261
|
+
// missing — e.g. HL api-wallet not approved for portfolio.v0). Marking
|
|
262
|
+
// FAILED is terminal so we don't re-attempt; another operator can still
|
|
263
|
+
// claim from the marketplace.
|
|
264
|
+
//
|
|
265
|
+
// Only fires when an implRegistry is wired in (production); tests that
|
|
266
|
+
// inject claimDeps without a registry intentionally exercise the raw
|
|
267
|
+
// claim path and are not gated.
|
|
268
|
+
const solverNet = this.solverNetRegistry && task.solverType
|
|
269
|
+
? this.solverNetRegistry.forSolverType(task.solverType)
|
|
270
|
+
: undefined;
|
|
271
|
+
if (this.solverNetRegistry && task.solverType && !solverNet) {
|
|
272
|
+
const reason = `no enabled SolverNet for solverType '${task.solverType}'; run \`jinn solver-nets enable <name>\``;
|
|
273
|
+
this.persistence.markFailed(task.requestId, reason);
|
|
274
|
+
console.log(`[harness-engine] ${task.requestId}: skipping claim — ${reason}`);
|
|
275
|
+
throw new Error(reason);
|
|
276
|
+
}
|
|
277
|
+
if (this.implRegistry && task.solverType) {
|
|
278
|
+
if (!solverNet) {
|
|
279
|
+
// Unit tests can wire only implRegistry to exercise the Harness gate.
|
|
280
|
+
}
|
|
281
|
+
const impl = this.implRegistry.findFor({
|
|
282
|
+
solverType: task.solverType,
|
|
283
|
+
role: task.taskRole ?? 'restoration',
|
|
284
|
+
});
|
|
285
|
+
if (!impl) {
|
|
286
|
+
const setHarnessHint = solverNet
|
|
287
|
+
? `jinn solver-nets set-harness ${solverNet.name} <harness>`
|
|
288
|
+
: 'jinn solver-nets set-harness <name> <harness>';
|
|
289
|
+
const reason = `no Harness registered or enabled for solverType '${task.solverType}'; run \`${setHarnessHint}\``;
|
|
290
|
+
this.persistence.markFailed(task.requestId, reason);
|
|
291
|
+
console.log(`[harness-engine] ${task.requestId}: skipping claim — ${reason}`);
|
|
292
|
+
throw new Error(reason);
|
|
293
|
+
}
|
|
294
|
+
if (impl.isReady) {
|
|
295
|
+
const status = await impl.isReady({
|
|
296
|
+
solverType: task.solverType,
|
|
297
|
+
role: task.taskRole ?? 'restoration',
|
|
298
|
+
});
|
|
299
|
+
if (!status.ready) {
|
|
300
|
+
const reason = `impl '${impl.name}' not ready: ${status.reason ?? 'unknown'}${status.nextStep?.cli ? ` — run \`${status.nextStep.cli}\`` : ''}`;
|
|
301
|
+
this.persistence.markFailed(task.requestId, reason);
|
|
302
|
+
console.log(`[harness-engine] ${task.requestId}: skipping claim — ${reason}`);
|
|
303
|
+
throw new Error(reason);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
const { registryClient, marketplaceClaimer } = this.claimDeps;
|
|
308
|
+
await executeTwoLayerClaim({
|
|
309
|
+
requestId: task.requestId,
|
|
310
|
+
windowStartTs: task.windowStartTs,
|
|
311
|
+
}, registryClient, marketplaceClaimer);
|
|
312
|
+
// Both layers succeeded. The event path and tick loop can race on the same
|
|
313
|
+
// DISCOVERED row; if another caller already advanced it, treat this claim as
|
|
314
|
+
// idempotent and do not rewind or fail the task.
|
|
315
|
+
const current = this.persistence.getByRequestId(task.requestId);
|
|
316
|
+
if (!current) {
|
|
317
|
+
throw new Error(`claim: task not found after claim: ${task.requestId}`);
|
|
318
|
+
}
|
|
319
|
+
if (current.state === TaskRunState.DISCOVERED) {
|
|
320
|
+
this.persistence.transition(task.requestId, TaskRunState.CLAIMED);
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
console.log(`[harness-engine] ${task.requestId}: claim completed but state is already ${current.state}; skipping CLAIMED transition`);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Release ClaimRegistry claims for all CLAIMED tasks whose work window has
|
|
328
|
+
* not yet started. Called on graceful engine shutdown.
|
|
329
|
+
*
|
|
330
|
+
* Returns the list of requestIds that were successfully released.
|
|
331
|
+
*/
|
|
332
|
+
async releaseClaimedNotStarted() {
|
|
333
|
+
if (!this.claimDeps) {
|
|
334
|
+
return []; // No registry client — nothing to release
|
|
335
|
+
}
|
|
336
|
+
const claimed = this.persistence.getByState(TaskRunState.CLAIMED);
|
|
337
|
+
const released = [];
|
|
338
|
+
for (const task of claimed) {
|
|
339
|
+
if (Date.now() < task.windowStartTs) {
|
|
340
|
+
try {
|
|
341
|
+
const ok = await releaseClaimedNotStarted({
|
|
342
|
+
requestId: task.requestId,
|
|
343
|
+
windowStartTs: task.windowStartTs,
|
|
344
|
+
}, this.claimDeps.registryClient);
|
|
345
|
+
if (ok) {
|
|
346
|
+
released.push(task.requestId);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
catch (err) {
|
|
350
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
351
|
+
console.error(`[harness-engine] releaseClaimedNotStarted failed for ${task.requestId}: ${reason}`);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
if (released.length > 0) {
|
|
356
|
+
console.log(`[harness-engine] released ${released.length} pre-window claim(s) on shutdown: ${released.join(', ')}`);
|
|
357
|
+
}
|
|
358
|
+
return released;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* PRE_SNAPSHOT transition: provision workingDir + implStateDir, write
|
|
362
|
+
* task.json + env/ files, create sessions/ directory.
|
|
363
|
+
*
|
|
364
|
+
* Requires no external deps beyond filesystem access — always implemented.
|
|
365
|
+
* Advances state PRE_SNAPSHOT with workingDir + implStateDir patch.
|
|
366
|
+
*/
|
|
367
|
+
async takePreSnapshot(run) {
|
|
368
|
+
const workingDir = join(this.paths.workingDirRoot, run.requestId);
|
|
369
|
+
// Resolve the impl via registry so implStateDir matches the path runImpl uses
|
|
370
|
+
// (join(implStateDirRoot, impl.name, solverType)). Falls back to solverType then 'default'
|
|
371
|
+
// when no impl is registered — legacy path preserved for health-check tasks.
|
|
372
|
+
const resolvedImpl = run.solverType
|
|
373
|
+
? this.implRegistry?.findFor({ solverType: run.solverType, role: run.taskRole ?? 'restoration' }) ?? null
|
|
374
|
+
: null;
|
|
375
|
+
const implStateName = run.implName ?? resolvedImpl?.name ?? run.solverType ?? 'default';
|
|
376
|
+
const kindSeg = (run.solverType ?? '').replace(/[.:]/g, '_');
|
|
377
|
+
const implStateDir = kindSeg
|
|
378
|
+
? join(this.paths.implStateDirRoot, implStateName, kindSeg)
|
|
379
|
+
: join(this.paths.implStateDirRoot, implStateName);
|
|
380
|
+
// Prefer the persisted full Task; fall back to a stub for legacy
|
|
381
|
+
// (pre-migration) rows so the engine still works for health-check tasks.
|
|
382
|
+
const task = run.task ?? {
|
|
383
|
+
id: run.requestId,
|
|
384
|
+
description: '',
|
|
385
|
+
...(run.solverType ? { solverType: run.solverType, spec: {} } : {}),
|
|
386
|
+
role: run.taskRole ?? 'restoration',
|
|
387
|
+
window: { startTs: run.windowStartTs, endTs: run.windowEndTs },
|
|
388
|
+
};
|
|
389
|
+
provisionWorkingDir(workingDir, task);
|
|
390
|
+
provisionImplStateDir(implStateDir);
|
|
391
|
+
// takePreSnapshot transitions directly to RUNNING with the snapshot payload
|
|
392
|
+
// and workingDir/implStateDir paths set. We cannot transition
|
|
393
|
+
// PRE_SNAPSHOT → PRE_SNAPSHOT (invalid); the snapshot is immediately ready
|
|
394
|
+
// (it's just the provisioned dir context), so we advance to RUNNING in one
|
|
395
|
+
// step. The impl is responsible for capturing real market data.
|
|
396
|
+
this.persistence.transition(run.requestId, TaskRunState.RUNNING, {
|
|
397
|
+
workingDir,
|
|
398
|
+
implStateDir,
|
|
399
|
+
preSnapshotCapturedAt: Date.now(),
|
|
400
|
+
preSnapshotPayload: { provisioned: true, workingDir },
|
|
401
|
+
});
|
|
402
|
+
console.log(`[harness-engine] ${run.requestId} PRE_SNAPSHOT -> RUNNING: workingDir=${workingDir}`);
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* RUNNING transition: dispatch to a Harness if implRegistry is provided.
|
|
406
|
+
*
|
|
407
|
+
* When no impl is found for the solverType, falls back to NotImplementedError
|
|
408
|
+
* so the engine does not silently swallow the request. In tests that don't
|
|
409
|
+
* exercise the impl path, override this method.
|
|
410
|
+
*
|
|
411
|
+
* Captures impl output in `solutionOutputs` map for pack() to consume. Also
|
|
412
|
+
* records a minimal post-snapshot so data-driven advance can fire.
|
|
413
|
+
*/
|
|
414
|
+
async runImpl(task) {
|
|
415
|
+
const solverType = task.solverType ?? '';
|
|
416
|
+
const role = task.taskRole ?? 'restoration';
|
|
417
|
+
const solverNet = solverType ? this.solverNetRegistry?.forSolverType(solverType) : undefined;
|
|
418
|
+
const impl = this.implRegistry?.findFor({ solverType, role });
|
|
419
|
+
if (!impl) {
|
|
420
|
+
throw new NotImplementedError('runImpl');
|
|
421
|
+
}
|
|
422
|
+
const runtimePlugins = solverNet
|
|
423
|
+
? [solverNet.canonicalPlugin, ...solverNet.plugins]
|
|
424
|
+
: [];
|
|
425
|
+
this.runtimePluginsByRequest.set(task.requestId, runtimePlugins);
|
|
426
|
+
const workingDir = task.workingDir ?? join(this.paths.workingDirRoot, task.requestId);
|
|
427
|
+
const kindSeg = solverType.replace(/[.:]/g, '_');
|
|
428
|
+
const implStateDir = task.implStateDir ?? (kindSeg
|
|
429
|
+
? join(this.paths.implStateDirRoot, impl.name, kindSeg)
|
|
430
|
+
: join(this.paths.implStateDirRoot, impl.name));
|
|
431
|
+
const windowEndTs = task.windowEndTs;
|
|
432
|
+
const abort = new AbortController();
|
|
433
|
+
const msUntilEndTs = () => Math.max(0, windowEndTs - Date.now());
|
|
434
|
+
const endTimer = setTimeout(() => abort.abort(), msUntilEndTs());
|
|
435
|
+
// Create a trajectory collector for this run.
|
|
436
|
+
const trajectory = new TrajectoryCollector({
|
|
437
|
+
taskCid: task.taskCid ?? '',
|
|
438
|
+
runId: randomUUID(),
|
|
439
|
+
});
|
|
440
|
+
try {
|
|
441
|
+
const ctx = {
|
|
442
|
+
task: (task.task ?? {
|
|
443
|
+
id: task.requestId,
|
|
444
|
+
description: '',
|
|
445
|
+
...(task.solverType ? { solverType: task.solverType, spec: {} } : {}),
|
|
446
|
+
role,
|
|
447
|
+
window: { startTs: task.windowStartTs, endTs: task.windowEndTs },
|
|
448
|
+
}),
|
|
449
|
+
taskCid: task.taskCid,
|
|
450
|
+
solverNet: solverNet ? { name: solverNet.name, solverType: solverNet.solverType } : undefined,
|
|
451
|
+
runtimePlugins,
|
|
452
|
+
solverPluginRoots: runtimePlugins.map((plugin) => plugin.root),
|
|
453
|
+
implStateDir,
|
|
454
|
+
workingDir,
|
|
455
|
+
log: (event) => {
|
|
456
|
+
console.log(`[harness-impl:${impl.name}] [${event.level}] ${event.msg}`, event.data ?? '');
|
|
457
|
+
},
|
|
458
|
+
abort: abort.signal,
|
|
459
|
+
msUntilEndTs,
|
|
460
|
+
trajectory,
|
|
461
|
+
};
|
|
462
|
+
let output;
|
|
463
|
+
try {
|
|
464
|
+
output = await impl.run(ctx);
|
|
465
|
+
}
|
|
466
|
+
catch (err) {
|
|
467
|
+
if (err instanceof SkippableError) {
|
|
468
|
+
const skippedAt = Date.now();
|
|
469
|
+
const detail = err.message;
|
|
470
|
+
console.warn(`[harness-engine] ${task.requestId}: impl=${impl.name} skipped (${err.reason}): ${detail}`);
|
|
471
|
+
output = {
|
|
472
|
+
venueRef: { name: 'legacy' },
|
|
473
|
+
gating: {
|
|
474
|
+
skipped: true,
|
|
475
|
+
reason: err.reason,
|
|
476
|
+
skippedAt: String(skippedAt),
|
|
477
|
+
},
|
|
478
|
+
informational: {
|
|
479
|
+
status: 'skipped',
|
|
480
|
+
detail,
|
|
481
|
+
},
|
|
482
|
+
artifacts: [],
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
else {
|
|
486
|
+
throw err;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
this.solutionOutputs.set(task.requestId, output);
|
|
490
|
+
// Store the trajectory collector so pack() can:
|
|
491
|
+
// 1. pass it to uploadArtifacts (artifact.emit spans + producedBy metadata)
|
|
492
|
+
// 2. call emitTrajectory AFTER artifact upload so spans are included
|
|
493
|
+
// 3. backfill trajectoryCid on artifacts before envelope assembly
|
|
494
|
+
// emitTrajectory is intentionally deferred to pack() (Task 16).
|
|
495
|
+
this.trajectoryCollectors.set(task.requestId, trajectory);
|
|
496
|
+
// Persist impl output BEFORE the state transition so that a crash after
|
|
497
|
+
// the transition (RUNNING → POST_SNAPSHOT) but before pack() runs will
|
|
498
|
+
// find the serialised output in the DB on restart. pack() will hydrate the
|
|
499
|
+
// in-memory map from solutionOutputsJson if the map entry is absent (#6).
|
|
500
|
+
// Capture post-snapshot from impl output so data-driven advance fires
|
|
501
|
+
this.persistence.transition(task.requestId, TaskRunState.POST_SNAPSHOT, {
|
|
502
|
+
postSnapshotCapturedAt: Date.now(),
|
|
503
|
+
postSnapshotPayload: output.postSnapshot ?? { capturedAt: Date.now(), hlTime: 0, payload: null },
|
|
504
|
+
fillsPayload: output.fills ?? [],
|
|
505
|
+
gatingClaim: output.gating,
|
|
506
|
+
informationalClaim: output.informational ?? null,
|
|
507
|
+
solutionOutputsJson: JSON.stringify(output),
|
|
508
|
+
implName: impl.name,
|
|
509
|
+
runtimePluginsJson: JSON.stringify(runtimePlugins),
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
finally {
|
|
513
|
+
clearTimeout(endTimer);
|
|
514
|
+
}
|
|
515
|
+
console.log(`[harness-engine] ${task.requestId} RUNNING → POST_SNAPSHOT via impl=${impl.name}`);
|
|
516
|
+
}
|
|
517
|
+
async takePostSnapshot(_intent) {
|
|
518
|
+
throw new NotImplementedError('takePostSnapshot');
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* PACKAGING transition: walk workingDir, upload artifacts, assemble + sign
|
|
522
|
+
* envelope, upload envelope, persist envelope CID + artifact CIDs.
|
|
523
|
+
*
|
|
524
|
+
* Requires packagingDeps + envelopeDeps. When absent, falls back to
|
|
525
|
+
* NotImplementedError.
|
|
526
|
+
*/
|
|
527
|
+
async pack(task) {
|
|
528
|
+
// Hydrate implOutput from DB if the in-memory map was lost (e.g. process restart
|
|
529
|
+
// after RUNNING → POST_SNAPSHOT but before pack() completed). This must run
|
|
530
|
+
// BEFORE the packagingDeps guard so subclass overrides that call super.pack()
|
|
531
|
+
// can still benefit from hydration even when packagingDeps is absent (#6).
|
|
532
|
+
if (!this.solutionOutputs.has(task.requestId) && task.solutionOutputsJson != null) {
|
|
533
|
+
try {
|
|
534
|
+
const recovered = JSON.parse(task.solutionOutputsJson);
|
|
535
|
+
this.solutionOutputs.set(task.requestId, recovered);
|
|
536
|
+
console.log(`[harness-engine] ${task.requestId}: hydrated solutionOutputs from DB (crash recovery)`);
|
|
537
|
+
}
|
|
538
|
+
catch (err) {
|
|
539
|
+
console.warn(`[harness-engine] ${task.requestId}: failed to hydrate solutionOutputsJson: ${err instanceof Error ? err.message : err}`);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
if (!this.packagingDeps || !this.envelopeDeps) {
|
|
543
|
+
throw new NotImplementedError('pack');
|
|
544
|
+
}
|
|
545
|
+
const workingDir = task.workingDir ?? join(this.paths.workingDirRoot, task.requestId);
|
|
546
|
+
const implOutput = this.solutionOutputs.get(task.requestId);
|
|
547
|
+
const implArtifacts = implOutput?.artifacts ?? [];
|
|
548
|
+
// 1. Walk + upload artifacts (NO registration yet — manifest CID not known).
|
|
549
|
+
// Pass the trajectory collector (if present) so uploadArtifacts can emit
|
|
550
|
+
// jinn.artifact.emit spans and attach producedBy back-refs (Task 16 forward
|
|
551
|
+
// linkage). emitTrajectory is called AFTER upload so artifact spans are included.
|
|
552
|
+
const collector = this.trajectoryCollectors.get(task.requestId);
|
|
553
|
+
const packagingDepsWithReq = {
|
|
554
|
+
...this.packagingDeps,
|
|
555
|
+
requestId: task.requestId,
|
|
556
|
+
...(collector ? { collector } : {}),
|
|
557
|
+
};
|
|
558
|
+
const rawArtifacts = await walkArtifacts(workingDir, implArtifacts);
|
|
559
|
+
const uploadedArtifacts = await uploadArtifacts(rawArtifacts, packagingDepsWithReq);
|
|
560
|
+
// 1b. Emit trajectory to IPFS now that all artifact spans have been added.
|
|
561
|
+
// Non-fatal — envelope assembly continues with envelope.trajectory = null if upload fails.
|
|
562
|
+
let trajectoryRef = this.trajectoryRefs.get(task.requestId) ?? null;
|
|
563
|
+
if (!trajectoryRef && collector && this.envelopeDeps) {
|
|
564
|
+
try {
|
|
565
|
+
const { privateKeyToAccount } = await import('viem/accounts');
|
|
566
|
+
const account = privateKeyToAccount(this.envelopeDeps.agentEoaPrivateKey);
|
|
567
|
+
const { cid, sha256 } = await emitTrajectory({
|
|
568
|
+
collector,
|
|
569
|
+
runId: collector.runId,
|
|
570
|
+
signerPrivateKey: this.envelopeDeps.agentEoaPrivateKey,
|
|
571
|
+
signerAddress: account.address,
|
|
572
|
+
ipfsRegistryUrl: this.envelopeDeps.ipfsRegistryUrl,
|
|
573
|
+
});
|
|
574
|
+
trajectoryRef = { cid, sha256 };
|
|
575
|
+
console.log(`[harness-engine] ${task.requestId}: trajectory emitted cid=${cid}`);
|
|
576
|
+
}
|
|
577
|
+
catch (err) {
|
|
578
|
+
console.warn(`[harness-engine] ${task.requestId}: trajectory emit failed (non-fatal):`, err instanceof Error ? err.message : err);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
this.trajectoryRefs.set(task.requestId, trajectoryRef);
|
|
582
|
+
// 1c. Backward linkage: backfill trajectoryCid on all artifacts that have a
|
|
583
|
+
// producedBy back-ref. This must happen BEFORE assembleAndSignEnvelope so the
|
|
584
|
+
// signed envelope carries the complete reference (Task 16).
|
|
585
|
+
if (trajectoryRef) {
|
|
586
|
+
const trajectoryCid = trajectoryRef.cid;
|
|
587
|
+
for (const art of uploadedArtifacts) {
|
|
588
|
+
const pb = art.metadata?.['producedBy'];
|
|
589
|
+
if (pb != null && typeof pb === 'object' && 'spanId' in pb) {
|
|
590
|
+
pb['trajectoryCid'] = trajectoryCid;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
// Map to Artifact shape (strip localPath)
|
|
595
|
+
const artifacts = uploadedArtifacts.map(({ localPath: _localPath, ...art }) => art);
|
|
596
|
+
// 2. Derive agentEoa from private key
|
|
597
|
+
const { privateKeyToAccount } = await import('viem/accounts');
|
|
598
|
+
const account = privateKeyToAccount(this.envelopeDeps.agentEoaPrivateKey);
|
|
599
|
+
const agentEoa = account.address;
|
|
600
|
+
// Safe multisig address — sourced from envelopeDeps (preferred) or deliveryDeps.
|
|
601
|
+
// Hard throw if absent: falling back to agentEoa would produce a
|
|
602
|
+
// protocol-invalid envelope (safeAddress MUST differ from agentEoa, §5.1).
|
|
603
|
+
const safeAddress = this.envelopeDeps.safeAddress ?? this.deliveryDeps?.safeAddress;
|
|
604
|
+
if (!safeAddress) {
|
|
605
|
+
throw new Error('pack: safeAddress not configured in envelopeDeps or deliveryDeps');
|
|
606
|
+
}
|
|
607
|
+
// 3. Build envelope payload from impl output (kind-typed, wrapped into payload field)
|
|
608
|
+
const preSnapshotPayload = task.preSnapshotPayload;
|
|
609
|
+
const postSnapshotPayload = task.postSnapshotPayload;
|
|
610
|
+
// The solverType drives payload schema selection. Fall back to 'legacy.v0'
|
|
611
|
+
// for tasks without a solverType (legacy health-check / daemon-loop-test
|
|
612
|
+
// tasks that use the legacy-claude impl). The legacy.v0 kind accepts any
|
|
613
|
+
// Record payload so validatePayload does not reject the output.
|
|
614
|
+
const solverType = task.solverType ?? 'legacy.v0';
|
|
615
|
+
// Derive role from Task.role. Evaluator tasks produce 'verdict' envelopes;
|
|
616
|
+
// all other tasks produce 'restoration' envelopes.
|
|
617
|
+
const isEvaluation = task.taskRole === 'evaluation';
|
|
618
|
+
const role = isEvaluation ? 'verdict' : 'restoration';
|
|
619
|
+
let envelopePayload;
|
|
620
|
+
if (isEvaluation) {
|
|
621
|
+
// ── Verdict envelope payload ──────────────────────────────────────────────
|
|
622
|
+
// The evaluator impl populates verdictPayload on Solution with a
|
|
623
|
+
// PortfolioV0VerdictPayload-shaped object. Engine passes it through to the
|
|
624
|
+
// envelope assembler, which runs validatePayload('portfolio.v0', 'verdict', ...).
|
|
625
|
+
//
|
|
626
|
+
// If verdictPayload is absent (impl bug / crash recovery), fall back to a
|
|
627
|
+
// minimal INDETERMINATE stub so the envelope assembly does not silently succeed
|
|
628
|
+
// with a wrong shape — validatePayload will catch schema mismatches.
|
|
629
|
+
//
|
|
630
|
+
// verificationOfRestoration: stubbed — Plan D will connect the real SDK.
|
|
631
|
+
// restorationEnvelope.sha256: placeholder — Plan D wires real sha256 derivation.
|
|
632
|
+
const verdictPayload = implOutput?.verdictPayload;
|
|
633
|
+
if (!verdictPayload) {
|
|
634
|
+
throw new Error(`pack: evaluator impl for ${task.requestId} did not produce verdictPayload on Solution; ` +
|
|
635
|
+
`ensure the impl populates output.verdictPayload`);
|
|
636
|
+
}
|
|
637
|
+
// If the (stub) verificationOfRestoration reports 'invalid', downgrade verdict
|
|
638
|
+
// to REJECTED per scope §3.3. For V1 the stub always returns 'valid', so this
|
|
639
|
+
// path does not fire in practice — Plan D makes it real.
|
|
640
|
+
const verif = verdictPayload['verificationOfRestoration'];
|
|
641
|
+
if (verif?.overall === 'invalid') {
|
|
642
|
+
// Override verdict to REJECTED; preserve the rest of the payload.
|
|
643
|
+
envelopePayload = {
|
|
644
|
+
...verdictPayload,
|
|
645
|
+
verdict: 'REJECTED',
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
else {
|
|
649
|
+
envelopePayload = verdictPayload;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
else if (implOutput?.solutionPayload) {
|
|
653
|
+
// ── Non-portfolio restoration envelope payload ────────────────────────────
|
|
654
|
+
// Impls for kinds with a non-portfolio payload schema (e.g. prediction.v0)
|
|
655
|
+
// declare their own fully-formed payload. Engine passes it through directly
|
|
656
|
+
// so validatePayload() can check it against the per-kind schema.
|
|
657
|
+
envelopePayload = implOutput.solutionPayload;
|
|
658
|
+
}
|
|
659
|
+
else {
|
|
660
|
+
// ── Portfolio restoration envelope payload (legacy / portfolio.v0) ─────────
|
|
661
|
+
envelopePayload = {
|
|
662
|
+
preSnapshot: {
|
|
663
|
+
capturedAt: task.preSnapshotCapturedAt ?? Date.now(),
|
|
664
|
+
hlTime: preSnapshotPayload?.hlTime ?? 0,
|
|
665
|
+
// Double-fallback: first tries the structured .payload field (normal shape),
|
|
666
|
+
// then falls back to the whole payload object (handles takePreSnapshot's
|
|
667
|
+
// synthetic shape where the snapshot IS the top-level object, not nested).
|
|
668
|
+
payload: preSnapshotPayload?.payload ?? preSnapshotPayload ?? {},
|
|
669
|
+
},
|
|
670
|
+
postSnapshot: {
|
|
671
|
+
capturedAt: task.postSnapshotCapturedAt ?? Date.now(),
|
|
672
|
+
hlTime: postSnapshotPayload?.hlTime ?? 0,
|
|
673
|
+
// Same double-fallback as above.
|
|
674
|
+
payload: postSnapshotPayload?.payload ?? postSnapshotPayload ?? {},
|
|
675
|
+
},
|
|
676
|
+
fills: task.fillsPayload ?? [],
|
|
677
|
+
gating: task.gatingClaim ?? {},
|
|
678
|
+
...(task.informationalClaim != null
|
|
679
|
+
? { informational: task.informationalClaim }
|
|
680
|
+
: {}),
|
|
681
|
+
...(implOutput?.rationale != null ? { rationale: implOutput.rationale } : {}),
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
// 4. Persist generatedAt once (first pack); reuse on retry for CID determinism.
|
|
685
|
+
const generatedAt = task.manifestGeneratedAt ?? Date.now();
|
|
686
|
+
if (!task.manifestGeneratedAt) {
|
|
687
|
+
// Persist before assembling so that a crash after assembly but before
|
|
688
|
+
// transition still gets the same generatedAt on the next attempt.
|
|
689
|
+
this.persistence.setManifestGeneratedAt(task.requestId, generatedAt);
|
|
690
|
+
}
|
|
691
|
+
// 5. Assemble + sign envelope → envelope CID now known.
|
|
692
|
+
// trajectoryRef was computed in step 1b above (emitted after artifact upload).
|
|
693
|
+
// Per the post-gating-fix schema, trajectory references carry sha256 + access
|
|
694
|
+
// (the operator HTTP endpoint that serves the bytes). Phase 3 (jinn-mono-vy37.1.3)
|
|
695
|
+
// sources this from the engine's operatorConfig; absent operatorConfig (e.g. test
|
|
696
|
+
// fixtures) falls back to packagingDeps.operatorEndpoint, then to a localhost
|
|
697
|
+
// sentinel so suites that don't exercise the publish path still pack cleanly.
|
|
698
|
+
const operatorEndpointForTraj = this.operatorConfig?.publicEndpoint
|
|
699
|
+
?? this.packagingDeps?.operatorEndpoint
|
|
700
|
+
?? 'http://localhost:7331';
|
|
701
|
+
const envelopeTrajectory = trajectoryRef
|
|
702
|
+
? {
|
|
703
|
+
sha256: trajectoryRef.sha256,
|
|
704
|
+
access: { endpoint: operatorEndpointForTraj, priceUsdc: '0' },
|
|
705
|
+
}
|
|
706
|
+
: null;
|
|
707
|
+
// evidenceTier reflects the on-chain commitment state at the time of signing.
|
|
708
|
+
// For the V2 claim flow, claimDelivery will write an evidenceHash on-chain,
|
|
709
|
+
// so the envelope should be declared 'committed'. For V1 or unknown flows,
|
|
710
|
+
// 'self-signed' is accurate (no on-chain hash commitment).
|
|
711
|
+
const evidenceTier = this.deliveryDeps?.claimDeliveryVariant === 'v2' ? 'committed' : 'self-signed';
|
|
712
|
+
const runtimePlugins = this.runtimePluginsByRequest.get(task.requestId)
|
|
713
|
+
?? (task.runtimePluginsJson ? JSON.parse(task.runtimePluginsJson) : []);
|
|
714
|
+
const executorPlugins = runtimePlugins
|
|
715
|
+
.map((plugin) => ({
|
|
716
|
+
name: plugin.name,
|
|
717
|
+
version: plugin.version,
|
|
718
|
+
...(plugin.cid ? { cid: plugin.cid } : {}),
|
|
719
|
+
sha256: plugin.sha256,
|
|
720
|
+
}))
|
|
721
|
+
.sort((a, b) => `${a.name}@${a.version}`.localeCompare(`${b.name}@${b.version}`));
|
|
722
|
+
const implNameForEnvelope = task.implName ?? solverType;
|
|
723
|
+
const solverNet = solverType ? this.solverNetRegistry?.forSolverType(solverType) : undefined;
|
|
724
|
+
const runtimeBundleDigest = `sha256:${createHash('sha256')
|
|
725
|
+
.update(JSON.stringify({
|
|
726
|
+
harness: {
|
|
727
|
+
name: implNameForEnvelope,
|
|
728
|
+
version: buildInfo.implVersion,
|
|
729
|
+
codeDigest: buildInfo.codeDigest,
|
|
730
|
+
},
|
|
731
|
+
solverNet: solverNet ? { name: solverNet.name, solverType: solverNet.solverType } : null,
|
|
732
|
+
plugins: executorPlugins,
|
|
733
|
+
}))
|
|
734
|
+
.digest('hex')}`;
|
|
735
|
+
const envelopeInputs = {
|
|
736
|
+
solverType,
|
|
737
|
+
role,
|
|
738
|
+
task: {
|
|
739
|
+
cid: task.taskCid,
|
|
740
|
+
onchainCreationTx: task.onchainCreationTx,
|
|
741
|
+
onchainCreationBlock: task.onchainCreationBlock,
|
|
742
|
+
requestId: task.requestId,
|
|
743
|
+
},
|
|
744
|
+
participant: { safeAddress, agentEoa },
|
|
745
|
+
window: { startTs: task.windowStartTs, endTs: task.windowEndTs },
|
|
746
|
+
executor: {
|
|
747
|
+
implName: implNameForEnvelope,
|
|
748
|
+
// buildInfo resolves to real values in production builds; falls back to
|
|
749
|
+
// clearly-labelled placeholders ('dev' / 'sha256:dev-build') when running
|
|
750
|
+
// via tsx without a prior `yarn build` (dev mode).
|
|
751
|
+
implVersion: buildInfo.implVersion,
|
|
752
|
+
clientGitSha: buildInfo.clientGitSha,
|
|
753
|
+
codeDigest: buildInfo.codeDigest,
|
|
754
|
+
runtimeBundleDigest,
|
|
755
|
+
plugins: executorPlugins,
|
|
756
|
+
signingKey: { kind: 'agent-eoa', pubkey: agentEoa },
|
|
757
|
+
},
|
|
758
|
+
evidenceTier,
|
|
759
|
+
trajectory: envelopeTrajectory,
|
|
760
|
+
artifacts,
|
|
761
|
+
payload: envelopePayload,
|
|
762
|
+
generatedAt,
|
|
763
|
+
};
|
|
764
|
+
const { envelopeCid, envelopeHash } = await assembleAndSignEnvelope(envelopeInputs, this.envelopeDeps);
|
|
765
|
+
const manifestCid = envelopeCid;
|
|
766
|
+
const signatureHash = envelopeHash;
|
|
767
|
+
// 6. ERC-8004 IdentityRegistry per-execution `setMetadata` fires in
|
|
768
|
+
// deliver() AFTER claimDelivery succeeds. 'committed' must mean
|
|
769
|
+
// "observable on-chain evidenceHash exists" — publishing before claim
|
|
770
|
+
// would lie during failures. The evidenceHash (signatureHash) is
|
|
771
|
+
// persisted to DELIVERING state below and reused by deliver().
|
|
772
|
+
// Operator-rooted entity model: docs/superpowers/specs/2026-04-27-erc-8004-entity-model-design.md.
|
|
773
|
+
// 7. Build artifact sha256 map for persistence.
|
|
774
|
+
// Post-gating-fix (spec §1): artifacts no longer have IPFS CIDs — bytes
|
|
775
|
+
// live in served_artifacts keyed by sha256. We reuse the legacy
|
|
776
|
+
// `artifactCids` persistence column (key: localPath) but populate it with
|
|
777
|
+
// sha256 hashes so downstream readers still get a stable identifier.
|
|
778
|
+
const artifactCids = {};
|
|
779
|
+
for (const art of uploadedArtifacts) {
|
|
780
|
+
artifactCids[art.localPath] = art.sha256;
|
|
781
|
+
}
|
|
782
|
+
// Backfill envelope_cid (manifestCid) on every served_artifacts row so
|
|
783
|
+
// the operator can answer manifest-rooted lookups later. Done after the
|
|
784
|
+
// manifest CID is known.
|
|
785
|
+
for (const art of uploadedArtifacts) {
|
|
786
|
+
this.store.setServedArtifactEnvelopeCid(art.sha256, manifestCid);
|
|
787
|
+
}
|
|
788
|
+
// 8. Persist DELIVERING with manifest CID + artifact CIDs + evidence hash.
|
|
789
|
+
// evidenceHash gets its own dedicated column (not stashed in informationalClaim).
|
|
790
|
+
this.persistence.transition(task.requestId, TaskRunState.DELIVERING, {
|
|
791
|
+
manifestCid,
|
|
792
|
+
artifactCids,
|
|
793
|
+
evidenceHash: signatureHash,
|
|
794
|
+
});
|
|
795
|
+
console.log(`[harness-engine] ${task.requestId} PACKAGING → DELIVERING manifestCid=${manifestCid}`);
|
|
796
|
+
// Clean up transient state (no longer needed after DELIVERING)
|
|
797
|
+
this.solutionOutputs.delete(task.requestId);
|
|
798
|
+
this.trajectoryCollectors.delete(task.requestId);
|
|
799
|
+
this.trajectoryRefs.delete(task.requestId);
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* DELIVERING transition: call mech.deliverToMarketplace + JinnRouter.claimDelivery.
|
|
803
|
+
*
|
|
804
|
+
* Requires deliveryDeps. When absent, falls back to NotImplementedError.
|
|
805
|
+
*
|
|
806
|
+
* Crash-recovery safe: if `task.deliveryTxHash` is already set (persisted
|
|
807
|
+
* after a previous deliverToMarketplace call that completed before the process
|
|
808
|
+
* crashed), we skip the deliver step and go straight to claimDelivery.
|
|
809
|
+
*/
|
|
810
|
+
async deliver(task) {
|
|
811
|
+
if (!this.deliveryDeps) {
|
|
812
|
+
throw new NotImplementedError('deliver');
|
|
813
|
+
}
|
|
814
|
+
const manifestCid = task.manifestCid;
|
|
815
|
+
if (!manifestCid) {
|
|
816
|
+
throw new Error(`deliver: manifestCid missing for ${task.requestId}`);
|
|
817
|
+
}
|
|
818
|
+
// Guard: v2 claimDelivery requires an evidenceHash — a zero fallback would
|
|
819
|
+
// silently brick staking rewards, so we fail loudly instead.
|
|
820
|
+
const evidenceHash = task.evidenceHash;
|
|
821
|
+
if (!evidenceHash && this.deliveryDeps.claimDeliveryVariant === 'v2') {
|
|
822
|
+
throw new MissingEvidenceHashError(task.requestId);
|
|
823
|
+
}
|
|
824
|
+
// Capture locals for use in the onDeliveryTxLanded closure.
|
|
825
|
+
const requestId = task.requestId;
|
|
826
|
+
const persistence = this.persistence;
|
|
827
|
+
const { deliveryTxHash, claimTxHash } = await deliverAndClaim(requestId, manifestCid, evidenceHash, this.deliveryDeps,
|
|
828
|
+
// Recovery: pass existing deliveryTxHash so deliverToMarketplace is skipped.
|
|
829
|
+
task.deliveryTxHash ?? undefined,
|
|
830
|
+
// Persist deliveryTxHash before claimDelivery so recovery can resume from here.
|
|
831
|
+
async (txHash) => {
|
|
832
|
+
persistence.setDeliveryTxHash(requestId, txHash);
|
|
833
|
+
});
|
|
834
|
+
this.persistence.transition(requestId, TaskRunState.COMPLETE, {
|
|
835
|
+
deliveryTxHash,
|
|
836
|
+
});
|
|
837
|
+
console.log(`[harness-engine] ${requestId} DELIVERING → COMPLETE deliveryTx=${deliveryTxHash} claimTx=${claimTxHash}`);
|
|
838
|
+
// Emit a SQLite artifact row so consumers (release acceptance gate, search
|
|
839
|
+
// API) see this cycle alongside legacy-claude / MCP-emitted rows. The
|
|
840
|
+
// legacy claude path writes via the MCP `submit_restoration_result` tool;
|
|
841
|
+
// deterministic impls (prediction-v0-baseline, prediction-v0-evaluator,
|
|
842
|
+
// …) don't go through MCP, so the engine emits on their behalf here.
|
|
843
|
+
// Idempotent: skips when a row for this requestId+tag already exists
|
|
844
|
+
// (legacy path may have already inserted).
|
|
845
|
+
this.emitCycleArtifact(task, manifestCid, evidenceHash);
|
|
846
|
+
// ── ERC-8004 setMetadata — fires AFTER claimDelivery succeeds ────────────
|
|
847
|
+
//
|
|
848
|
+
// Moved here from pack() per PR#37 review2 must-fix #2. 'committed' means
|
|
849
|
+
// "observable on-chain evidenceHash exists" — publishing before claim would
|
|
850
|
+
// lie during failures. evidenceHash comes from task (persisted in
|
|
851
|
+
// DELIVERING state by pack()); idempotent on retry (setMetadata is a pure
|
|
852
|
+
// key-value write; re-running with the same payload is safe).
|
|
853
|
+
//
|
|
854
|
+
// Restoration-only for now. Evaluator setMetadata lands with jinn-mono-2ff.
|
|
855
|
+
if (this.identityPublisher) {
|
|
856
|
+
const taskRoleRaw = task.taskRole ?? 'restoration';
|
|
857
|
+
if (taskRoleRaw === 'restoration') {
|
|
858
|
+
const signatureHash = evidenceHash;
|
|
859
|
+
// v0 tier rule: with an evidenceHash on chain we declare `committed` (tier=1);
|
|
860
|
+
// higher tiers (`attested`, `proved`) come later when TEE work lands.
|
|
861
|
+
const tier = signatureHash ? 1 : 0;
|
|
862
|
+
const setMetadataPayload = {
|
|
863
|
+
version: 1,
|
|
864
|
+
tier,
|
|
865
|
+
manifestHash: signatureHash ?? '0x',
|
|
866
|
+
attestationQuoteCid: '0x',
|
|
867
|
+
sourceMeasurement: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
868
|
+
};
|
|
869
|
+
try {
|
|
870
|
+
const pubTxHash = await this.identityPublisher.publishContent({
|
|
871
|
+
kind: 'envelope',
|
|
872
|
+
cid: manifestCid,
|
|
873
|
+
payload: setMetadataPayload,
|
|
874
|
+
});
|
|
875
|
+
console.log(`[harness-engine] ${requestId}: setMetadata envelope:${manifestCid} tx=${pubTxHash}`);
|
|
876
|
+
}
|
|
877
|
+
catch (err) {
|
|
878
|
+
console.warn(`[harness-engine] ${requestId}: setMetadata envelope publish failed (non-fatal): ${err instanceof Error ? err.message : err}`);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
// ── Reputation feedback hook (jinn-mono-yg4) ─────────────────────────────
|
|
883
|
+
//
|
|
884
|
+
// Evaluator-only path: after `claimDelivery` settles the verdict, fire
|
|
885
|
+
// `ReputationRegistry.giveFeedback(harnessAgentId, ...)` so the
|
|
886
|
+
// harness's agent NFT accrues a rating (DR §4.3).
|
|
887
|
+
//
|
|
888
|
+
// Best-effort: any failure inside the hook is logged but does not
|
|
889
|
+
// change the COMPLETE state. claimDelivery is already authoritative.
|
|
890
|
+
if (task.taskRole === 'evaluation' && this.reputationFeedback) {
|
|
891
|
+
await this._maybePostEvaluatorFeedback(task).catch((err) => {
|
|
892
|
+
console.warn(`[harness-engine] ${requestId}: reputation feedback hook errored unexpectedly (non-fatal): ${err instanceof Error ? err.message : err}`);
|
|
893
|
+
});
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
/**
|
|
897
|
+
* Post evaluator feedback on the harness's agent NFT.
|
|
898
|
+
*
|
|
899
|
+
* Pulls the verdict from the persisted gating claim (the evaluator impl
|
|
900
|
+
* writes `{ verdict, score, scoreBasis, ... }` into `output.gating`),
|
|
901
|
+
* resolves the harness's `agentId` via the configured subgraph
|
|
902
|
+
* resolver, and submits a single `ReputationRegistry.giveFeedback` tx.
|
|
903
|
+
*
|
|
904
|
+
* Skipped silently when:
|
|
905
|
+
* - No `reputationFeedback` deps wired.
|
|
906
|
+
* - `gatingClaim` doesn't carry a verdict (impl shape mismatch — log and
|
|
907
|
+
* return).
|
|
908
|
+
* - The parent harness's manifest hash isn't reachable from the
|
|
909
|
+
* persisted state — log and return).
|
|
910
|
+
* - `resolveAgentId` returns null (subgraph not indexed yet, or no
|
|
911
|
+
* subgraph URL configured at all — log and return).
|
|
912
|
+
*
|
|
913
|
+
* The mapping policy (PASS / FAIL / REJECTED / INDETERMINATE → score) lives
|
|
914
|
+
* inside `submitEvaluatorFeedback` / `mapVerdictToScore` in the
|
|
915
|
+
* feedback-hook module; we just hand it the verdict.
|
|
916
|
+
*/
|
|
917
|
+
/**
|
|
918
|
+
* Insert a SQLite `artifacts` row for a successfully delivered cycle so the
|
|
919
|
+
* release acceptance gate (and the search API) can observe completion via
|
|
920
|
+
* the same surface as the legacy claude / MCP path.
|
|
921
|
+
*
|
|
922
|
+
* The legacy `legacy-claude` impl writes via the MCP `submit_restoration_result`
|
|
923
|
+
* tool when Claude reports success; deterministic impls don't go through MCP.
|
|
924
|
+
* This emitter closes that gap by writing the row from the engine when the
|
|
925
|
+
* cycle hits COMPLETE.
|
|
926
|
+
*
|
|
927
|
+
* Idempotent: if a row already exists for (requestId, tag) — e.g. the legacy
|
|
928
|
+
* MCP path got there first — we leave it alone.
|
|
929
|
+
*/
|
|
930
|
+
emitCycleArtifact(task, manifestCid, evidenceHash) {
|
|
931
|
+
const taskId = task.task?.id;
|
|
932
|
+
if (!taskId) {
|
|
933
|
+
// Rows without task payload cannot be attributed to a Task id. Skip
|
|
934
|
+
// rather than synthesise provenance.
|
|
935
|
+
return;
|
|
936
|
+
}
|
|
937
|
+
const taskRole = task.taskRole ?? 'restoration';
|
|
938
|
+
const tag = taskRole === 'evaluation' ? 'evaluation-verdict' : 'restoration-result';
|
|
939
|
+
const existing = this.store.getArtifactByRequestId(task.requestId, tag);
|
|
940
|
+
if (existing)
|
|
941
|
+
return;
|
|
942
|
+
this.store.insertArtifact({
|
|
943
|
+
id: randomUUID(),
|
|
944
|
+
taskId,
|
|
945
|
+
requestId: task.requestId,
|
|
946
|
+
title: `${tag}: ${task.solverType ?? 'cycle'} (${task.implName ?? 'engine'})`,
|
|
947
|
+
content: JSON.stringify({
|
|
948
|
+
manifestCid,
|
|
949
|
+
evidenceHash: evidenceHash ?? null,
|
|
950
|
+
implName: task.implName,
|
|
951
|
+
}),
|
|
952
|
+
tags: [tag, 'success'],
|
|
953
|
+
outcome: 'SUCCESS',
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
async _maybePostEvaluatorFeedback(task) {
|
|
957
|
+
if (!this.reputationFeedback)
|
|
958
|
+
return;
|
|
959
|
+
const gating = task.gatingClaim;
|
|
960
|
+
const verdictRaw = gating?.['verdict'];
|
|
961
|
+
if (verdictRaw !== 'PASS' &&
|
|
962
|
+
verdictRaw !== 'FAIL' &&
|
|
963
|
+
verdictRaw !== 'REJECTED' &&
|
|
964
|
+
verdictRaw !== 'INDETERMINATE') {
|
|
965
|
+
console.warn(`[harness-engine] ${task.requestId}: reputation feedback skipped — gatingClaim has no recognised verdict (got=${String(verdictRaw)})`);
|
|
966
|
+
return;
|
|
967
|
+
}
|
|
968
|
+
const verdict = verdictRaw;
|
|
969
|
+
// Pull the parent harness's manifest evidence from the inlined eval
|
|
970
|
+
// payload. The evaluator impl receives the harness's signed manifest
|
|
971
|
+
// JSON via `task.context.restorationResult` (see
|
|
972
|
+
// `MechAdapter.tryCreateEvaluationJob`). Its `signature.hash` is
|
|
973
|
+
// exactly what the harness committed via `claimDelivery(evidenceHash)`.
|
|
974
|
+
const parent = this._extractHarnessManifestRef(task);
|
|
975
|
+
if (!parent) {
|
|
976
|
+
console.warn(`[harness-engine] ${task.requestId}: reputation feedback skipped — could not extract harness manifest hash from inlined evaluation payload`);
|
|
977
|
+
return;
|
|
978
|
+
}
|
|
979
|
+
let resolved;
|
|
980
|
+
try {
|
|
981
|
+
resolved = await this.reputationFeedback.resolveAgentId(parent.evidenceHash);
|
|
982
|
+
}
|
|
983
|
+
catch (err) {
|
|
984
|
+
console.warn(`[harness-engine] ${task.requestId}: reputation feedback resolver threw (non-fatal): ${err instanceof Error ? err.message : err}`);
|
|
985
|
+
return;
|
|
986
|
+
}
|
|
987
|
+
if (!resolved) {
|
|
988
|
+
console.log(`[harness-engine] ${task.requestId}: reputation feedback skipped — no agentId resolved for harness manifestHash=${parent.evidenceHash} (subgraph not indexed yet, or no envelope published)`);
|
|
989
|
+
return;
|
|
990
|
+
}
|
|
991
|
+
// CID resolution priority: subgraph row's `manifestCid` (cheapest, the
|
|
992
|
+
// operator already published an envelope under it), else the inlined
|
|
993
|
+
// CID hint when present, else fall back to the bare hash. The subgraph
|
|
994
|
+
// parses `manifest:<cid>` to a `manifestRef` regardless.
|
|
995
|
+
const manifestCid = resolved.manifestCid ?? parent.manifestCid ?? '';
|
|
996
|
+
// The SolverType is the same value used by the restoration —
|
|
997
|
+
// `task.solverType` is "portfolio.v0" both for the restoration and its
|
|
998
|
+
// evaluation. Tag1 is indexed on the on-chain event, so cheap to filter.
|
|
999
|
+
const kind = task.solverType ?? undefined;
|
|
1000
|
+
const verdictArg = kind ? { verdict, solverType: kind } : { verdict };
|
|
1001
|
+
let outcome;
|
|
1002
|
+
try {
|
|
1003
|
+
outcome = await submitEvaluatorFeedback({
|
|
1004
|
+
registry: this.reputationFeedback.client,
|
|
1005
|
+
ref: {
|
|
1006
|
+
harnessAgentId: resolved.agentId,
|
|
1007
|
+
harnessManifestCid: manifestCid,
|
|
1008
|
+
harnessEvidenceHash: parent.evidenceHash,
|
|
1009
|
+
},
|
|
1010
|
+
verdict: verdictArg,
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
1013
|
+
catch (err) {
|
|
1014
|
+
// submitEvaluatorFeedback already swallows known reverts, but a
|
|
1015
|
+
// truly unexpected throw still must not propagate past delivery.
|
|
1016
|
+
console.warn(`[harness-engine] ${task.requestId}: reputation feedback unexpected throw (non-fatal): ${err instanceof Error ? err.message : err}`);
|
|
1017
|
+
return;
|
|
1018
|
+
}
|
|
1019
|
+
console.log(`[harness-engine] ${task.requestId}: reputation feedback ${outcome.kind} verdict=${verdict} harnessAgentId=${resolved.agentId.toString()}`);
|
|
1020
|
+
}
|
|
1021
|
+
/**
|
|
1022
|
+
* Extract the harness's `evidenceHash` (and best-effort `manifestCid`)
|
|
1023
|
+
* from the persisted evaluation task.
|
|
1024
|
+
*
|
|
1025
|
+
* The evaluator's `task.context.restorationResult` holds the harness's
|
|
1026
|
+
* full signed manifest JSON inlined as a string (per
|
|
1027
|
+
* `MechAdapter.tryCreateEvaluationJob`). We parse it and pull the
|
|
1028
|
+
* `signature.hash`, which is exactly the on-chain `evidenceHash`.
|
|
1029
|
+
*
|
|
1030
|
+
* The CID is not always inlined — the manifest carries its own
|
|
1031
|
+
* `task.cid` field (the *original task* CID), not its self-CID. We
|
|
1032
|
+
* therefore return `manifestCid: null` here and rely on the subgraph
|
|
1033
|
+
* resolver to surface the published manifest CID. Returns `null` when
|
|
1034
|
+
* the inlined payload is missing or malformed.
|
|
1035
|
+
*/
|
|
1036
|
+
_extractHarnessManifestRef(task) {
|
|
1037
|
+
const ds = task.task;
|
|
1038
|
+
const inlined = ds?.context?.['restorationResult'];
|
|
1039
|
+
if (typeof inlined !== 'string' || inlined.length === 0) {
|
|
1040
|
+
return null;
|
|
1041
|
+
}
|
|
1042
|
+
let parsed;
|
|
1043
|
+
try {
|
|
1044
|
+
parsed = JSON.parse(inlined);
|
|
1045
|
+
}
|
|
1046
|
+
catch {
|
|
1047
|
+
return null;
|
|
1048
|
+
}
|
|
1049
|
+
if (typeof parsed !== 'object' || parsed === null) {
|
|
1050
|
+
return null;
|
|
1051
|
+
}
|
|
1052
|
+
const sig = parsed['signature'];
|
|
1053
|
+
if (typeof sig !== 'object' || sig === null) {
|
|
1054
|
+
return null;
|
|
1055
|
+
}
|
|
1056
|
+
const hashRaw = sig['hash'];
|
|
1057
|
+
if (typeof hashRaw !== 'string' || !/^0x[0-9a-fA-F]{64}$/.test(hashRaw)) {
|
|
1058
|
+
return null;
|
|
1059
|
+
}
|
|
1060
|
+
return {
|
|
1061
|
+
evidenceHash: hashRaw,
|
|
1062
|
+
manifestCid: null,
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
1065
|
+
// ── Internal helpers ────────────────────────────────────────────────────────
|
|
1066
|
+
/**
|
|
1067
|
+
* Returns the next state if the current state can be advanced purely from
|
|
1068
|
+
* persisted data (no external work needed), or null if external work is required.
|
|
1069
|
+
*
|
|
1070
|
+
* Used for crash recovery and for collapsing transitions in process()
|
|
1071
|
+
* when a previous run already produced the data.
|
|
1072
|
+
*/
|
|
1073
|
+
dataDrivenAdvance(task) {
|
|
1074
|
+
switch (task.state) {
|
|
1075
|
+
case TaskRunState.WAITING:
|
|
1076
|
+
return Date.now() >= task.windowStartTs ? TaskRunState.PRE_SNAPSHOT : null;
|
|
1077
|
+
case TaskRunState.PRE_SNAPSHOT:
|
|
1078
|
+
return task.preSnapshotPayload != null ? TaskRunState.RUNNING : null;
|
|
1079
|
+
case TaskRunState.POST_SNAPSHOT:
|
|
1080
|
+
return task.postSnapshotPayload != null ? TaskRunState.PACKAGING : null;
|
|
1081
|
+
default:
|
|
1082
|
+
return null;
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
/**
|
|
1086
|
+
* Wraps a transition method call with error handling: if the transition
|
|
1087
|
+
* throws, the task is marked FAILED with the error message.
|
|
1088
|
+
*/
|
|
1089
|
+
async _runTransition(task, fn) {
|
|
1090
|
+
const oldState = task.state;
|
|
1091
|
+
try {
|
|
1092
|
+
await fn();
|
|
1093
|
+
const updated = this.persistence.getByRequestId(task.requestId);
|
|
1094
|
+
if (updated && updated.state !== oldState) {
|
|
1095
|
+
console.log(`[harness-engine] ${task.requestId} ${oldState} → ${updated.state}`);
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
catch (err) {
|
|
1099
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
1100
|
+
this.persistence.markFailed(task.requestId, reason);
|
|
1101
|
+
throw err;
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
/**
|
|
1105
|
+
* Recovery handler for a single in-flight task.
|
|
1106
|
+
* Dispatches by state per §6.5.
|
|
1107
|
+
*/
|
|
1108
|
+
async _recoverOne(task) {
|
|
1109
|
+
try {
|
|
1110
|
+
await this._recoverDispatch(task);
|
|
1111
|
+
}
|
|
1112
|
+
catch (err) {
|
|
1113
|
+
// If recovery itself throws (e.g. NotImplementedError stub), mark failed.
|
|
1114
|
+
// NotImplementedError is expected during development; don't swallow it in prod.
|
|
1115
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
1116
|
+
// Only mark failed if the task is still in the same non-terminal state
|
|
1117
|
+
// (another concurrent recovery pass might have already advanced it).
|
|
1118
|
+
const current = this.persistence.getByRequestId(task.requestId);
|
|
1119
|
+
if (current && current.state === task.state) {
|
|
1120
|
+
this.persistence.markFailed(task.requestId, `recovery: ${reason}`);
|
|
1121
|
+
console.error(`[harness-engine] resume failed for ${task.requestId}: ${reason}`);
|
|
1122
|
+
}
|
|
1123
|
+
throw err;
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
/**
|
|
1127
|
+
* Per-state recovery dispatch per §6.5.
|
|
1128
|
+
*/
|
|
1129
|
+
async _recoverDispatch(task) {
|
|
1130
|
+
switch (task.state) {
|
|
1131
|
+
case TaskRunState.DISCOVERED:
|
|
1132
|
+
// Ready to claim — delegate to claim flow (subsequent task).
|
|
1133
|
+
// Stub: leaves state unchanged; logs task is ready.
|
|
1134
|
+
await this.claim(task);
|
|
1135
|
+
break;
|
|
1136
|
+
case TaskRunState.CLAIMED:
|
|
1137
|
+
// Advance to WAITING — no side effect needed.
|
|
1138
|
+
this.persistence.transition(task.requestId, TaskRunState.WAITING);
|
|
1139
|
+
await this._recoverDispatch(this.persistence.getOrThrow(task.requestId));
|
|
1140
|
+
break;
|
|
1141
|
+
case TaskRunState.WAITING: {
|
|
1142
|
+
const advance = this.dataDrivenAdvance(task);
|
|
1143
|
+
if (advance !== null) {
|
|
1144
|
+
// Window has started — advance immediately.
|
|
1145
|
+
this.persistence.transition(task.requestId, advance);
|
|
1146
|
+
await this._recoverDispatch(this.persistence.getOrThrow(task.requestId));
|
|
1147
|
+
}
|
|
1148
|
+
// else: schedule a timer for startTs — caller handles scheduling.
|
|
1149
|
+
break;
|
|
1150
|
+
}
|
|
1151
|
+
case TaskRunState.PRE_SNAPSHOT: {
|
|
1152
|
+
const advance = this.dataDrivenAdvance(task);
|
|
1153
|
+
if (advance !== null) {
|
|
1154
|
+
// Snapshot already in DB — advance to RUNNING.
|
|
1155
|
+
this.persistence.transition(task.requestId, advance);
|
|
1156
|
+
await this._recoverDispatch(this.persistence.getOrThrow(task.requestId));
|
|
1157
|
+
}
|
|
1158
|
+
else {
|
|
1159
|
+
// Need to (re-)fetch snapshot.
|
|
1160
|
+
await this.takePreSnapshot(task);
|
|
1161
|
+
// takePreSnapshot transitions PRE_SNAPSHOT → RUNNING. Re-dispatch
|
|
1162
|
+
// against the post-transition state so runImpl actually fires for
|
|
1163
|
+
// tasks that were persisted at CLAIMED/WAITING/PRE_SNAPSHOT
|
|
1164
|
+
// before a restart (otherwise recovery stops at RUNNING-but-not-run).
|
|
1165
|
+
const after = this.persistence.getByRequestId(task.requestId);
|
|
1166
|
+
if (after && after.state !== task.state && after.state !== TaskRunState.FAILED) {
|
|
1167
|
+
await this._recoverDispatch(after);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
break;
|
|
1171
|
+
}
|
|
1172
|
+
case TaskRunState.RUNNING:
|
|
1173
|
+
// Re-spawn impl with workingDir + implStateDir intact.
|
|
1174
|
+
await this.runImpl(task);
|
|
1175
|
+
break;
|
|
1176
|
+
case TaskRunState.POST_SNAPSHOT: {
|
|
1177
|
+
const advance = this.dataDrivenAdvance(task);
|
|
1178
|
+
if (advance !== null) {
|
|
1179
|
+
// Snapshot already in DB — advance to PACKAGING.
|
|
1180
|
+
this.persistence.transition(task.requestId, advance);
|
|
1181
|
+
await this._recoverDispatch(this.persistence.getOrThrow(task.requestId));
|
|
1182
|
+
}
|
|
1183
|
+
else {
|
|
1184
|
+
await this.takePostSnapshot(task);
|
|
1185
|
+
}
|
|
1186
|
+
break;
|
|
1187
|
+
}
|
|
1188
|
+
case TaskRunState.PACKAGING:
|
|
1189
|
+
// Re-walk workingDir + Solution; re-upload missing CIDs.
|
|
1190
|
+
await this.pack(task);
|
|
1191
|
+
break;
|
|
1192
|
+
case TaskRunState.DELIVERING:
|
|
1193
|
+
// Chain query — if already delivered → COMPLETE; else retry.
|
|
1194
|
+
await this.deliver(task);
|
|
1195
|
+
break;
|
|
1196
|
+
case TaskRunState.COMPLETE:
|
|
1197
|
+
case TaskRunState.FAILED:
|
|
1198
|
+
// Terminal — nothing to recover.
|
|
1199
|
+
break;
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
//# sourceMappingURL=engine.js.map
|