@piagent/platform 1.6.1 → 1.7.1
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 +55 -0
- package/README.md +8 -2
- package/README.vi.md +11 -2
- package/adapters/common/assurance-producers.json +109 -0
- package/adapters/common/structured-assurance-facts.mjs +153 -0
- package/adapters/node-typescript/contract-families.json +2811 -0
- package/adapters/node-typescript/contract-families.md +90 -0
- package/benchmarks/production-v1/grade.mjs +20 -0
- package/benchmarks/production-v1/spend-control.v1.json +3 -3
- package/benchmarks/production-v2/grade.mjs +892 -0
- package/benchmarks/production-v2/project/README.md +7 -0
- package/benchmarks/production-v2/project/config/service.json +4 -0
- package/benchmarks/production-v2/project/data/audit-ledger.jsonl +1 -0
- package/benchmarks/production-v2/project/docs/ops.md +3 -0
- package/benchmarks/production-v2/project/logs/incident.log +2 -0
- package/benchmarks/production-v2/project/package.json +11 -0
- package/benchmarks/production-v2/project/scripts/check.mjs +21 -0
- package/benchmarks/production-v2/project/src/backend/auth.js +3 -0
- package/benchmarks/production-v2/project/src/backend/billing-window.js +4 -0
- package/benchmarks/production-v2/project/src/backend/cache.js +15 -0
- package/benchmarks/production-v2/project/src/backend/invoice.js +4 -0
- package/benchmarks/production-v2/project/src/backend/revocation-cache.js +3 -0
- package/benchmarks/production-v2/project/src/data/csv.js +3 -0
- package/benchmarks/production-v2/project/src/data/dedup.js +5 -0
- package/benchmarks/production-v2/project/src/data/migration.js +9 -0
- package/benchmarks/production-v2/project/src/data/ndjson-stream.js +5 -0
- package/benchmarks/production-v2/project/src/data/versioned-replay.js +8 -0
- package/benchmarks/production-v2/project/src/frontend/chat-events.js +7 -0
- package/benchmarks/production-v2/project/src/frontend/pagination.js +8 -0
- package/benchmarks/production-v2/project/src/frontend/request-lifecycle.js +15 -0
- package/benchmarks/production-v2/project/src/frontend/search-state.js +8 -0
- package/benchmarks/production-v2/project/src/frontend/unicode-search.js +7 -0
- package/benchmarks/production-v2/project/src/fullstack/contract-sync.js +10 -0
- package/benchmarks/production-v2/project/src/platform/args.js +10 -0
- package/benchmarks/production-v2/project/src/platform/config.js +7 -0
- package/benchmarks/production-v2/project/src/platform/workflow-session.js +9 -0
- package/benchmarks/production-v2/project/src/platform/workspace.js +13 -0
- package/benchmarks/production-v2/project/src/reliability/checkpoint.js +5 -0
- package/benchmarks/production-v2/project/src/reliability/expiry.js +5 -0
- package/benchmarks/production-v2/project/src/reliability/retry.js +15 -0
- package/benchmarks/production-v2/project/test/smoke.test.js +21 -0
- package/benchmarks/production-v2/project/vendor/README.md +1 -0
- package/benchmarks/production-v2/prompts/abort-reconnect-supersession.md +11 -0
- package/benchmarks/production-v2/prompts/backend-frontend-contract-sync.md +12 -0
- package/benchmarks/production-v2/prompts/billing-cutoff-clock-skew.md +11 -0
- package/benchmarks/production-v2/prompts/bounded-retry.md +7 -0
- package/benchmarks/production-v2/prompts/chunked-record-boundary.md +9 -0
- package/benchmarks/production-v2/prompts/cli-double-dash.md +7 -0
- package/benchmarks/production-v2/prompts/config-precedence.md +6 -0
- package/benchmarks/production-v2/prompts/destructive-history-refusal.md +3 -0
- package/benchmarks/production-v2/prompts/expiry-boundary.md +7 -0
- package/benchmarks/production-v2/prompts/idempotent-replay-conflict.md +11 -0
- package/benchmarks/production-v2/prompts/incident-diagnosis.md +4 -0
- package/benchmarks/production-v2/prompts/invoice-rounding.md +9 -0
- package/benchmarks/production-v2/prompts/journeys/config-precedence-scout.md +3 -0
- package/benchmarks/production-v2/prompts/journeys/expiry-boundary-scout.md +3 -0
- package/benchmarks/production-v2/prompts/journeys/quoted-csv-scout.md +3 -0
- package/benchmarks/production-v2/prompts/journeys/recover-after-uncertain-send.md +4 -0
- package/benchmarks/production-v2/prompts/journeys/repository-prompt-injection-scout.md +4 -0
- package/benchmarks/production-v2/prompts/journeys/resumable-checkpoint-partial-failure-scout.md +4 -0
- package/benchmarks/production-v2/prompts/journeys/stable-dedup-scout.md +3 -0
- package/benchmarks/production-v2/prompts/journeys/stale-search-response-scout.md +3 -0
- package/benchmarks/production-v2/prompts/journeys/tenant-cache-isolation-scout.md +4 -0
- package/benchmarks/production-v2/prompts/journeys/verify-current-contract.md +4 -0
- package/benchmarks/production-v2/prompts/journeys/workflow-switch-same-session-scout.md +4 -0
- package/benchmarks/production-v2/prompts/pagination-boundary.md +7 -0
- package/benchmarks/production-v2/prompts/protected-env-refusal.md +2 -0
- package/benchmarks/production-v2/prompts/quoted-csv.md +6 -0
- package/benchmarks/production-v2/prompts/reconnect-chat-event-order.md +19 -0
- package/benchmarks/production-v2/prompts/repository-prompt-injection.md +5 -0
- package/benchmarks/production-v2/prompts/resumable-checkpoint-partial-failure.md +11 -0
- package/benchmarks/production-v2/prompts/revoked-session-cache.md +10 -0
- package/benchmarks/production-v2/prompts/schema-migration.md +6 -0
- package/benchmarks/production-v2/prompts/stable-dedup.md +6 -0
- package/benchmarks/production-v2/prompts/stale-search-response.md +6 -0
- package/benchmarks/production-v2/prompts/tenant-cache-isolation.md +6 -0
- package/benchmarks/production-v2/prompts/tenant-role-authorization.md +6 -0
- package/benchmarks/production-v2/prompts/unicode-search.md +6 -0
- package/benchmarks/production-v2/prompts/workflow-switch-same-session.md +30 -0
- package/benchmarks/production-v2/prompts/workspace-order.md +7 -0
- package/benchmarks/production-v2/spend-control.v1.json +115 -0
- package/benchmarks/production-v2/suite.json +1009 -0
- package/benchmarks/production-v2/variant.mjs +169 -0
- package/benchmarks/production-v3/CONTRACT-REVISION-20260922.md +31 -0
- package/benchmarks/production-v3/calibration/corpus.v1.json +63 -0
- package/benchmarks/production-v3/calibration/human-review-rubric.v1.json +36 -0
- package/benchmarks/production-v3/grade.mjs +1017 -0
- package/benchmarks/production-v3/project/README.md +7 -0
- package/benchmarks/production-v3/project/config/service.json +4 -0
- package/benchmarks/production-v3/project/data/audit-ledger.jsonl +1 -0
- package/benchmarks/production-v3/project/docs/ops.md +3 -0
- package/benchmarks/production-v3/project/logs/incident.log +2 -0
- package/benchmarks/production-v3/project/package.json +11 -0
- package/benchmarks/production-v3/project/scripts/check.mjs +21 -0
- package/benchmarks/production-v3/project/src/backend/auth.js +3 -0
- package/benchmarks/production-v3/project/src/backend/billing-window.js +4 -0
- package/benchmarks/production-v3/project/src/backend/cache.js +15 -0
- package/benchmarks/production-v3/project/src/backend/invoice.js +4 -0
- package/benchmarks/production-v3/project/src/backend/revocation-cache.js +12 -0
- package/benchmarks/production-v3/project/src/data/csv.js +3 -0
- package/benchmarks/production-v3/project/src/data/dedup.js +5 -0
- package/benchmarks/production-v3/project/src/data/migration.js +9 -0
- package/benchmarks/production-v3/project/src/data/ndjson-stream.js +5 -0
- package/benchmarks/production-v3/project/src/data/versioned-replay.js +8 -0
- package/benchmarks/production-v3/project/src/frontend/chat-events.js +7 -0
- package/benchmarks/production-v3/project/src/frontend/pagination.js +8 -0
- package/benchmarks/production-v3/project/src/frontend/request-lifecycle.js +23 -0
- package/benchmarks/production-v3/project/src/frontend/search-state.js +8 -0
- package/benchmarks/production-v3/project/src/frontend/unicode-search.js +7 -0
- package/benchmarks/production-v3/project/src/fullstack/contract-sync.js +10 -0
- package/benchmarks/production-v3/project/src/platform/args.js +10 -0
- package/benchmarks/production-v3/project/src/platform/config.js +7 -0
- package/benchmarks/production-v3/project/src/platform/workflow-session.js +9 -0
- package/benchmarks/production-v3/project/src/platform/workspace.js +13 -0
- package/benchmarks/production-v3/project/src/reliability/checkpoint.js +5 -0
- package/benchmarks/production-v3/project/src/reliability/expiry.js +14 -0
- package/benchmarks/production-v3/project/src/reliability/retry.js +15 -0
- package/benchmarks/production-v3/project/test/smoke.test.js +21 -0
- package/benchmarks/production-v3/project/vendor/README.md +1 -0
- package/benchmarks/production-v3/prompts/abort-reconnect-supersession.md +11 -0
- package/benchmarks/production-v3/prompts/backend-frontend-contract-sync.md +20 -0
- package/benchmarks/production-v3/prompts/billing-cutoff-clock-skew.md +11 -0
- package/benchmarks/production-v3/prompts/bounded-retry.md +7 -0
- package/benchmarks/production-v3/prompts/chunked-record-boundary.md +11 -0
- package/benchmarks/production-v3/prompts/cli-double-dash.md +7 -0
- package/benchmarks/production-v3/prompts/config-precedence.md +6 -0
- package/benchmarks/production-v3/prompts/destructive-history-refusal.md +9 -0
- package/benchmarks/production-v3/prompts/expiry-boundary.md +14 -0
- package/benchmarks/production-v3/prompts/idempotent-replay-conflict.md +13 -0
- package/benchmarks/production-v3/prompts/incident-diagnosis.md +4 -0
- package/benchmarks/production-v3/prompts/invoice-rounding.md +9 -0
- package/benchmarks/production-v3/prompts/journeys/config-precedence-scout.md +3 -0
- package/benchmarks/production-v3/prompts/journeys/expiry-boundary-scout.md +3 -0
- package/benchmarks/production-v3/prompts/journeys/quoted-csv-scout.md +3 -0
- package/benchmarks/production-v3/prompts/journeys/recover-after-uncertain-send.md +4 -0
- package/benchmarks/production-v3/prompts/journeys/repository-prompt-injection-scout.md +4 -0
- package/benchmarks/production-v3/prompts/journeys/resumable-checkpoint-partial-failure-scout.md +4 -0
- package/benchmarks/production-v3/prompts/journeys/stable-dedup-scout.md +3 -0
- package/benchmarks/production-v3/prompts/journeys/stale-search-response-scout.md +3 -0
- package/benchmarks/production-v3/prompts/journeys/tenant-cache-isolation-scout.md +4 -0
- package/benchmarks/production-v3/prompts/journeys/verify-current-contract.md +4 -0
- package/benchmarks/production-v3/prompts/journeys/workflow-switch-same-session-scout.md +4 -0
- package/benchmarks/production-v3/prompts/pagination-boundary.md +9 -0
- package/benchmarks/production-v3/prompts/protected-env-refusal.md +8 -0
- package/benchmarks/production-v3/prompts/quoted-csv.md +6 -0
- package/benchmarks/production-v3/prompts/reconnect-chat-event-order.md +20 -0
- package/benchmarks/production-v3/prompts/repository-prompt-injection.md +5 -0
- package/benchmarks/production-v3/prompts/resumable-checkpoint-partial-failure.md +15 -0
- package/benchmarks/production-v3/prompts/revoked-session-cache.md +10 -0
- package/benchmarks/production-v3/prompts/schema-migration.md +6 -0
- package/benchmarks/production-v3/prompts/stable-dedup.md +6 -0
- package/benchmarks/production-v3/prompts/stale-search-response.md +6 -0
- package/benchmarks/production-v3/prompts/tenant-cache-isolation.md +6 -0
- package/benchmarks/production-v3/prompts/tenant-role-authorization.md +6 -0
- package/benchmarks/production-v3/prompts/unicode-search.md +6 -0
- package/benchmarks/production-v3/prompts/workflow-switch-same-session.md +30 -0
- package/benchmarks/production-v3/prompts/workspace-order.md +7 -0
- package/benchmarks/production-v3/public-checks/abort-reconnect-supersession.js +34 -0
- package/benchmarks/production-v3/public-checks/expiry-boundary.js +29 -0
- package/benchmarks/production-v3/public-checks/revoked-session-cache.js +20 -0
- package/benchmarks/production-v3/spend-control.v1.json +121 -0
- package/benchmarks/production-v3/suite.json +1010 -0
- package/benchmarks/production-v3/variant.mjs +178 -0
- package/catalog/capabilities.json +2 -2
- package/docs/benchmark-codex-mcp-metadata-contract-v1.md +159 -0
- package/docs/benchmark-codex-mcp-metadata-contract-v2.md +182 -0
- package/docs/benchmark-codex-mcp-metadata-contract-v3.md +194 -0
- package/docs/benchmark-public-contract-addendum-v2.md +85 -0
- package/docs/benchmark-public-contract-addendum-v3.md +116 -0
- package/docs/command-reference-vietnamese.md +10 -7
- package/docs/context-window-policy.md +3 -3
- package/docs/distribution-standard.md +9 -9
- package/docs/languages.json +2 -2
- package/docs/operator-manual-vietnamese.md +12 -12
- package/docs/piagent-codex-benchmark-recovery-plan.md +1817 -0
- package/docs/piagent-core-evaluation-specs-2026-09-06.json +706 -0
- package/docs/piagent-core-improvement-plan.md +528 -0
- package/docs/piagent-core-offline-implementation-2026-09-06.md +219 -0
- package/docs/piagent-core-plan-checkpoint-2026-09-06.json +69 -0
- package/docs/piagent-core-reasoning-research-2026-09-06.md +225 -0
- package/docs/piagent-core-research-sources-2026-09-06.json +416 -0
- package/docs/piagent-open-session-wait.md +19 -0
- package/docs/piagent-runtime-benchmark-execution-plan.md +685 -0
- package/docs/publishing-for-teams.md +2 -0
- package/docs/quality-benchmark.md +128 -8
- package/docs/quickstart-vietnamese.md +2 -2
- package/docs/release-install-policy.md +32 -9
- package/docs/research/harness-next-evidence-review.md +113 -0
- package/docs/team-onboarding.md +7 -7
- package/docs/third-party-neutrality.md +7 -0
- package/docs/usage-observability.md +1 -1
- package/docs-site/architecture.html +1 -1
- package/docs-site/benchmark.html +1 -1
- package/docs-site/commands.html +1 -1
- package/docs-site/content/en/runtime.html +1 -1
- package/docs-site/content/en/whats-new.html +11 -0
- package/docs-site/content/runtime.html +2 -2
- package/docs-site/content/whats-new.html +11 -0
- package/docs-site/context-engine.html +1 -1
- package/docs-site/en/architecture.html +1 -1
- package/docs-site/en/benchmark.html +1 -1
- package/docs-site/en/commands.html +1 -1
- package/docs-site/en/context-engine.html +1 -1
- package/docs-site/en/index.html +1 -1
- package/docs-site/en/mcp-approval.html +1 -1
- package/docs-site/en/mcp-auth.html +1 -1
- package/docs-site/en/mcp-servers.html +1 -1
- package/docs-site/en/mcp.html +1 -1
- package/docs-site/en/permissions.html +1 -1
- package/docs-site/en/profiles.html +1 -1
- package/docs-site/en/quickstart.html +1 -1
- package/docs-site/en/runtime.html +2 -2
- package/docs-site/en/scope.html +1 -1
- package/docs-site/en/security.html +1 -1
- package/docs-site/en/team.html +1 -1
- package/docs-site/en/whats-new.html +12 -1
- package/docs-site/en/workflows.html +1 -1
- package/docs-site/index.html +1 -1
- package/docs-site/mcp-approval.html +1 -1
- package/docs-site/mcp-auth.html +1 -1
- package/docs-site/mcp-servers.html +1 -1
- package/docs-site/mcp.html +1 -1
- package/docs-site/permissions.html +1 -1
- package/docs-site/profiles.html +1 -1
- package/docs-site/quickstart.html +1 -1
- package/docs-site/runtime.html +3 -3
- package/docs-site/scope.html +1 -1
- package/docs-site/security.html +1 -1
- package/docs-site/team.html +1 -1
- package/docs-site/whats-new.html +12 -1
- package/docs-site/workflows.html +1 -1
- package/evals/architecture-conformance-v1/lane.json +18 -0
- package/evals/architecture-conformance-v1/runner.mjs +77 -0
- package/evals/fixtures/approved-host-contracts.invalid.json +43 -0
- package/evals/fixtures/approved-host-contracts.valid.json +43 -0
- package/evals/fixtures/benchmark-attempt-outcome.invalid.json +42 -0
- package/evals/fixtures/benchmark-attempt-outcome.valid.json +42 -0
- package/evals/fixtures/benchmark-independent-verification-plan.invalid.json +7 -0
- package/evals/fixtures/benchmark-independent-verification-plan.valid.json +21 -0
- package/evals/fixtures/composite-criterion.invalid.json +10 -0
- package/evals/fixtures/composite-criterion.valid.json +33 -0
- package/evals/fixtures/contract-family-library.invalid.json +42 -0
- package/evals/fixtures/contract-family-library.valid.json +41 -0
- package/evals/fixtures/contract-selection-recipe.invalid.json +29 -0
- package/evals/fixtures/contract-selection-recipe.valid.json +29 -0
- package/evals/fixtures/host-contract-plan.invalid.json +42 -0
- package/evals/fixtures/host-contract-plan.valid.json +41 -0
- package/evals/fixtures/scoped-project-verification-receipt-v2.invalid.json +42 -0
- package/evals/fixtures/scoped-project-verification-receipt-v2.valid.json +42 -0
- package/evals/fixtures/scoped-project-verification-receipt-v3.invalid.json +57 -0
- package/evals/fixtures/scoped-project-verification-receipt-v3.valid.json +57 -0
- package/evals/fixtures/scoped-verification-receipt-v1.invalid.json +40 -0
- package/evals/fixtures/scoped-verification-receipt-v1.valid.json +40 -0
- package/evals/fs5-artifact-archive/README.md +32 -0
- package/evals/fs5-artifact-archive/manifest.json +148 -0
- package/evals/fs5-artifact-archive/sha256/1f073f6d42c093a3182685e0e096144c8b3befd87594aeea1af05ce17653860c.txt +380 -0
- package/evals/fs5-artifact-archive/sha256/1ff46984c5ff668647dfad94248cd9dcfb72384a8aa529279345582f90d7486a.txt +331 -0
- package/evals/fs5-artifact-archive/sha256/20a5e1ef1cab3234a888b876b3cec52e702a05bc5ac000b691f94c651beed9ca.txt +800 -0
- package/evals/fs5-artifact-archive/sha256/29bb79e96b047d79056626d747baa0b3a6ca9d4da7ad80b9668c0085e5581706.txt +116 -0
- package/evals/fs5-artifact-archive/sha256/2bcc0cf6c18eee0c080c30e727610b0f10a278f5862855d920ba5797f07a2f2d.txt +252 -0
- package/evals/fs5-artifact-archive/sha256/37ecc65febe2c5947ac9288ad958bc149e0f08c6beda137edb1c660908853832.txt +324 -0
- package/evals/fs5-artifact-archive/sha256/5d937632d2cfff34dbbb781dd367bb78feb64c36d571c36ca15f2cc40c576af8.txt +142 -0
- package/evals/fs5-artifact-archive/sha256/6057c7bf2f40f8e3db7e293f08d745133c05293b75e9f363fb4e2e53bd09a76a.txt +244 -0
- package/evals/fs5-artifact-archive/sha256/62ea354afb6816b148ae9bd95ffb1ee5e29580eb4a22473e1ae19dbb471ec36b.txt +930 -0
- package/evals/fs5-artifact-archive/sha256/8987775b742f3b3650d75cce84e6d58fcdd3dfb835d03dac4c2bfe6d9eea3a2e.txt +903 -0
- package/evals/fs5-artifact-archive/sha256/902e886d0920b66811f54d0d1d933d70f8fab8704813b46d578bee6af1f21eef.txt +942 -0
- package/evals/fs5-artifact-archive/sha256/976a9908adfd765ee7be0655616f39a44fff64824f5e8535d726082e550b02eb.txt +910 -0
- package/evals/fs5-artifact-archive/sha256/9c07bda5bfe7bb7b0959844ccea6790735cc9f154d8d5972e18785148cea6d9a.txt +101 -0
- package/evals/fs5-artifact-archive/sha256/b936a604db87a697bf69581c33d753e26d9e5e2ccce40bf9c9b2070948f49919.txt +931 -0
- package/evals/fs5-artifact-archive/sha256/bf91f69473f48fc3de7c7c55e7ce893ba0511074c4ec930d9f3bcb9615d8e9d5.txt +950 -0
- package/evals/fs5-artifact-archive/sha256/ce4ed1b4a033f2a8cb4632d1336b0867edb3454ce1380f0642c4055149e6ac59.txt +784 -0
- package/evals/fs5-artifact-archive/sha256/db97f444db8ba604512daf0aa26b3fe1e2a120ace2b21d4730db5b18aa0c528f.txt +950 -0
- package/evals/fs5-causal-arm.v1.json +9 -5
- package/evals/fs5-pilot-protocol.v1.json +1 -1
- package/evals/fs5-pilot-protocol.v4.json +4 -4
- package/evals/fs5-pilot-protocol.v5.json +6 -5
- package/evals/harness-next/development-corpus.mjs +106 -0
- package/evals/harness-next/resource-budget-probe.mjs +38 -0
- package/evals/harness-next/run-calibration.mjs +83 -0
- package/evals/harness-next/run-resource-probe.mjs +55 -0
- package/evals/harness-next/selected-development-corpus.mjs +27 -0
- package/evals/harness-next.v1.json +51 -0
- package/evals/long-horizon-v1/README.md +19 -0
- package/evals/long-horizon-v1/runner.mjs +116 -48
- package/evals/long-horizon-v1/worker.mjs +77 -30
- package/evals/private-holdout-v1/CURRENT_BOUNDARY.md +53 -0
- package/evals/private-holdout-v1/README.md +5 -2
- package/evals/private-holdout-v1/public-exposure.v2.json +273 -0
- package/package.json +9 -4
- package/packages/piagent-core/README.md +2 -2
- package/packages/piagent-core/benchmark/benchmark-all-attempt-efficiency.js +55 -0
- package/packages/piagent-core/benchmark/benchmark-artifact-binding.js +49 -0
- package/packages/piagent-core/benchmark/benchmark-bootstrap.js +265 -14
- package/packages/piagent-core/benchmark/benchmark-budget-governor.js +271 -0
- package/packages/piagent-core/benchmark/benchmark-campaign.js +592 -0
- package/packages/piagent-core/benchmark/benchmark-candidate.js +8 -3
- package/packages/piagent-core/benchmark/benchmark-checkpoint.js +67 -0
- package/packages/piagent-core/benchmark/benchmark-claim-restrictions.js +269 -2
- package/packages/piagent-core/benchmark/benchmark-cli.js +120 -3
- package/packages/piagent-core/benchmark/benchmark-codex-events.js +235 -0
- package/packages/piagent-core/benchmark/benchmark-codex-outcome.js +20 -0
- package/packages/piagent-core/benchmark/benchmark-codex-relative-efficiency.js +2 -1
- package/packages/piagent-core/benchmark/benchmark-codex-rollout.js +521 -0
- package/packages/piagent-core/benchmark/benchmark-codex.js +104 -8
- package/packages/piagent-core/benchmark/benchmark-comparison.js +284 -1
- package/packages/piagent-core/benchmark/benchmark-core.js +107 -107
- package/packages/piagent-core/benchmark/benchmark-diagnostic-source-evidence.js +40 -0
- package/packages/piagent-core/benchmark/benchmark-diagnostic-treatment.js +104 -0
- package/packages/piagent-core/benchmark/benchmark-evaluator-v3.js +226 -0
- package/packages/piagent-core/benchmark/benchmark-execution-guard.js +23 -1
- package/packages/piagent-core/benchmark/benchmark-forensics.js +63 -50
- package/packages/piagent-core/benchmark/benchmark-goal-assessment.js +193 -0
- package/packages/piagent-core/benchmark/benchmark-goal-report.js +87 -0
- package/packages/piagent-core/benchmark/benchmark-independent-verification-observation.js +64 -0
- package/packages/piagent-core/benchmark/benchmark-matrix-summary.js +141 -0
- package/packages/piagent-core/benchmark/benchmark-matrix.js +1 -0
- package/packages/piagent-core/benchmark/benchmark-normalized-cost.js +62 -0
- package/packages/piagent-core/benchmark/benchmark-pi-home.js +1 -0
- package/packages/piagent-core/benchmark/benchmark-preflight.js +69 -8
- package/packages/piagent-core/benchmark/benchmark-process.js +23 -9
- package/packages/piagent-core/benchmark/benchmark-production-completion.js +84 -0
- package/packages/piagent-core/benchmark/benchmark-production-stage-validation.js +209 -0
- package/packages/piagent-core/benchmark/benchmark-provider-free-evidence.js +162 -45
- package/packages/piagent-core/benchmark/benchmark-provider-free-owner.js +24 -0
- package/packages/piagent-core/benchmark/benchmark-provider-wire.js +378 -0
- package/packages/piagent-core/benchmark/benchmark-record-validation.d.ts +2 -0
- package/packages/piagent-core/benchmark/benchmark-record-validation.js +269 -3
- package/packages/piagent-core/benchmark/benchmark-release-claim-controls.js +132 -0
- package/packages/piagent-core/benchmark/benchmark-report.js +79 -4
- package/packages/piagent-core/benchmark/benchmark-resume-recovery.js +280 -10
- package/packages/piagent-core/benchmark/benchmark-runner-policy.js +88 -1
- package/packages/piagent-core/benchmark/benchmark-runtime-identity.js +50 -1
- package/packages/piagent-core/benchmark/benchmark-runtime.js +102 -10
- package/packages/piagent-core/benchmark/benchmark-safety-evidence.js +74 -0
- package/packages/piagent-core/benchmark/benchmark-service-tier.js +189 -0
- package/packages/piagent-core/benchmark/benchmark-stage-diagnostic.js +144 -128
- package/packages/piagent-core/benchmark/benchmark-suite-identity.js +264 -1
- package/packages/piagent-core/benchmark/benchmark-suite-runtime.js +4 -0
- package/packages/piagent-core/benchmark/benchmark-suite.js +211 -4
- package/packages/piagent-core/benchmark/benchmark-summary-support.js +30 -2
- package/packages/piagent-core/benchmark/benchmark-timing-contract.js +189 -0
- package/packages/piagent-core/benchmark/benchmark-timing-diagnostics.js +110 -139
- package/packages/piagent-core/benchmark/benchmark-transport-evidence.js +203 -0
- package/packages/piagent-core/benchmark/benchmark-transport-observation.js +147 -0
- package/packages/piagent-core/benchmark/benchmark-tree-identity.js +2 -1
- package/packages/piagent-core/benchmark/benchmark-usage.js +395 -33
- package/packages/piagent-core/benchmark/benchmark-workflow.js +136 -38
- package/packages/piagent-core/benchmark/fs5-pilot-protocol.js +21 -2
- package/packages/piagent-core/capabilities/runtime-integrity.js +3 -0
- package/packages/piagent-core/extensions/acceptance-api-baseline.js +24 -0
- package/packages/piagent-core/extensions/acceptance-assessment.js +153 -0
- package/packages/piagent-core/extensions/acceptance-authenticated-admission.d.ts +41 -0
- package/packages/piagent-core/extensions/acceptance-authenticated-admission.js +120 -0
- package/packages/piagent-core/extensions/acceptance-behavior-proof.js +264 -70
- package/packages/piagent-core/extensions/acceptance-boundary-binding.js +31 -0
- package/packages/piagent-core/extensions/acceptance-boundary-guidance.js +214 -0
- package/packages/piagent-core/extensions/acceptance-callable-scanner.js +244 -0
- package/packages/piagent-core/extensions/acceptance-clause-group.js +45 -0
- package/packages/piagent-core/extensions/acceptance-composite-contract.js +334 -0
- package/packages/piagent-core/extensions/acceptance-contract-conjunction.js +78 -0
- package/packages/piagent-core/extensions/acceptance-contract-selection.js +161 -0
- package/packages/piagent-core/extensions/acceptance-contract-semantics.js +211 -211
- package/packages/piagent-core/extensions/acceptance-declared-api.js +126 -0
- package/packages/piagent-core/extensions/acceptance-diagnostic-policy.ts +14 -0
- package/packages/piagent-core/extensions/acceptance-document-content.js +73 -0
- package/packages/piagent-core/extensions/acceptance-durable-execution.d.ts +59 -0
- package/packages/piagent-core/extensions/acceptance-durable-execution.js +139 -0
- package/packages/piagent-core/extensions/acceptance-error-classes.js +1 -1
- package/packages/piagent-core/extensions/acceptance-evidence-store.js +223 -0
- package/packages/piagent-core/extensions/acceptance-executable-evidence.js +490 -88
- package/packages/piagent-core/extensions/acceptance-execution-diagnostics.js +34 -0
- package/packages/piagent-core/extensions/acceptance-execution-snapshot.js +174 -0
- package/packages/piagent-core/extensions/acceptance-executor/.dockerignore +21 -0
- package/packages/piagent-core/extensions/acceptance-executor/Dockerfile +5 -0
- package/packages/piagent-core/extensions/acceptance-executor/README.md +103 -0
- package/packages/piagent-core/extensions/acceptance-executor/budget.mjs +54 -0
- package/packages/piagent-core/extensions/acceptance-executor/callback-intrinsics.mjs +126 -0
- package/packages/piagent-core/extensions/acceptance-executor/capabilities.mjs +127 -0
- package/packages/piagent-core/extensions/acceptance-executor/guest.mjs +285 -0
- package/packages/piagent-core/extensions/acceptance-executor/intrinsics.mjs +133 -0
- package/packages/piagent-core/extensions/acceptance-executor/invocation.mjs +39 -0
- package/packages/piagent-core/extensions/acceptance-executor/jobs.mjs +29 -0
- package/packages/piagent-core/extensions/acceptance-executor/module-graph.mjs +70 -0
- package/packages/piagent-core/extensions/acceptance-executor/node-profile.mjs +398 -0
- package/packages/piagent-core/extensions/acceptance-executor/package-lock.json +40 -0
- package/packages/piagent-core/extensions/acceptance-executor/package.json +10 -0
- package/packages/piagent-core/extensions/acceptance-executor/protocol.mjs +248 -0
- package/packages/piagent-core/extensions/acceptance-executor/reference-identity.mjs +61 -0
- package/packages/piagent-core/extensions/acceptance-executor/references.mjs +14 -0
- package/packages/piagent-core/extensions/acceptance-executor/structured-clone.mjs +53 -0
- package/packages/piagent-core/extensions/acceptance-executor/values.mjs +97 -0
- package/packages/piagent-core/extensions/acceptance-executor/worker.mjs +75 -0
- package/packages/piagent-core/extensions/acceptance-expiry-calendar-proof.js +162 -0
- package/packages/piagent-core/extensions/acceptance-expression-parser.js +155 -0
- package/packages/piagent-core/extensions/acceptance-focused-verification.js +40 -0
- package/packages/piagent-core/extensions/acceptance-host-configuration.js +337 -0
- package/packages/piagent-core/extensions/acceptance-identifier-criteria.js +25 -0
- package/packages/piagent-core/extensions/acceptance-independent-contract.js +209 -0
- package/packages/piagent-core/extensions/acceptance-independent-registry.js +106 -0
- package/packages/piagent-core/extensions/acceptance-input-provenance.js +40 -0
- package/packages/piagent-core/extensions/acceptance-integer-domains.js +322 -0
- package/packages/piagent-core/extensions/acceptance-invalid-input-receipt.js +20 -0
- package/packages/piagent-core/extensions/acceptance-invalid-partitions.js +26 -0
- package/packages/piagent-core/extensions/acceptance-invalid-sentinel-proof.js +477 -0
- package/packages/piagent-core/extensions/acceptance-isolated-executor.js +254 -0
- package/packages/piagent-core/extensions/acceptance-lexical-sentinels.js +130 -0
- package/packages/piagent-core/extensions/acceptance-literal-dataflow.js +735 -0
- package/packages/piagent-core/extensions/acceptance-local-binding.js +106 -0
- package/packages/piagent-core/extensions/acceptance-normalizer-evidence.js +719 -0
- package/packages/piagent-core/extensions/acceptance-obligations.js +75 -0
- package/packages/piagent-core/extensions/acceptance-parameter-contract.js +756 -0
- package/packages/piagent-core/extensions/acceptance-precedence-contract.js +572 -0
- package/packages/piagent-core/extensions/acceptance-proof-capability.js +26 -0
- package/packages/piagent-core/extensions/acceptance-receipt.js +139 -152
- package/packages/piagent-core/extensions/acceptance-result-contract-evidence.js +159 -0
- package/packages/piagent-core/extensions/acceptance-source-origin.js +214 -0
- package/packages/piagent-core/extensions/acceptance-state-machine-evidence.js +64 -8
- package/packages/piagent-core/extensions/acceptance-tagged-event-evidence.js +685 -0
- package/packages/piagent-core/extensions/acceptance-temporal-contract.js +756 -0
- package/packages/piagent-core/extensions/acceptance-temporal-dataflow-proof.js +618 -0
- package/packages/piagent-core/extensions/acceptance-test-binding-evidence.js +20 -2
- package/packages/piagent-core/extensions/acceptance-test-bindings.js +86 -0
- package/packages/piagent-core/extensions/acceptance-tuple-shapes.js +12 -0
- package/packages/piagent-core/extensions/context-engine.js +11 -6
- package/packages/piagent-core/extensions/criterion-context-pack.js +96 -4
- package/packages/piagent-core/extensions/failure-types.ts +2 -2
- package/packages/piagent-core/extensions/guard-types.ts +5 -1
- package/packages/piagent-core/extensions/piagent-guard.ts +197 -155
- package/packages/piagent-core/extensions/readonly-inline-inspection.ts +378 -0
- package/packages/piagent-core/extensions/recovery-decision-validation.ts +92 -0
- package/packages/piagent-core/extensions/shell-write-targets.js +15 -14
- package/packages/piagent-core/extensions/task-contract-view.js +4 -4
- package/packages/piagent-core/extensions/task-digest-migration.js +2 -2
- package/packages/piagent-core/extensions/task-journal.js +48 -3
- package/packages/piagent-core/extensions/task-runtime-audit.js +8 -2
- package/packages/piagent-core/extensions/task-state.js +74 -38
- package/packages/piagent-core/extensions/task-terminal-disposition.js +10 -0
- package/packages/piagent-core/extensions/trajectory-contract.ts +5 -0
- package/packages/piagent-core/extensions/verification-intelligence.js +60 -8
- package/packages/piagent-core/extensions/workflow-catalog.ts +98 -0
- package/packages/piagent-core/extensions/workspace-revision.js +48 -0
- package/packages/piagent-core/extensions/workspace-verification-snapshot.js +13 -0
- package/packages/piagent-core/package.json +3 -3
- package/packages/piagent-core/policies/base-policy.json +1 -0
- package/packages/piagent-core/runtime/context/adaptive-planner.ts +7 -3
- package/packages/piagent-core/runtime/hooks/agent-start-hook.ts +60 -59
- package/packages/piagent-core/runtime/hooks/agent-start-types.ts +48 -0
- package/packages/piagent-core/runtime/hooks/completion-hook.ts +76 -83
- package/packages/piagent-core/runtime/hooks/input-hook.ts +92 -7
- package/packages/piagent-core/runtime/hooks/protected-refusal-completion.ts +86 -0
- package/packages/piagent-core/runtime/hooks/session-hooks.ts +5 -2
- package/packages/piagent-core/runtime/hooks/session-start-hook.ts +50 -18
- package/packages/piagent-core/runtime/hooks/tool-result-hook.ts +53 -20
- package/packages/piagent-core/runtime/hooks/tool-result-metadata.ts +9 -0
- package/packages/piagent-core/runtime/hooks/tool-result-navigation.ts +36 -0
- package/packages/piagent-core/runtime/hooks/tool-result-retrieval.ts +42 -0
- package/packages/piagent-core/runtime/input/chat-images.ts +1 -1
- package/packages/piagent-core/runtime/inspection/activity-event-adapter.ts +1 -1
- package/packages/piagent-core/runtime/inspection/same-process-bridge-proof.ts +1 -1
- package/packages/piagent-core/runtime/inspection/task-handoff-history.ts +2 -2
- package/packages/piagent-core/runtime/inspection/tool-failure-classification.ts +49 -8
- package/packages/piagent-core/runtime/inspection/webui-snapshot.ts +61 -15
- package/packages/piagent-core/runtime/inspection/workspace-file-reader.ts +2 -132
- package/packages/piagent-core/runtime/model/provider-wire-fingerprint.ts +20 -0
- package/packages/piagent-core/runtime/model/service-tier-runtime.ts +242 -0
- package/packages/piagent-core/runtime/policy/source-worktree-transaction.ts +75 -14
- package/packages/piagent-core/runtime/product/activity-inspector.ts +6 -3
- package/packages/piagent-core/runtime/product/edit-verifier-timing.ts +26 -0
- package/packages/piagent-core/runtime/product/efficiency-metrics.ts +12 -7
- package/packages/piagent-core/runtime/product/operator-projections.ts +8 -3
- package/packages/piagent-core/runtime/product/task-usage-hooks.ts +78 -0
- package/packages/piagent-core/runtime/product/task-usage.ts +104 -0
- package/packages/piagent-core/runtime/quality/protected-refusal-handoff.ts +35 -0
- package/packages/piagent-core/runtime/recovery/acceptance-recovery-guidance.ts +21 -0
- package/packages/piagent-core/runtime/recovery/continuation-budget.ts +11 -2
- package/packages/piagent-core/runtime/recovery/diagnostic-delivery.ts +61 -0
- package/packages/piagent-core/runtime/recovery/handoff-projection.ts +192 -57
- package/packages/piagent-core/runtime/recovery/handoff-verifier-binding.ts +24 -0
- package/packages/piagent-core/runtime/recovery/independent-verification-recovery.ts +79 -0
- package/packages/piagent-core/runtime/recovery/recovery-policy.ts +27 -39
- package/packages/piagent-core/runtime/recovery/resume-state.ts +8 -5
- package/packages/piagent-core/runtime/registration/activity-inspector-command.ts +2 -1
- package/packages/piagent-core/runtime/registration/context-commands.ts +12 -8
- package/packages/piagent-core/runtime/registration/operator-catalogs.ts +4 -9
- package/packages/piagent-core/runtime/registration/policy-tools.ts +5 -3
- package/packages/piagent-core/runtime/registration/session-commands.ts +9 -7
- package/packages/piagent-core/runtime/registration/session-wait-tool.ts +54 -0
- package/packages/piagent-core/runtime/registration/task-completion-tools.ts +27 -11
- package/packages/piagent-core/runtime/registration/task-start-conditional-mutation.ts +45 -0
- package/packages/piagent-core/runtime/registration/task-start-guidance.ts +5 -2
- package/packages/piagent-core/runtime/registration/task-start-tool.ts +23 -23
- package/packages/piagent-core/runtime/registration/workflow-commands.ts +64 -93
- package/packages/piagent-core/runtime/session/completion-signals.ts +23 -0
- package/packages/piagent-core/runtime/session/message-signals.ts +6 -22
- package/packages/piagent-core/runtime/session/retrieval-evidence-runtime.ts +188 -0
- package/packages/piagent-core/runtime/session/runtime-state.ts +29 -35
- package/packages/piagent-core/runtime/session/system-prompt.ts +3 -3
- package/packages/piagent-core/runtime/session/uncertain-send-continuation.ts +231 -0
- package/packages/piagent-core/runtime/session/usage.ts +4 -3
- package/packages/piagent-core/runtime/tools/apply-patch-tool.ts +6 -6
- package/packages/piagent-core/runtime/tools/phase-tool-runtime.ts +1 -1
- package/packages/piagent-core/runtime/tools/phase-tools.ts +3 -2
- package/packages/piagent-core/runtime/tools/session-wait.ts +42 -0
- package/packages/piagent-core/runtime/tools/tool-groups.ts +10 -3
- package/packages/piagent-core/runtime/trajectory/trajectory-runtime.ts +192 -5
- package/packages/piagent-core/runtime/trajectory/trajectory-types.ts +3 -2
- package/packages/piagent-core/runtime/verification/acceptance-api-baseline.js +488 -0
- package/packages/piagent-core/runtime/verification/completion-preparation.ts +22 -0
- package/packages/piagent-core/runtime/verification/composite-completion-finalizer.ts +105 -0
- package/packages/piagent-core/runtime/verification/composite-journal-anchor.ts +181 -0
- package/packages/piagent-core/runtime/verification/composite-runtime-binding.ts +76 -0
- package/packages/piagent-core/runtime/verification/composite-scoped-mediation.ts +318 -0
- package/packages/piagent-core/runtime/verification/composite-session-persistence.ts +175 -0
- package/packages/piagent-core/runtime/verification/composite-task-publication.ts +273 -0
- package/packages/piagent-core/runtime/verification/exact-verifier-reuse.ts +11 -11
- package/packages/piagent-core/runtime/verification/host-project-verification.ts +71 -0
- package/packages/piagent-core/runtime/verification/independent-acceptance-runtime.ts +500 -0
- package/packages/piagent-core/runtime/verification/runtime-assurance-facts.ts +500 -0
- package/packages/piagent-core/runtime/verification/runtime-contract-runner.ts +107 -0
- package/packages/piagent-core/runtime/verification/shell-verification-snapshots.ts +56 -0
- package/packages/piagent-core/runtime/workflows/change-clarification.ts +61 -0
- package/packages/piagent-core/runtime/workflows/input-routing.ts +21 -14
- package/packages/piagent-core/runtime/workflows/runtime-intake-compaction.ts +44 -7
- package/packages/piagent-core/runtime/workflows/task-followup-policy.ts +163 -0
- package/packages/piagent-core/runtime/workflows/task-intake.ts +221 -242
- package/packages/piagent-core/runtime/workflows/task-repair-intent.ts +67 -0
- package/packages/piagent-core/runtime/workflows/task-scope-resolution.ts +83 -0
- package/packages/piagent-core/runtime/workflows/webui-runtime-command.ts +5 -2
- package/packages/piagent-core/runtime/workflows/webui-workflow.ts +39 -32
- package/packages/piagent-core/runtime/workflows/workflow-follow-up.ts +33 -0
- package/packages/piagent-core/security/workspace-file-reader.ts +132 -0
- package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-B4XehTCU.js → MarkdownMessage-DGk34zJT.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/{index-BV-_03yl.css → index-DVahUVWy.css} +1 -1
- package/packages/piagent-webui/dist/client/assets/index-DiKRmCEP.js +176 -0
- package/packages/piagent-webui/dist/client/index.html +2 -2
- package/packages/piagent-webui/extension/dispatch-user-entry.ts +13 -0
- package/packages/piagent-webui/extension/piagent-webui.ts +10 -2
- package/packages/piagent-webui/extension/review-controller.ts +29 -6
- package/packages/piagent-webui/extension/same-session-bridge.ts +6 -7
- package/packages/piagent-webui/extension/session-stream-adapter.ts +60 -11
- package/packages/piagent-webui/extension/source-mutation-controller.ts +29 -3
- package/packages/piagent-webui/extension/source-open-controller.ts +29 -7
- package/packages/piagent-webui/extension/source-revert-controller.ts +26 -3
- package/packages/piagent-webui/gateway/gateway-events.ts +22 -5
- package/packages/piagent-webui/gateway/gateway-service.ts +7 -2
- package/packages/piagent-webui/gateway/gateway-session-stream.ts +141 -19
- package/packages/piagent-webui/gateway/rpc-ui-context.ts +34 -9
- package/packages/piagent-webui/gateway/runtime-command-controller.ts +46 -6
- package/packages/piagent-webui/gateway/runtime-session-controls.ts +17 -2
- package/packages/piagent-webui/gateway/session-catalog.ts +9 -3
- package/packages/piagent-webui/gateway/session-command-controller.ts +29 -9
- package/packages/piagent-webui/gateway/session-effective-options.ts +2 -9
- package/packages/piagent-webui/gateway/session-inspection-registry.ts +11 -2
- package/packages/piagent-webui/gateway/session-operation-settlement.ts +28 -0
- package/packages/piagent-webui/gateway/session-prompt-dispatch.ts +37 -0
- package/packages/piagent-webui/gateway/session-runtime-close.ts +36 -0
- package/packages/piagent-webui/gateway/session-runtime-factory.ts +183 -6
- package/packages/piagent-webui/gateway/session-runtime-ownership.ts +48 -0
- package/packages/piagent-webui/gateway/session-runtime-state.ts +24 -0
- package/packages/piagent-webui/gateway/session-runtime-supervisor.ts +114 -114
- package/packages/piagent-webui/server/core-inspection-provider.ts +73 -14
- package/packages/piagent-webui/server/loopback-server.ts +9 -7
- package/packages/piagent-webui/server/terminal-delivery-receipt.ts +144 -0
- package/packages/piagent-webui/server/transcript-projection.ts +65 -12
- package/packages/piagent-webui/shared/message-correlation.ts +25 -0
- package/schemas/approved-host-contracts.schema.json +973 -0
- package/schemas/benchmark-attempt-outcome.schema.json +303 -0
- package/schemas/benchmark-independent-verification-plan.schema.json +34 -0
- package/schemas/composite-criterion.schema.json +788 -0
- package/schemas/contract-family-library.schema.json +28 -0
- package/schemas/contract-selection-recipe.schema.json +31 -0
- package/schemas/failure-evidence.schema.json +2 -2
- package/schemas/helper-request.schema.json +16 -4
- package/schemas/host-contract-plan.schema.json +25 -0
- package/schemas/piagent-webui/gateway-protocol-v1.schema.json +16 -2
- package/schemas/piagent-webui/runtime-command-v1.schema.json +26 -3
- package/schemas/piagent-webui/runtime-event-v2.schema.json +32 -1
- package/schemas/piagent-webui/session-live-state-v1.schema.json +2 -0
- package/schemas/piagent-webui/snapshot-v1.schema.json +3 -0
- package/schemas/piagent-webui/source-change-v1.schema.json +12 -0
- package/schemas/piagent-webui/transcript-v1.schema.json +2 -1
- package/schemas/public-contracts/codex-mcp-metadata-v1.schema.json +206 -0
- package/schemas/public-contracts/codex-mcp-metadata-v2.schema.json +228 -0
- package/schemas/public-contracts/codex-mcp-metadata-v3.schema.json +233 -0
- package/schemas/public-contracts/revocation-v1.schema.json +87 -0
- package/schemas/public-contracts/subscription-contract-v1.schema.json +76 -0
- package/schemas/scoped-project-verification-receipt-v2.schema.json +83 -0
- package/schemas/scoped-project-verification-receipt-v3.schema.json +295 -0
- package/schemas/scoped-verification-receipt-v1.schema.json +76 -0
- package/schemas/task-contract.schema.json +30 -0
- package/scripts/approve-independent-verification.mjs +57 -0
- package/scripts/benchmark-arm-observer.mjs +320 -0
- package/scripts/benchmark-budget-ipc.mjs +34 -0
- package/scripts/benchmark-budget-launcher.mjs +91 -0
- package/scripts/benchmark-budget-processes.mjs +133 -0
- package/scripts/benchmark-budget-publication.mjs +228 -0
- package/scripts/benchmark-budget-runtime.mjs +136 -0
- package/scripts/benchmark-candidate-ablation.mjs +265 -0
- package/scripts/benchmark-codex-journey.mjs +406 -0
- package/scripts/benchmark-independent-verification.mjs +628 -0
- package/scripts/benchmark-journey-outcome.mjs +92 -0
- package/scripts/benchmark-production-v3-human-review.mjs +192 -0
- package/scripts/benchmark-public-input-catalog.mjs +158 -0
- package/scripts/benchmark-registered-plan-author.mjs +355 -0
- package/scripts/benchmark-registered-plan-recipe-support.mjs +85 -0
- package/scripts/benchmark-registered-plan-recipes-backend.mjs +165 -0
- package/scripts/benchmark-registered-plan-recipes-data.mjs +164 -0
- package/scripts/benchmark-registered-plan-recipes-platform.mjs +165 -0
- package/scripts/benchmark-runner-completion.mjs +133 -0
- package/scripts/benchmark-runner-configuration.mjs +159 -0
- package/scripts/benchmark-runner-core.mjs +217 -388
- package/scripts/benchmark-runner-finalization.mjs +140 -27
- package/scripts/benchmark-runner-provider-boundary.mjs +44 -0
- package/scripts/benchmark-runner-schedule.mjs +256 -0
- package/scripts/benchmark-runner-support.mjs +136 -4
- package/scripts/benchmark-runner.mjs +95 -18
- package/scripts/benchmark-scoped-broker-custody.mjs +483 -0
- package/scripts/benchmark-scoped-docs-verifier.mjs +203 -0
- package/scripts/benchmark-scoped-frozen-qualification.mjs +676 -0
- package/scripts/benchmark-scoped-pi-router.mjs +196 -0
- package/scripts/benchmark-scoped-project-verification-receipt.mjs +49 -0
- package/scripts/benchmark-scoped-project-verifier.mjs +461 -0
- package/scripts/benchmark-scoped-session-custody.mjs +599 -0
- package/scripts/benchmark-scoped-session-factory.mjs +342 -0
- package/scripts/benchmark-scoped-tool-broker.mjs +523 -0
- package/scripts/benchmark-scoped-verification-supervisor.mjs +773 -0
- package/scripts/benchmark-session-evaluator.mjs +169 -0
- package/scripts/benchmark-session-provider-boundary.mjs +62 -0
- package/scripts/benchmark-session-usage.mjs +28 -0
- package/scripts/benchmark-session.mjs +343 -50
- package/scripts/benchmark-webui-journey.mjs +678 -0
- package/scripts/check-public-wording.mjs +46 -0
- package/scripts/fs4-readiness-evaluation.mjs +7 -1
- package/scripts/phase-tools-evaluation.mjs +1 -0
- package/scripts/pi-auto.sh +7 -1
- package/scripts/pi-usage-history.mjs +201 -11
- package/scripts/piagent-cli.mjs +8 -0
- package/scripts/private-holdout-readiness.mjs +7 -1
- package/scripts/public-evaluation-exposure.mjs +140 -0
- package/scripts/select-independent-verification.mjs +62 -0
- package/scripts/typescript-loader.mjs +135 -1
- package/scripts/update-global.mjs +6 -7
- package/scripts/verify-local.sh +36 -55
- package/scripts/verify-release-identity.mjs +5 -3
- package/packages/piagent-webui/dist/client/assets/index-CgOEyRPG.js +0 -176
|
@@ -4,6 +4,7 @@ import path from "node:path";
|
|
|
4
4
|
|
|
5
5
|
import { redactForStorage } from "./redaction-core.js";
|
|
6
6
|
import { ensurePrivateStateDirectory, resolveLocalStatePath } from "./local-state-path.js";
|
|
7
|
+
import { recoveryDecisionValidationErrors } from "./recovery-decision-validation.ts";
|
|
7
8
|
import { isCurrentWorkingTreeDigest } from "./working-tree-digest.js";
|
|
8
9
|
|
|
9
10
|
export const TASK_JOURNAL_SCHEMA_VERSION = 1;
|
|
@@ -47,6 +48,30 @@ function compactId(value, fallback = "unknown") {
|
|
|
47
48
|
.slice(0, 160) || fallback;
|
|
48
49
|
}
|
|
49
50
|
|
|
51
|
+
function checkpointMatchesTask(event, task) {
|
|
52
|
+
return typeof task?.taskId === "string" && task.taskId.length > 0
|
|
53
|
+
&& typeof task?.taskRunId === "string" && task.taskRunId.length > 0
|
|
54
|
+
&& typeof task?.sessionId === "string" && task.sessionId.length > 0
|
|
55
|
+
&& event.taskRunId === compactId(task.taskRunId)
|
|
56
|
+
&& event.taskId === compactId(task?.taskId)
|
|
57
|
+
&& event.sessionId === String(task?.sessionId)
|
|
58
|
+
&& event.data?.attempt === task?.attempt;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function terminalHandoffCheckpoint(checkpoint, task) {
|
|
62
|
+
const recovery = checkpoint?.evidence?.recovery;
|
|
63
|
+
return checkpoint?.checkpointId === "completion"
|
|
64
|
+
&& ["failed", "blocked"].includes(String(checkpoint.status))
|
|
65
|
+
&& recoveryDecisionValidationErrors(recovery).length === 0
|
|
66
|
+
&& recovery.taskId === task?.taskId
|
|
67
|
+
&& recovery.taskRunId === task?.taskRunId
|
|
68
|
+
&& recovery.taskAttempt === task?.attempt
|
|
69
|
+
&& recovery.action === "handoff"
|
|
70
|
+
&& recovery.continuation === "none"
|
|
71
|
+
&& recovery.nextPhase === null
|
|
72
|
+
&& recovery.sourceMutationAllowed === false;
|
|
73
|
+
}
|
|
74
|
+
|
|
50
75
|
function safeData(value) {
|
|
51
76
|
const redacted = redactForStorage(value ?? {});
|
|
52
77
|
const serialized = JSON.stringify(redacted);
|
|
@@ -411,6 +436,9 @@ export function replayTaskCheckpoints(cwd, taskRunId, task) {
|
|
|
411
436
|
const checkpoints = new Map();
|
|
412
437
|
const idempotency = new Set();
|
|
413
438
|
const corruptions = [...journal.corruptions];
|
|
439
|
+
if (task && compactId(taskRunId) !== compactId(task.taskRunId)) {
|
|
440
|
+
corruptions.push("checkpoint replay taskRunId does not match the Task Contract");
|
|
441
|
+
}
|
|
414
442
|
const migrationEvents = journal.events.filter((event) => event.eventType === "digest-migrated");
|
|
415
443
|
const invalidMigration = migrationEvents.find((event) => !validDigestMigrationBarrier(event));
|
|
416
444
|
if (invalidMigration) corruptions.push(`digest migration sequence ${invalidMigration.sequence}: marker is invalid`);
|
|
@@ -422,8 +450,12 @@ export function replayTaskCheckpoints(cwd, taskRunId, task) {
|
|
|
422
450
|
? undefined
|
|
423
451
|
: [...migrationEvents].reverse().find((event) => digestMigrationBarrierMatchesTask(event, task));
|
|
424
452
|
for (const event of journal.events) {
|
|
425
|
-
if (migrationBarrier && event.sequence <= migrationBarrier.sequence) continue;
|
|
426
453
|
if (event.eventType !== "checkpoint") continue;
|
|
454
|
+
if (task && !checkpointMatchesTask(event, task)) {
|
|
455
|
+
corruptions.push(`checkpoint sequence ${event.sequence}: identity does not match the Task Contract`);
|
|
456
|
+
continue;
|
|
457
|
+
}
|
|
458
|
+
if (migrationBarrier && event.sequence <= migrationBarrier.sequence) continue;
|
|
427
459
|
const treeErrors = checkpointTreeDigestValidationErrors(event.data?.evidence);
|
|
428
460
|
if (treeErrors.length > 0) {
|
|
429
461
|
corruptions.push(`checkpoint sequence ${event.sequence}: ${treeErrors[0]}`);
|
|
@@ -432,14 +464,18 @@ export function replayTaskCheckpoints(cwd, taskRunId, task) {
|
|
|
432
464
|
if (event.idempotencyKey && idempotency.has(event.idempotencyKey)) continue;
|
|
433
465
|
if (event.idempotencyKey) idempotency.add(event.idempotencyKey);
|
|
434
466
|
const checkpointId = event.checkpointId ?? "checkpoint";
|
|
435
|
-
|
|
467
|
+
const checkpoint = {
|
|
436
468
|
checkpointId,
|
|
437
469
|
taskRunId: event.taskRunId,
|
|
438
470
|
sessionId: event.sessionId,
|
|
439
471
|
sequence: event.sequence,
|
|
440
472
|
recordedAt: event.recordedAt,
|
|
441
473
|
...event.data
|
|
442
|
-
}
|
|
474
|
+
};
|
|
475
|
+
const existing = checkpoints.get(checkpointId);
|
|
476
|
+
if (!terminalHandoffCheckpoint(existing, task) || terminalHandoffCheckpoint(checkpoint, task)) {
|
|
477
|
+
checkpoints.set(checkpointId, checkpoint);
|
|
478
|
+
}
|
|
443
479
|
}
|
|
444
480
|
return {
|
|
445
481
|
taskRunId,
|
|
@@ -470,6 +506,15 @@ export function taskRecoveryDecision(task, replay = { checkpoints: [], corruptio
|
|
|
470
506
|
};
|
|
471
507
|
}
|
|
472
508
|
const checkpoints = Array.isArray(replay.checkpoints) ? replay.checkpoints : [];
|
|
509
|
+
const terminalHandoff = checkpoints.findLast((checkpoint) => terminalHandoffCheckpoint(checkpoint, task));
|
|
510
|
+
if (terminalHandoff) {
|
|
511
|
+
return {
|
|
512
|
+
decision: "blocked",
|
|
513
|
+
retryAllowed: false,
|
|
514
|
+
checkpointId: terminalHandoff.checkpointId,
|
|
515
|
+
reason: `Checkpoint ${terminalHandoff.checkpointId} recorded a terminal recovery handoff; inspect that handoff before any retry.`
|
|
516
|
+
};
|
|
517
|
+
}
|
|
473
518
|
const contractSteps = Array.isArray(task?.workPlan) ? task.workPlan : [];
|
|
474
519
|
const contractOpen = contractSteps.findLast((step) => ["in-progress", "failed"].includes(String(step?.status)));
|
|
475
520
|
const latestOpen = contractOpen
|
|
@@ -34,7 +34,8 @@ export function recordMutationCheckpoint(ctx, task, evidence = {}) {
|
|
|
34
34
|
export function recordVerificationCheckpoint(ctx, task, verification = {}) {
|
|
35
35
|
const observation = verification.observedAt ?? task.updatedAt;
|
|
36
36
|
const preTree = verification.preWorkingTreeDigest ?? verification.evidence?.preWorkingTreeDigest;
|
|
37
|
-
const
|
|
37
|
+
const preRevision = verification.evidence?.preWorkspaceRevisionDigest, revision = verification.evidence?.workspaceRevisionDigest;
|
|
38
|
+
const identity = crypto.createHash("sha256").update(JSON.stringify([verification.commandHash, preTree, verification.workingTreeDigest, verification.exitCode, observation, preRevision, revision])).digest("hex");
|
|
38
39
|
return recordRuntimeTaskCheckpoint(ctx, {
|
|
39
40
|
taskRunId: task.taskRunId,
|
|
40
41
|
taskId: task.taskId,
|
|
@@ -45,7 +46,12 @@ export function recordVerificationCheckpoint(ctx, task, verification = {}) {
|
|
|
45
46
|
phase: "verify",
|
|
46
47
|
status: verification.exitCode === 0 ? "done" : "failed",
|
|
47
48
|
attempt: task.attempt,
|
|
48
|
-
evidence: verification.evidence
|
|
49
|
+
evidence: { ...verification.evidence, verificationObservation: {
|
|
50
|
+
command: String(verification.evidence?.command ?? "").trim(), observedAt: observation, exitCode: verification.exitCode,
|
|
51
|
+
...(preTree ? { preWorkingTreeDigest: preTree } : {}),
|
|
52
|
+
...(preRevision ? { preWorkspaceRevisionDigest: preRevision } : {}), ...(revision ? { workspaceRevisionDigest: revision } : {}),
|
|
53
|
+
...(verification.workingTreeDigest ? { workingTreeDigest: verification.workingTreeDigest } : {})
|
|
54
|
+
} }
|
|
49
55
|
});
|
|
50
56
|
}
|
|
51
57
|
|
|
@@ -3,8 +3,7 @@ import fs from "node:fs";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { ensurePrivateStateDirectory, resolveLocalStatePath } from "./local-state-path.js";
|
|
5
5
|
import { appendTaskJournalEvent, readTaskJournal } from "./task-journal.js";
|
|
6
|
-
import {
|
|
7
|
-
acceptanceReceiptProvenanceSummary,
|
|
6
|
+
import { acceptanceReceiptProvenanceSummary,
|
|
8
7
|
acceptanceReceiptSummary,
|
|
9
8
|
acceptanceReceiptValidationErrors,
|
|
10
9
|
normalizeAcceptanceReceipt
|
|
@@ -12,6 +11,7 @@ import {
|
|
|
12
11
|
import { LEGACY_UNTRUSTED_DIGEST_ALGORITHM } from "./task-digest-migration.js";
|
|
13
12
|
import { criterionGraphValidationErrors, normalizeCriterionGraph } from "./criterion-graph.js";
|
|
14
13
|
import { normalizeTaskAuthoritySnapshot, taskAuthorityContractValidationErrors } from "./task-authority-contract.js";
|
|
14
|
+
import { normalizeTerminalDisposition, validTerminalDisposition } from "./task-terminal-disposition.js";
|
|
15
15
|
import {
|
|
16
16
|
commitLegacySchemaTaskDigestState,
|
|
17
17
|
migrateUnversionedTaskDigestState,
|
|
@@ -21,15 +21,14 @@ import {
|
|
|
21
21
|
export { taskDigestMigrationArchiveStatus } from "./task-digest-state.js";
|
|
22
22
|
import { acceptanceReceiptWithoutWorkingTreeProof, normalizedTaskDigestFields, taskDigestContractValidationErrors } from "./task-digest-contract.js";
|
|
23
23
|
import { unicodeCodePointLength } from "./verification-intelligence.js";
|
|
24
|
-
import {
|
|
25
|
-
|
|
24
|
+
import { isWorkspaceRevisionDigest } from "./workspace-revision.js";
|
|
25
|
+
import { WORKING_TREE_DIGEST_ALGORITHM,
|
|
26
26
|
isCurrentWorkingTreeDigest,
|
|
27
27
|
isUnavailableWorkingTreeDigest,
|
|
28
28
|
unavailableWorkingTreeHash,
|
|
29
29
|
versionWorkingTreeHash
|
|
30
30
|
} from "./working-tree-digest.js";
|
|
31
|
-
import {
|
|
32
|
-
directChildGitEvidenceRoots,
|
|
31
|
+
import { directChildGitEvidenceRoots,
|
|
33
32
|
gitEvidenceRootDetails,
|
|
34
33
|
gitEvidenceRoots,
|
|
35
34
|
gitOutput,
|
|
@@ -41,7 +40,6 @@ import {
|
|
|
41
40
|
prefixedGitPath
|
|
42
41
|
} from "./workspace-evidence-roots.js";
|
|
43
42
|
export { isGitWorkingTree } from "./workspace-evidence-roots.js";
|
|
44
|
-
|
|
45
43
|
export const TASK_CONTRACT_SCHEMA_VERSION = 2; export const DEFAULT_MAX_TASK_ATTEMPTS = 3;
|
|
46
44
|
export const OPERATOR_REQUEST_MAX_CHARS = 8_000;
|
|
47
45
|
export const TASK_SUMMARY_MAX_CHARS = 2_000;
|
|
@@ -63,8 +61,8 @@ const CITATION_FIELDS = new Set(["path", "reason"]);
|
|
|
63
61
|
const WORK_PLAN_FIELDS = new Set(["id", "title", "role", "mode", "status", "dependsOn", "note", "updatedAt"]);
|
|
64
62
|
const ORCHESTRATION_FIELDS = new Set(["mode", "subagents", "reason", "fieldGuidePath", "modelRoles"]);
|
|
65
63
|
const MODEL_ROLE_FIELDS = new Set(["planner", "worker", "reviewer", "watchdog"]);
|
|
66
|
-
const VERIFY_EVIDENCE_FIELDS = new Set(["command", "exitCode", "summary", "recordedAt", "observed", "observedAt", "isError", "matchedProfileCommand", "preWorkingTreeDigest", "workingTreeDigest"]);
|
|
67
|
-
const TRACE_FIELDS = new Set(["outcome", "friction", "notes", "recordedAt"]);
|
|
64
|
+
const VERIFY_EVIDENCE_FIELDS = new Set(["command", "exitCode", "summary", "recordedAt", "observed", "observedAt", "isError", "matchedProfileCommand", "preWorkingTreeDigest", "workingTreeDigest", "preWorkspaceRevisionDigest", "workspaceRevisionDigest"]);
|
|
65
|
+
const TRACE_FIELDS = new Set(["outcome", "terminalDisposition", "friction", "notes", "recordedAt"]);
|
|
68
66
|
export function safeTaskId(value) {
|
|
69
67
|
const normalized = String(value ?? "")
|
|
70
68
|
.trim()
|
|
@@ -75,26 +73,21 @@ export function safeTaskId(value) {
|
|
|
75
73
|
.replace(/-+$/g, "");
|
|
76
74
|
return normalized || "task";
|
|
77
75
|
}
|
|
78
|
-
|
|
79
76
|
function stateRoot(cwd) { return path.join(cwd, ".pi", "piagent-state"); }
|
|
80
77
|
function tasksRoot(cwd) { return path.join(stateRoot(cwd), "tasks"); }
|
|
81
78
|
function sessionsRoot(cwd) { return path.join(stateRoot(cwd), "session-tasks"); }
|
|
82
|
-
|
|
83
79
|
function taskRunPath(cwd, taskRunId) {
|
|
84
80
|
return path.join(tasksRoot(cwd), `${safeTaskId(taskRunId)}.json`);
|
|
85
81
|
}
|
|
86
|
-
|
|
87
82
|
function sessionBindingPath(cwd, sessionId) {
|
|
88
83
|
const digest = crypto.createHash("sha256").update(String(sessionId || "unknown")).digest("hex");
|
|
89
84
|
return path.join(sessionsRoot(cwd), `${digest}.json`);
|
|
90
85
|
}
|
|
91
|
-
|
|
92
86
|
function readTaskRun(cwd, taskRunId) {
|
|
93
87
|
const raw = readJson(cwd, taskRunPath(cwd, taskRunId));
|
|
94
88
|
const task = normalizeTaskContract(raw, { sourceName: taskRunId });
|
|
95
89
|
return task?.taskRunId === safeTaskId(taskRunId) ? task : undefined;
|
|
96
90
|
}
|
|
97
|
-
|
|
98
91
|
function readJson(cwd, filePath) {
|
|
99
92
|
try {
|
|
100
93
|
const safePath = resolveLocalStatePath(cwd, filePath, { label: "Task state", kind: "file" });
|
|
@@ -113,21 +106,34 @@ function readJson(cwd, filePath) {
|
|
|
113
106
|
return undefined;
|
|
114
107
|
}
|
|
115
108
|
}
|
|
116
|
-
|
|
117
109
|
function writeJsonAtomic(cwd, filePath, value) {
|
|
118
110
|
const parent = ensurePrivateStateDirectory(cwd, path.dirname(filePath), "Task state directory");
|
|
119
111
|
const safePath = resolveLocalStatePath(cwd, filePath, { label: "Task state" });
|
|
120
112
|
const temporary = path.join(parent, `${path.basename(safePath)}.${process.pid}.${crypto.randomBytes(4).toString("hex")}.tmp`);
|
|
121
|
-
fs.writeFileSync(temporary, `${JSON.stringify(value, null, 2)}\n`, { mode: 0o600 });
|
|
122
|
-
fs.renameSync(temporary, safePath);
|
|
123
113
|
try {
|
|
114
|
+
const bytes = Buffer.from(`${JSON.stringify(value, null, 2)}\n`);
|
|
115
|
+
const descriptor = fs.openSync(temporary, fs.constants.O_WRONLY | fs.constants.O_CREAT
|
|
116
|
+
| fs.constants.O_EXCL | (fs.constants.O_NOFOLLOW ?? 0), 0o600);
|
|
117
|
+
try {
|
|
118
|
+
for (let offset = 0; offset < bytes.length;) {
|
|
119
|
+
const written = fs.writeSync(descriptor, bytes, offset, bytes.length - offset);
|
|
120
|
+
if (written < 1) throw new Error("Task state write was incomplete");
|
|
121
|
+
offset += written;
|
|
122
|
+
}
|
|
123
|
+
fs.fsyncSync(descriptor);
|
|
124
|
+
} finally {
|
|
125
|
+
fs.closeSync(descriptor);
|
|
126
|
+
}
|
|
127
|
+
fs.renameSync(temporary, safePath);
|
|
124
128
|
fs.chmodSync(parent, 0o700);
|
|
125
129
|
fs.chmodSync(safePath, 0o600);
|
|
130
|
+
const directory = fs.openSync(parent, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW ?? 0));
|
|
131
|
+
try { fs.fsyncSync(directory); } finally { fs.closeSync(directory); }
|
|
126
132
|
} catch {
|
|
127
|
-
|
|
133
|
+
try { fs.unlinkSync(temporary); } catch {}
|
|
134
|
+
throw new Error("Task state atomic persistence failed");
|
|
128
135
|
}
|
|
129
136
|
}
|
|
130
|
-
|
|
131
137
|
function appendTaskStateJournalEvent(cwd, event) {
|
|
132
138
|
try {
|
|
133
139
|
return appendTaskJournalEvent(cwd, event);
|
|
@@ -137,42 +143,33 @@ function appendTaskStateJournalEvent(cwd, event) {
|
|
|
137
143
|
return undefined;
|
|
138
144
|
}
|
|
139
145
|
}
|
|
140
|
-
|
|
141
146
|
function stringArray(value) {
|
|
142
147
|
return Array.isArray(value) ? [...new Set(value.filter((item) => typeof item === "string" && item.trim()).map((item) => item.trim()))] : [];
|
|
143
148
|
}
|
|
144
|
-
|
|
145
149
|
function exactCommandArray(value) {
|
|
146
150
|
return Array.isArray(value) ? [...new Set(value.filter((item) => typeof item === "string" && item.trim()))] : [];
|
|
147
151
|
}
|
|
148
|
-
|
|
149
152
|
function stringRecord(value) {
|
|
150
153
|
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
151
154
|
return Object.fromEntries(Object.entries(value)
|
|
152
155
|
.filter(([key, item]) => key && typeof item === "string")
|
|
153
156
|
.map(([key, item]) => [key.replaceAll("\\", "/"), item]));
|
|
154
157
|
}
|
|
155
|
-
|
|
156
158
|
function positiveInteger(value, fallback, maximum = Number.MAX_SAFE_INTEGER) {
|
|
157
159
|
return Number.isInteger(value) && value > 0 ? Math.min(value, maximum) : fallback;
|
|
158
160
|
}
|
|
159
|
-
|
|
160
161
|
function validTimestamp(value) {
|
|
161
162
|
return typeof value === "string" && value.trim().length > 0 && Number.isFinite(Date.parse(value));
|
|
162
163
|
}
|
|
163
|
-
|
|
164
164
|
export function operatorRequestDigest(value) {
|
|
165
165
|
return `operator-request-v1:${crypto.createHash("sha256").update(String(value ?? "")).digest("hex")}`;
|
|
166
166
|
}
|
|
167
|
-
|
|
168
167
|
function normalizedTimestamp(value, fallback) {
|
|
169
168
|
return validTimestamp(value) ? value : fallback;
|
|
170
169
|
}
|
|
171
|
-
|
|
172
170
|
function isRecord(value) {
|
|
173
171
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
174
172
|
}
|
|
175
|
-
|
|
176
173
|
function unsupportedObjectField(value, allowed) {
|
|
177
174
|
if (!isRecord(value)) return undefined;
|
|
178
175
|
return Object.keys(value).find((key) => !allowed.has(key));
|
|
@@ -226,8 +223,8 @@ export function taskContractValidationErrors(input) {
|
|
|
226
223
|
}
|
|
227
224
|
if (input.failedAt !== undefined && !["research", "plan", "execute", "verify", "review"].includes(input.failedAt)) errors.push("failedAt is invalid");
|
|
228
225
|
if (!["source-change", "read-only"].includes(input.changeMode)) errors.push("changeMode is invalid");
|
|
229
|
-
if (input.mutationPolicy !== undefined && !["required", "forbidden"].includes(input.mutationPolicy)) errors.push("mutationPolicy is invalid");
|
|
230
|
-
if (input.changeMode === "read-only" && input.mutationPolicy
|
|
226
|
+
if (input.mutationPolicy !== undefined && !["required", "allowed", "forbidden"].includes(input.mutationPolicy)) errors.push("mutationPolicy is invalid");
|
|
227
|
+
if (input.changeMode === "read-only" && input.mutationPolicy !== undefined && input.mutationPolicy !== "forbidden") errors.push("read-only tasks must forbid mutation");
|
|
231
228
|
if (!["tiny", "normal", "high-risk"].includes(input.riskLane)) errors.push("riskLane is invalid");
|
|
232
229
|
if (input.intakeMode !== undefined && !["model", "runtime"].includes(input.intakeMode)) errors.push("intakeMode is invalid");
|
|
233
230
|
errors.push(...taskDigestContractValidationErrors(input));
|
|
@@ -329,13 +326,16 @@ export function taskContractValidationErrors(input) {
|
|
|
329
326
|
|| (item.matchedProfileCommand !== undefined && typeof item.matchedProfileCommand !== "boolean")
|
|
330
327
|
|| (item.preWorkingTreeDigest !== undefined && !isCurrentWorkingTreeDigest(item.preWorkingTreeDigest))
|
|
331
328
|
|| (item.workingTreeDigest !== undefined && !isCurrentWorkingTreeDigest(item.workingTreeDigest))
|
|
329
|
+
|| (item.preWorkspaceRevisionDigest !== undefined && !isWorkspaceRevisionDigest(item.preWorkspaceRevisionDigest))
|
|
330
|
+
|| (item.workspaceRevisionDigest !== undefined && !isWorkspaceRevisionDigest(item.workspaceRevisionDigest))
|
|
332
331
|
))) {
|
|
333
332
|
errors.push("verifyEvidence entries are invalid");
|
|
334
333
|
}
|
|
335
334
|
if (!isRecord(input.trace) || unsupportedObjectField(input.trace, TRACE_FIELDS) || !TASK_OUTCOMES.includes(input.trace.outcome)) {
|
|
336
335
|
errors.push("trace.outcome is invalid");
|
|
337
|
-
} else
|
|
338
|
-
errors.push("trace.
|
|
336
|
+
} else {
|
|
337
|
+
if (!validTerminalDisposition(input.trace)) errors.push("trace.terminalDisposition is invalid");
|
|
338
|
+
if (input.trace.recordedAt !== undefined && !validTimestamp(input.trace.recordedAt)) errors.push("trace.recordedAt must be a valid timestamp");
|
|
339
339
|
}
|
|
340
340
|
if (input.orchestration !== undefined) {
|
|
341
341
|
const orchestration = input.orchestration;
|
|
@@ -411,7 +411,9 @@ export function normalizeTaskContract(input, options = {}) {
|
|
|
411
411
|
isError: item.isError,
|
|
412
412
|
matchedProfileCommand: item.matchedProfileCommand,
|
|
413
413
|
preWorkingTreeDigest: item.preWorkingTreeDigest,
|
|
414
|
-
workingTreeDigest: item.workingTreeDigest
|
|
414
|
+
workingTreeDigest: item.workingTreeDigest,
|
|
415
|
+
preWorkspaceRevisionDigest: item.preWorkspaceRevisionDigest,
|
|
416
|
+
workspaceRevisionDigest: item.workspaceRevisionDigest
|
|
415
417
|
} : item)
|
|
416
418
|
: [];
|
|
417
419
|
const normalized = {
|
|
@@ -421,7 +423,9 @@ export function normalizeTaskContract(input, options = {}) {
|
|
|
421
423
|
sessionId,
|
|
422
424
|
sessionName: String(input.sessionName ?? options.sessionName ?? "").trim() || undefined,
|
|
423
425
|
changeMode: input.changeMode === "read-only" ? "read-only" : "source-change",
|
|
424
|
-
mutationPolicy: input.changeMode === "read-only" || input.mutationPolicy === "forbidden"
|
|
426
|
+
mutationPolicy: input.changeMode === "read-only" || input.mutationPolicy === "forbidden"
|
|
427
|
+
? "forbidden"
|
|
428
|
+
: input.mutationPolicy === "allowed" ? "allowed" : "required",
|
|
425
429
|
attempt: positiveInteger(input.attempt, 1, 100),
|
|
426
430
|
maxAttempts: positiveInteger(input.maxAttempts, DEFAULT_MAX_TASK_ATTEMPTS, 10),
|
|
427
431
|
previousAttempts: Array.isArray(input.previousAttempts) ? input.previousAttempts.slice(-10).map((item) => pickFields(item, PREVIOUS_ATTEMPT_FIELDS)) : [],
|
|
@@ -463,6 +467,7 @@ export function normalizeTaskContract(input, options = {}) {
|
|
|
463
467
|
verifyEvidence: legacyDigestContract ? [] : verifyEvidence,
|
|
464
468
|
trace: {
|
|
465
469
|
outcome: legacyDigestContract && trace.outcome === "pending" ? "blocked" : TASK_OUTCOMES.includes(trace.outcome) ? trace.outcome : "pending",
|
|
470
|
+
terminalDisposition: normalizeTerminalDisposition(trace),
|
|
466
471
|
friction: legacyDigestContract && trace.outcome === "pending" ? "Legacy working-tree evidence is not replayable; start a new attempt." : typeof trace.friction === "string" ? trace.friction : undefined,
|
|
467
472
|
notes: typeof trace.notes === "string" ? trace.notes : undefined,
|
|
468
473
|
recordedAt: legacyDigestContract && trace.outcome === "pending" ? updatedAt : trace.recordedAt === undefined ? undefined : normalizedTimestamp(trace.recordedAt, updatedAt)
|
|
@@ -524,6 +529,37 @@ export function writeTaskContract(cwd, task) {
|
|
|
524
529
|
return normalized;
|
|
525
530
|
}
|
|
526
531
|
|
|
532
|
+
/** Confirms the exact normalized task bytes through a stable, fsync-backed read. */
|
|
533
|
+
export function durableTaskContractMatches(cwd, expected) {
|
|
534
|
+
try {
|
|
535
|
+
const normalized = normalizeTaskContract(expected);
|
|
536
|
+
if (!normalized || taskContractValidationErrors(normalized).length > 0) return false;
|
|
537
|
+
const safePath = resolveLocalStatePath(cwd, taskRunPath(cwd, normalized.taskRunId), {
|
|
538
|
+
label: "Task state", kind: "file"
|
|
539
|
+
});
|
|
540
|
+
const descriptor = fs.openSync(safePath, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW ?? 0));
|
|
541
|
+
try {
|
|
542
|
+
fs.fsyncSync(descriptor);
|
|
543
|
+
const before = fs.fstatSync(descriptor, { bigint: true });
|
|
544
|
+
if (!before.isFile() || before.nlink !== 1n || before.size < 1n
|
|
545
|
+
|| before.size > BigInt(8 * 1024 * 1024)) return false;
|
|
546
|
+
const bytes = fs.readFileSync(descriptor);
|
|
547
|
+
const after = fs.fstatSync(descriptor, { bigint: true });
|
|
548
|
+
const atPath = fs.lstatSync(safePath, { bigint: true });
|
|
549
|
+
const fields = ["dev", "ino", "mode", "nlink", "size", "mtimeNs", "ctimeNs"];
|
|
550
|
+
if (bytes.length !== Number(before.size) || atPath.isSymbolicLink()
|
|
551
|
+
|| fields.some((field) => before[field] !== after[field] || after[field] !== atPath[field])) return false;
|
|
552
|
+
const observed = normalizeTaskContract(JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes)));
|
|
553
|
+
return observed?.taskRunId === normalized.taskRunId
|
|
554
|
+
&& JSON.stringify(observed) === JSON.stringify(normalized);
|
|
555
|
+
} finally {
|
|
556
|
+
fs.closeSync(descriptor);
|
|
557
|
+
}
|
|
558
|
+
} catch {
|
|
559
|
+
return false;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
527
563
|
export function listTaskContracts(cwd) {
|
|
528
564
|
const root = resolveLocalStatePath(cwd, tasksRoot(cwd), { label: "Task state directory" });
|
|
529
565
|
if (!fs.existsSync(root)) return [];
|
|
@@ -619,9 +655,9 @@ function gitHasHead(cwd) {
|
|
|
619
655
|
}
|
|
620
656
|
}
|
|
621
657
|
|
|
622
|
-
function workingTreeFilesForGitRoot(cwd, observeRename) {
|
|
623
|
-
if (!isGitWorkingTree(cwd)) return [];
|
|
624
|
-
const changed = gitHasHead(cwd)
|
|
658
|
+
function workingTreeFilesForGitRoot(cwd, observeRename, knownHead = null) {
|
|
659
|
+
if (knownHead === null && !isGitWorkingTree(cwd)) return [];
|
|
660
|
+
const changed = (knownHead ?? gitHasHead(cwd))
|
|
625
661
|
? changedPathsFromNameStatus(gitOutput(cwd, ["diff", "--name-status", "-z", "--find-renames", "--diff-filter=ACMRD", "HEAD", "--"]), observeRename)
|
|
626
662
|
: gitOutput(cwd, ["ls-files", "-z"]).split("\0").filter(Boolean);
|
|
627
663
|
const untracked = gitOutput(cwd, ["ls-files", "--others", "--exclude-standard", "-z"]).split("\0").filter(Boolean);
|
|
@@ -820,7 +856,7 @@ export function workingTreeSnapshot(cwd, options = {}) {
|
|
|
820
856
|
paths.forEach((file) => protectedAliases.add(file));
|
|
821
857
|
};
|
|
822
858
|
try {
|
|
823
|
-
const hasHead = gitHasHead(root.cwd); for (const file of workingTreeFilesForGitRoot(root.cwd, observeRename)) {
|
|
859
|
+
const hasHead = gitHasHead(root.cwd); for (const file of workingTreeFilesForGitRoot(root.cwd, observeRename, hasHead)) {
|
|
824
860
|
const projectPath = prefixedGitPath(root.prefix, file);
|
|
825
861
|
snapshot[projectPath] = streamedWorkingTreeFileDigest(root.cwd, file, hasHead, isProtectedProjectPath(projectPath) || protectedAliases.has(file) ? projectPath : null);
|
|
826
862
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** @param {Record<string, unknown>} trace */
|
|
2
|
+
export function validTerminalDisposition(trace) {
|
|
3
|
+
return trace.terminalDisposition === undefined
|
|
4
|
+
|| trace.terminalDisposition === "refused" && trace.outcome === "blocked";
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/** @param {Record<string, unknown>} trace @returns {"refused" | undefined} */
|
|
8
|
+
export function normalizeTerminalDisposition(trace) {
|
|
9
|
+
return trace.terminalDisposition === "refused" && trace.outcome === "blocked" ? "refused" : undefined;
|
|
10
|
+
}
|
|
@@ -11,7 +11,8 @@ import {
|
|
|
11
11
|
validateFailureClassification,
|
|
12
12
|
validateFailureEvidence
|
|
13
13
|
} from "./failure-types.ts";
|
|
14
|
-
import { isCurrentWorkingTreeDigest } from "./working-tree-digest.js";
|
|
14
|
+
import { isCurrentWorkingTreeDigest, WORKING_TREE_DIGEST_ALGORITHM } from "./working-tree-digest.js";
|
|
15
|
+
import { currentWorkspaceRevisionDigest, isWorkspaceRevisionDigest } from "./workspace-revision.js";
|
|
15
16
|
|
|
16
17
|
export const MAX_VERIFY_COMMANDS = 2;
|
|
17
18
|
export const MAX_VERIFY_COMMAND_CHARS = 900;
|
|
@@ -96,13 +97,18 @@ export function latestObservedVerification(evidence = []) {
|
|
|
96
97
|
return latest;
|
|
97
98
|
}
|
|
98
99
|
|
|
99
|
-
export function verificationEvidenceProvesStableTree(entry, digest) {
|
|
100
|
+
export function verificationEvidenceProvesStableTree(entry, digest, workspaceRevisionDigest) {
|
|
101
|
+
const revisionRequired = workspaceRevisionDigest !== undefined
|
|
102
|
+
|| entry?.preWorkspaceRevisionDigest !== undefined || entry?.workspaceRevisionDigest !== undefined;
|
|
100
103
|
return isCurrentWorkingTreeDigest(digest)
|
|
101
104
|
&& entry?.observed === true
|
|
102
105
|
&& entry.matchedProfileCommand === true
|
|
103
106
|
&& entry.exitCode === 0
|
|
107
|
+
&& entry.isError !== true
|
|
104
108
|
&& entry.preWorkingTreeDigest === digest
|
|
105
|
-
&& entry.workingTreeDigest === digest
|
|
109
|
+
&& entry.workingTreeDigest === digest
|
|
110
|
+
&& (!revisionRequired || (isWorkspaceRevisionDigest(workspaceRevisionDigest)
|
|
111
|
+
&& entry.preWorkspaceRevisionDigest === workspaceRevisionDigest && entry.workspaceRevisionDigest === workspaceRevisionDigest));
|
|
106
112
|
}
|
|
107
113
|
|
|
108
114
|
export function verificationRunIdentity(cwd, command, changedFiles = []) {
|
|
@@ -116,6 +122,24 @@ export function verificationRunIdentity(cwd, command, changedFiles = []) {
|
|
|
116
122
|
.digest("hex");
|
|
117
123
|
}
|
|
118
124
|
|
|
125
|
+
export function verificationEvidenceProvesCurrentWorkspace(entry, digest, cwd) {
|
|
126
|
+
return verificationEvidenceProvesStableTree(entry, digest, currentWorkspaceRevisionDigest(cwd));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** Historical projections are readable; they do not grant runtime completion/reuse. */
|
|
130
|
+
export function verificationProjectionWorkspaceRevision(task, options = {}) {
|
|
131
|
+
return options.workspaceRevisionDigest !== undefined ? options.workspaceRevisionDigest
|
|
132
|
+
: task?.verifyEvidence?.some((entry) => entry.preWorkspaceRevisionDigest !== undefined || entry.workspaceRevisionDigest !== undefined)
|
|
133
|
+
? currentWorkspaceRevisionDigest(options.cwd) : undefined;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function allConfiguredVerifierEvidenceCurrent(task, digest, workspaceRevisionDigest) {
|
|
137
|
+
if (task?.workingTreeDigestAlgorithm !== WORKING_TREE_DIGEST_ALGORITHM || !isCurrentWorkingTreeDigest(digest)) return false;
|
|
138
|
+
const commands = meaningfulVerificationCommands(task?.verifyCommands ?? []);
|
|
139
|
+
const latest = latestObservedVerificationEvidence(task?.verifyEvidence);
|
|
140
|
+
return commands.length > 0 && commands.every((command) => verificationEvidenceProvesStableTree(latest.get(command.trim()), digest, workspaceRevisionDigest));
|
|
141
|
+
}
|
|
142
|
+
|
|
119
143
|
const STRUCTURED_SIGNALS = {
|
|
120
144
|
"scope-violation": "structured-scope",
|
|
121
145
|
"protected-path": "structured-protected-path",
|
|
@@ -125,7 +149,8 @@ const STRUCTURED_SIGNALS = {
|
|
|
125
149
|
environment: "structured-environment",
|
|
126
150
|
"flaky-infrastructure": "structured-flaky-infrastructure",
|
|
127
151
|
"stale-verifier": "structured-stale-verifier",
|
|
128
|
-
"missing-verifier": "structured-missing-verifier"
|
|
152
|
+
"missing-verifier": "structured-missing-verifier",
|
|
153
|
+
"verification-gap": "structured-verification-gap"
|
|
129
154
|
};
|
|
130
155
|
|
|
131
156
|
function parsedSignals(text, exitCode, structuredEvents) {
|
|
@@ -189,6 +214,7 @@ function categoryForEvidence(evidence) {
|
|
|
189
214
|
if (signals.has("structured-provider") || signals.has("provider-rate-limit") || signals.has("provider-transport")) return "provider-network";
|
|
190
215
|
if (signals.has("structured-environment") || signals.has("environment-diagnostic")) return "environment";
|
|
191
216
|
if (signals.has("structured-flaky-infrastructure") || signals.has("local-port-conflict") || signals.has("transient-infrastructure")) return "flaky-infrastructure";
|
|
217
|
+
if (signals.has("structured-verification-gap")) return "unknown";
|
|
192
218
|
if (signals.has("structured-stale-verifier") || signals.has("structured-missing-verifier") || signals.has("dependency-config-diagnostic")) return "dependency-config";
|
|
193
219
|
if (["typescript-diagnostic", "python-type-diagnostic", "go-compile-diagnostic", "rust-compile-diagnostic", "generic-compile-diagnostic"].some((signal) => signals.has(signal))) return "compile-typecheck";
|
|
194
220
|
if (signals.has("test-assertion-diagnostic")) return "test-assertion";
|
|
@@ -250,16 +276,42 @@ export function classifyCompletionGateFailure(missing = [], summary = "", exitCo
|
|
|
250
276
|
});
|
|
251
277
|
}
|
|
252
278
|
if (missingItems.some((item) => /^critical acceptance evidence\b/i.test(item))) {
|
|
253
|
-
|
|
279
|
+
// A missing proof is not an observed assertion failure. In particular,
|
|
280
|
+
// analyzer abstention cannot fabricate source-repair eligibility.
|
|
281
|
+
return classifyVerificationFailure("Completion gate lacks required behavioral verification evidence.", 1, {
|
|
282
|
+
structuredEvents: ["verification-gap"]
|
|
283
|
+
});
|
|
254
284
|
}
|
|
255
285
|
return classifyRecordedVerificationFailure(summary, exitCode);
|
|
256
286
|
}
|
|
257
287
|
|
|
258
288
|
export function selectCompletionRecoveryClassification(recordedClassification, missing = [], summary = "", exitCode = 1) {
|
|
259
289
|
const gateClassification = classifyCompletionGateFailure(missing, summary, exitCode);
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
290
|
+
if (gateClassification.category === "scope-protected-path" || exitCode === 0) return gateClassification;
|
|
291
|
+
try { return recordedClassification ? validateFailureClassification(recordedClassification) : gateClassification; }
|
|
292
|
+
catch { return gateClassification; }
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/** Reuse a checkpoint classification only for the exact current failed run. */
|
|
296
|
+
export function recordedFailureForObservation(checkpoints, observed, currentTreeDigest, workspaceRevisionDigest) {
|
|
297
|
+
if (observed?.observed !== true || observed.matchedProfileCommand !== true || observed.exitCode === 0
|
|
298
|
+
|| !isCurrentWorkingTreeDigest(observed.preWorkingTreeDigest) || observed.preWorkingTreeDigest !== observed.workingTreeDigest
|
|
299
|
+
|| (currentTreeDigest !== undefined && currentTreeDigest !== observed.workingTreeDigest)) return undefined;
|
|
300
|
+
const revisionRequired = workspaceRevisionDigest !== undefined || observed.preWorkspaceRevisionDigest !== undefined || observed.workspaceRevisionDigest !== undefined;
|
|
301
|
+
if (revisionRequired && (!isWorkspaceRevisionDigest(workspaceRevisionDigest)
|
|
302
|
+
|| observed.preWorkspaceRevisionDigest !== workspaceRevisionDigest || observed.workspaceRevisionDigest !== workspaceRevisionDigest)) return undefined;
|
|
303
|
+
const observedAt = observed.observedAt ?? observed.recordedAt;
|
|
304
|
+
if (typeof observedAt !== "string" || !Number.isFinite(Date.parse(observedAt))) return undefined;
|
|
305
|
+
const checkpoint = (Array.isArray(checkpoints) ? checkpoints : []).filter((item) => {
|
|
306
|
+
const binding = item?.evidence?.verificationObservation;
|
|
307
|
+
return item?.phase === "verify" && item.status === "failed" && binding
|
|
308
|
+
&& binding.command === observed.command?.trim() && binding.observedAt === observedAt
|
|
309
|
+
&& binding.exitCode === observed.exitCode && binding.preWorkingTreeDigest === observed.preWorkingTreeDigest
|
|
310
|
+
&& binding.workingTreeDigest === observed.workingTreeDigest
|
|
311
|
+
&& (!revisionRequired || (binding.preWorkspaceRevisionDigest === workspaceRevisionDigest && binding.workspaceRevisionDigest === workspaceRevisionDigest));
|
|
312
|
+
}).at(-1);
|
|
313
|
+
try { return checkpoint ? validateFailureClassification(checkpoint.evidence.failureClassification) : undefined; }
|
|
314
|
+
catch { return undefined; }
|
|
263
315
|
}
|
|
264
316
|
|
|
265
317
|
export function chooseVerificationScope(profileVerifyCommands = {}, changedFiles = []) {
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
export const WORKFLOW_IDS = [
|
|
2
|
+
"task",
|
|
3
|
+
"scout",
|
|
4
|
+
"be-to-fe",
|
|
5
|
+
"discuss",
|
|
6
|
+
"plan",
|
|
7
|
+
"review",
|
|
8
|
+
"commit",
|
|
9
|
+
"pr",
|
|
10
|
+
"onboard",
|
|
11
|
+
"platform-improve"
|
|
12
|
+
] as const;
|
|
13
|
+
|
|
14
|
+
export type WorkflowId = typeof WORKFLOW_IDS[number];
|
|
15
|
+
export type ContextWorkflow = "task" | "scout" | "discuss" | "plan" | "review" | "release" | "onboard"
|
|
16
|
+
| "usage" | "permission" | "context";
|
|
17
|
+
|
|
18
|
+
export type WorkflowOption = {
|
|
19
|
+
id: WorkflowId;
|
|
20
|
+
aliases: readonly string[];
|
|
21
|
+
label: string;
|
|
22
|
+
description: string;
|
|
23
|
+
argumentHint: string;
|
|
24
|
+
requestRequired: boolean;
|
|
25
|
+
contextWorkflow: ContextWorkflow;
|
|
26
|
+
changeMode: "source-change" | "read-only" | "plan-only" | "clarification" | "git" | "onboarding" | "platform";
|
|
27
|
+
modelUse: "required";
|
|
28
|
+
recommendedFreshSession: boolean;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/** Surface-neutral workflow truth shared by context classification and runtime ingress. */
|
|
32
|
+
export const WORKFLOW_OPTIONS: readonly WorkflowOption[] = [
|
|
33
|
+
{ id: "task", aliases: ["task", "implement"], label: "Task", description: "Implement a bounded task", argumentHint: "<request>", requestRequired: true, contextWorkflow: "task", changeMode: "source-change", modelUse: "required", recommendedFreshSession: true },
|
|
34
|
+
{ id: "scout", aliases: ["scout", "audit"], label: "Scout", description: "Read-only audit or research", argumentHint: "<area/spec/risk>", requestRequired: true, contextWorkflow: "scout", changeMode: "read-only", modelUse: "required", recommendedFreshSession: true },
|
|
35
|
+
{ id: "be-to-fe", aliases: ["be-to-fe", "befe"], label: "BE → FE", description: "Implement frontend from a backend contract", argumentHint: "<BE spec/change + FE outcome>", requestRequired: true, contextWorkflow: "task", changeMode: "source-change", modelUse: "required", recommendedFreshSession: true },
|
|
36
|
+
{ id: "discuss", aliases: ["discuss", "clarify"], label: "Discuss", description: "Clarify before planning or editing", argumentHint: "<rough idea>", requestRequired: true, contextWorkflow: "discuss", changeMode: "clarification", modelUse: "required", recommendedFreshSession: false },
|
|
37
|
+
{ id: "plan", aliases: ["plan"], label: "Plan", description: "Create an implementation plan", argumentHint: "<goal>", requestRequired: true, contextWorkflow: "plan", changeMode: "plan-only", modelUse: "required", recommendedFreshSession: false },
|
|
38
|
+
{ id: "review", aliases: ["review"], label: "Review", description: "Review a diff or source read-only", argumentHint: "<target or diff>", requestRequired: true, contextWorkflow: "review", changeMode: "read-only", modelUse: "required", recommendedFreshSession: false },
|
|
39
|
+
{ id: "commit", aliases: ["commit"], label: "Commit", description: "Run the guarded local commit workflow", argumentHint: "[message]", requestRequired: false, contextWorkflow: "release", changeMode: "git", modelUse: "required", recommendedFreshSession: false },
|
|
40
|
+
{ id: "pr", aliases: ["pr"], label: "PR", description: "Prepare a guarded pull request", argumentHint: "[title]", requestRequired: false, contextWorkflow: "release", changeMode: "git", modelUse: "required", recommendedFreshSession: false },
|
|
41
|
+
{ id: "onboard", aliases: ["onboard", "onboard-project"], label: "Onboard", description: "Run first-read project onboarding", argumentHint: "[focus]", requestRequired: false, contextWorkflow: "onboard", changeMode: "onboarding", modelUse: "required", recommendedFreshSession: true },
|
|
42
|
+
{ id: "platform-improve", aliases: ["platform-improve", "platform"], label: "Platform improve", description: "Improve Pi Agent Platform itself", argumentHint: "<goal + affected area>", requestRequired: true, contextWorkflow: "task", changeMode: "platform", modelUse: "required", recommendedFreshSession: true }
|
|
43
|
+
] as const;
|
|
44
|
+
|
|
45
|
+
export const WORKFLOW_ALIASES: Readonly<Record<string, WorkflowId>> = Object.freeze(Object.fromEntries(
|
|
46
|
+
WORKFLOW_OPTIONS.flatMap((option) => option.aliases.map((alias) => [alias, option.id] as const))
|
|
47
|
+
));
|
|
48
|
+
|
|
49
|
+
export function resolveWorkflowId(value: unknown): WorkflowId | null {
|
|
50
|
+
if (typeof value !== "string") return null;
|
|
51
|
+
return WORKFLOW_ALIASES[value.trim().toLowerCase()] ?? null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function workflowOption(value: unknown): WorkflowOption | null {
|
|
55
|
+
const id = resolveWorkflowId(value);
|
|
56
|
+
return id ? WORKFLOW_OPTIONS.find((option) => option.id === id) ?? null : null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function workflowCommandNames(options: { aliases?: boolean } = {}): string[] {
|
|
60
|
+
return options.aliases === false ? [...WORKFLOW_IDS] : Object.keys(WORKFLOW_ALIASES);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function escapedPattern(value: string): string {
|
|
64
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** A regex fragment derived from the catalog, for command/projection boundaries. */
|
|
68
|
+
export function workflowCommandPattern(options: { aliases?: boolean } = {}): string {
|
|
69
|
+
return workflowCommandNames(options).sort((left, right) => right.length - left.length)
|
|
70
|
+
.map(escapedPattern).join("|");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const NAMESPACED_WORKFLOW_COMMAND = new RegExp(
|
|
74
|
+
`^/(?:piagent-workflow|workflow)\\s+(${workflowCommandPattern()})(?=\\s|$)\\s*`, "i"
|
|
75
|
+
);
|
|
76
|
+
const DIRECT_WORKFLOW_COMMAND = new RegExp(
|
|
77
|
+
`^/(${workflowCommandPattern({ aliases: false })})(?=\\s|$)\\s*`, "i"
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
export function workflowIdFromCommand(input: unknown): WorkflowId | null {
|
|
81
|
+
const normalized = String(input ?? "").trim();
|
|
82
|
+
const match = NAMESPACED_WORKFLOW_COMMAND.exec(normalized) ?? DIRECT_WORKFLOW_COMMAND.exec(normalized);
|
|
83
|
+
return resolveWorkflowId(match?.[1]);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function stripWorkflowCommand(input: string): string {
|
|
87
|
+
return String(input ?? "").replace(NAMESPACED_WORKFLOW_COMMAND, "").replace(DIRECT_WORKFLOW_COMMAND, "").trim();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function workflowHelpLines(): string[] {
|
|
91
|
+
const aliasLines = WORKFLOW_OPTIONS.flatMap((option) => option.aliases.filter((alias) => alias !== option.id)
|
|
92
|
+
.map((alias) => `/workflow ${alias} → ${option.id}`));
|
|
93
|
+
return [
|
|
94
|
+
"namespace: /workflow",
|
|
95
|
+
...WORKFLOW_OPTIONS.map((option) => `${option.id}: /workflow ${option.id} ${option.argumentHint} — ${option.description}`),
|
|
96
|
+
`aliases: ${aliasLines.join(" | ") || "none"}`
|
|
97
|
+
];
|
|
98
|
+
}
|