@piagent/platform 1.6.0 → 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 +104 -0
- package/README.md +24 -15
- package/README.vi.md +36 -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 +27 -3
- package/benchmarks/production-v1/suite.json +5 -1
- 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 +16 -16
- package/docs/authority-manifest.md +1 -1
- package/docs/auto-delegation-policy.md +38 -73
- 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 +30 -35
- package/docs/context-engine.md +5 -3
- package/docs/context-window-policy.md +37 -1
- package/docs/distribution-standard.md +9 -9
- package/docs/en/architecture.md +26 -13
- package/docs/languages.json +4 -4
- package/docs/operator-manual-vietnamese.md +26 -46
- 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 +7 -0
- package/docs/quality-benchmark.md +299 -23
- 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/runtime-harness-standard.md +3 -3
- package/docs/security-threat-model.md +1 -1
- package/docs/subagent-orchestration-capabilities.md +19 -51
- package/docs/subagents-and-multiagent.md +21 -47
- package/docs/task-implementation-contract.md +3 -3
- package/docs/task-lifecycle-vietnamese.md +1 -1
- package/docs/team-onboarding.md +7 -7
- package/docs/third-party-neutrality.md +7 -0
- package/docs/usage-observability.md +1 -1
- package/docs/vi/architecture.md +26 -13
- package/docs-site/architecture.html +1 -1
- package/docs-site/benchmark.html +89 -95
- package/docs-site/commands.html +1 -1
- package/docs-site/content/benchmark.html +88 -94
- package/docs-site/content/en/benchmark.html +134 -90
- package/docs-site/content/en/index.html +19 -19
- package/docs-site/content/en/runtime.html +5 -5
- package/docs-site/content/en/whats-new.html +23 -1
- package/docs-site/content/en/workflows.html +2 -2
- package/docs-site/content/index.html +19 -19
- package/docs-site/content/runtime.html +6 -6
- package/docs-site/content/whats-new.html +23 -1
- package/docs-site/content/workflows.html +2 -2
- package/docs-site/context-engine.html +1 -1
- package/docs-site/en/architecture.html +1 -1
- package/docs-site/en/benchmark.html +135 -91
- package/docs-site/en/commands.html +1 -1
- package/docs-site/en/context-engine.html +1 -1
- package/docs-site/en/index.html +20 -20
- 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 +6 -6
- 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 +24 -2
- package/docs-site/en/workflows.html +3 -3
- package/docs-site/index.html +20 -20
- 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 +7 -7
- 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 +24 -2
- package/docs-site/workflows.html +3 -3
- 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-assurance-evidence.invalid.json +1 -1
- package/evals/fixtures/benchmark-assurance-evidence.valid.json +1 -1
- 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/codex-relative-efficiency-v1.invalid.json +4 -0
- package/evals/fixtures/codex-relative-efficiency-v1.valid.json +94 -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/helper-request.invalid.json +1 -1
- package/evals/fixtures/helper-request.valid.json +1 -1
- package/evals/fixtures/host-contract-plan.invalid.json +42 -0
- package/evals/fixtures/host-contract-plan.valid.json +41 -0
- package/evals/fixtures/piagent-webui/subagent-tree-v1.valid.json +7 -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/fixtures/task-authority-snapshot.valid.json +4 -4
- package/evals/fs4-readiness-matrix.v1.json +2 -2
- 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 +10 -6
- package/evals/fs5-pilot-protocol.v1.json +3 -3
- package/evals/fs5-pilot-protocol.v2.json +8 -8
- package/evals/fs5-pilot-protocol.v3.json +8 -8
- package/evals/fs5-pilot-protocol.v4.json +7 -7
- package/evals/fs5-pilot-protocol.v5.json +10 -8
- 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.v1.json +1 -1
- package/evals/private-holdout-v1/public-exposure.v2.json +273 -0
- package/evals/runtime-conformance-v1/README.md +43 -0
- package/evals/runtime-conformance-v1/evaluate-paid-canary.mjs +198 -0
- package/evals/runtime-conformance-v1/lane.json +57 -0
- package/evals/runtime-conformance-v1/paid-canary.json +31 -0
- package/evals/runtime-conformance-v1/runner.mjs +456 -0
- package/package.json +9 -4
- package/packages/piagent-core/README.md +15 -6
- 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 +699 -0
- 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 +111 -110
- 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 +67 -52
- 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 +70 -7
- 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 +462 -0
- 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 +343 -8
- package/packages/piagent-core/benchmark/benchmark-release-claim-controls.js +132 -0
- package/packages/piagent-core/benchmark/benchmark-report.js +94 -5
- 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-causal.js +244 -0
- 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 +246 -33
- 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 +232 -4
- package/packages/piagent-core/benchmark/benchmark-summary-support.js +33 -1
- 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 +410 -37
- 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 +6 -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 +1000 -0
- 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 +208 -180
- 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 +12 -17
- package/packages/piagent-core/extensions/context-index-policy.js +4 -0
- package/packages/piagent-core/extensions/context-query-paths.js +57 -0
- package/packages/piagent-core/extensions/criterion-context-pack.js +109 -4
- package/packages/piagent-core/extensions/criterion-graph.js +4 -1
- package/packages/piagent-core/extensions/failure-types.ts +2 -2
- package/packages/piagent-core/extensions/fallback-base-policy.ts +101 -0
- package/packages/piagent-core/extensions/guard-types.ts +9 -1
- package/packages/piagent-core/extensions/piagent-guard.ts +374 -364
- 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-lifecycle.js +32 -0
- package/packages/piagent-core/extensions/task-runtime-audit.js +8 -2
- package/packages/piagent-core/extensions/task-state.js +140 -43
- 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 +109 -20
- package/packages/piagent-core/extensions/workflow-catalog.ts +98 -0
- package/packages/piagent-core/extensions/workspace-evidence-roots.js +52 -16
- 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 +43 -2
- package/packages/piagent-core/policy/authority-manifest.v1.json +3 -3
- package/packages/piagent-core/prompts/be-to-fe.md +2 -8
- package/packages/piagent-core/prompts/plan.md +1 -1
- package/packages/piagent-core/prompts/platform-improve.md +2 -6
- package/packages/piagent-core/prompts/review.md +2 -7
- package/packages/piagent-core/prompts/scout.md +1 -1
- package/packages/piagent-core/prompts/task.md +4 -3
- 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 +83 -89
- package/packages/piagent-core/runtime/hooks/input-hook.ts +98 -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 +150 -19
- package/packages/piagent-core/runtime/hooks/tool-result-hook.ts +111 -92
- 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/hooks/tool-result-value-helpers.ts +66 -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/bounded-emission-guard.ts +286 -0
- package/packages/piagent-core/runtime/inspection/runtime-event-store.ts +37 -7
- 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/task-subagent-tree.ts +27 -4
- package/packages/piagent-core/runtime/inspection/tool-failure-classification.ts +69 -11
- package/packages/piagent-core/runtime/inspection/webui-snapshot.ts +104 -22
- 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/orchestration/helper-lifecycle.ts +16 -12
- package/packages/piagent-core/runtime/orchestration/minimal-delegation-policy.ts +71 -0
- package/packages/piagent-core/runtime/orchestration/owned-work-budget.ts +28 -20
- package/packages/piagent-core/runtime/orchestration/role-policy.ts +27 -9
- package/packages/piagent-core/runtime/orchestration/subagent-tool-policy.ts +329 -0
- package/packages/piagent-core/runtime/policy/block-remedy.ts +0 -4
- 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 +15 -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/edit-freshness-guard.ts +102 -0
- package/packages/piagent-core/runtime/quality/exact-output-contract.ts +20 -10
- package/packages/piagent-core/runtime/quality/performance-assurance.ts +3 -3
- 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 +12 -3
- package/packages/piagent-core/runtime/recovery/diagnostic-delivery.ts +61 -0
- package/packages/piagent-core/runtime/recovery/handoff-projection.ts +196 -58
- 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/pristine-task-policy-refresh.ts +91 -0
- package/packages/piagent-core/runtime/recovery/recovery-policy.ts +31 -40
- package/packages/piagent-core/runtime/recovery/resume-state.ts +120 -19
- package/packages/piagent-core/runtime/recovery/semantic-repair-handshake.ts +7 -13
- package/packages/piagent-core/runtime/recovery/task-evidence-coverage-refresh.ts +217 -0
- package/packages/piagent-core/runtime/registration/activity-inspector-command.ts +2 -1
- package/packages/piagent-core/runtime/registration/context-commands.ts +28 -10
- package/packages/piagent-core/runtime/registration/knowledge-tools.ts +9 -5
- package/packages/piagent-core/runtime/registration/operator-catalogs.ts +4 -9
- package/packages/piagent-core/runtime/registration/operator-request-intake.ts +49 -0
- package/packages/piagent-core/runtime/registration/policy-tools.ts +8 -6
- package/packages/piagent-core/runtime/registration/session-commands.ts +10 -8
- package/packages/piagent-core/runtime/registration/session-wait-tool.ts +54 -0
- package/packages/piagent-core/runtime/registration/task-completion-tools.ts +39 -20
- package/packages/piagent-core/runtime/registration/task-evidence-tools.ts +21 -12
- package/packages/piagent-core/runtime/registration/task-start-conditional-mutation.ts +45 -0
- package/packages/piagent-core/runtime/registration/task-start-guidance.ts +24 -15
- package/packages/piagent-core/runtime/registration/task-start-manifest.ts +54 -0
- package/packages/piagent-core/runtime/registration/task-start-tool.ts +79 -79
- package/packages/piagent-core/runtime/registration/workflow-commands.ts +64 -93
- package/packages/piagent-core/runtime/runtime-limits.ts +16 -2
- package/packages/piagent-core/runtime/session/adaptive-context-analysis.ts +461 -0
- package/packages/piagent-core/runtime/session/adaptive-context-governor.ts +464 -0
- package/packages/piagent-core/runtime/session/adaptive-context-ledger.ts +265 -0
- package/packages/piagent-core/runtime/session/completion-signals.ts +23 -0
- package/packages/piagent-core/runtime/session/message-signals.ts +6 -18
- package/packages/piagent-core/runtime/session/operator-request-carry.ts +44 -0
- package/packages/piagent-core/runtime/session/retrieval-evidence-runtime.ts +188 -0
- package/packages/piagent-core/runtime/session/runtime-state.ts +37 -39
- package/packages/piagent-core/runtime/session/source-checkout-read-grants.ts +35 -0
- package/packages/piagent-core/runtime/session/system-prompt.ts +76 -14
- package/packages/piagent-core/runtime/session/task-contract-presentation.ts +39 -0
- 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 +10 -9
- package/packages/piagent-core/runtime/tools/session-wait.ts +42 -0
- package/packages/piagent-core/runtime/tools/tool-groups.ts +22 -5
- 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 +101 -0
- 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 +201 -0
- package/packages/piagent-core/runtime/workflows/task-followup-policy.ts +163 -0
- package/packages/piagent-core/runtime/workflows/task-intake.ts +276 -169
- 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-core/subagents/piagent-oracle.md +5 -3
- package/packages/piagent-core/subagents/piagent-planner.md +6 -4
- package/packages/piagent-core/subagents/piagent-reviewer.md +5 -3
- package/packages/piagent-core/subagents/piagent-scout.md +4 -2
- package/packages/piagent-core/subagents/piagent-worker.md +6 -4
- package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-CxeZqTte.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 +13 -3
- package/packages/piagent-webui/extension/review-controller.ts +29 -6
- package/packages/piagent-webui/extension/same-session-bridge.ts +7 -8
- package/packages/piagent-webui/extension/session-stream-adapter.ts +88 -16
- 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 +170 -32
- 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-lifecycle.ts +237 -0
- package/packages/piagent-webui/gateway/session-operation-retry-control.ts +38 -0
- package/packages/piagent-webui/gateway/session-operation-settlement.ts +28 -0
- package/packages/piagent-webui/gateway/session-operation-watchdog.ts +9 -2
- 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 +118 -117
- package/packages/piagent-webui/ownership/session-lease-store.ts +5 -2
- package/packages/piagent-webui/server/core-inspection-provider.ts +75 -15
- 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 +150 -11
- 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/codex-relative-efficiency-v1.schema.json +155 -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 +46 -5
- 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/subagent-tree-v1.schema.json +11 -1
- package/schemas/piagent-webui/transcript-v1.schema.json +2 -1
- package/schemas/project-profile.schema.json +1 -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 +45 -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 +224 -387
- package/scripts/benchmark-runner-finalization.mjs +144 -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/configure-subagents.sh +42 -34
- package/scripts/fs4-readiness-evaluation.mjs +7 -1
- package/scripts/helper-evaluation.mjs +1 -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/team-doctor.sh +1 -1
- package/scripts/typescript-loader.mjs +135 -1
- package/scripts/update-global.mjs +6 -7
- package/scripts/verify-local.sh +41 -55
- package/scripts/verify-release-identity.mjs +5 -3
- package/packages/piagent-webui/dist/client/assets/index-DynIMe8I.js +0 -176
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { observedFocusedTestSummary, retainFocusedVerification, unresolvedFocusedVerification } from "./acceptance-focused-verification.js";
|
|
1
2
|
import fs from "node:fs";
|
|
2
3
|
import os from "node:os";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import crypto from "node:crypto";
|
|
5
6
|
import { execFileSync } from "node:child_process";
|
|
6
7
|
import { fileURLToPath } from "node:url";
|
|
8
|
+
import { apiBaselineCriterionEvidence as apiBaselineEvidence } from "../runtime/verification/acceptance-api-baseline.js";
|
|
7
9
|
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
8
10
|
import { StringEnum } from "@earendil-works/pi-ai";
|
|
9
11
|
import { Type } from "typebox";
|
|
@@ -17,6 +19,7 @@ import {
|
|
|
17
19
|
unresolvedExpansionReason
|
|
18
20
|
} from "./shell-reach.ts";
|
|
19
21
|
import { extractShellWritePathCandidates, shellHasFileWriteRedirection } from "./shell-write-targets.js";
|
|
22
|
+
import { isProjectMutatingShellCommand, isReadOnlyTaskShellCommand } from "./readonly-inline-inspection.ts";
|
|
20
23
|
import { commandMatchesVerifyPlan, createBashResultLedger, findMatchingObservedBashResult, readObservedBashResults } from "./runtime-evidence.js";
|
|
21
24
|
import { findPackageRoot, findPlatformRoot, readJsonFile } from "./guard-io.js";
|
|
22
25
|
import {
|
|
@@ -67,28 +70,25 @@ import {
|
|
|
67
70
|
} from "./context-index-policy.js";
|
|
68
71
|
import {
|
|
69
72
|
DEFAULT_MAX_TASK_ATTEMPTS, activeSessionTask, bindSessionTask, createTaskRunId, hasGitEvidenceRoot, listTaskContracts,
|
|
70
|
-
|
|
73
|
+
priorTaskAttempts, repositoryFileManifest, repositoryFileManifestDetails, resolveTaskContract, safeTaskId, summarizeAttempt, taskContractValidationErrors, taskDigestMigrationArchiveStatus,
|
|
71
74
|
workPlanDependencyError, workingTreeSnapshot, workingTreeSnapshotHasUnavailableEvidence, writeTaskContract
|
|
72
75
|
} from "./task-state.js";
|
|
73
|
-
import { classifyRecordedVerificationFailure, classifyVerificationFailure, latestObservedVerification, meaningfulVerificationCommands, selectCompletionRecoveryClassification, selectVerificationPlan } from "./verification-intelligence.js";
|
|
76
|
+
import { classifyRecordedVerificationFailure, classifyVerificationFailure, latestObservedVerification, meaningfulVerificationCommands, recordedFailureForObservation, selectCompletionRecoveryClassification, selectVerificationPlan } from "./verification-intelligence.js";
|
|
74
77
|
import { executionBackendToolDecision } from "./execution-backend.js";
|
|
75
78
|
import { replayTaskCheckpoints } from "./task-journal.js";
|
|
76
79
|
import type { FailureClassification } from "./failure-types.ts";
|
|
77
80
|
import { recordCompletionAudit, recordMutationCheckpoint, recordTaskProgressCheckpoints, recordTaskStartCheckpoint, recordVerificationCheckpoint } from "./task-runtime-audit.js";
|
|
78
81
|
import {
|
|
79
|
-
applyAcceptanceRecoveryProvenance,
|
|
80
|
-
|
|
81
|
-
acceptanceProofGuidance,
|
|
82
|
-
acceptanceSemanticConflicts,
|
|
83
|
-
buildAcceptanceReceipt,
|
|
84
|
-
invalidateAcceptanceReceiptAfterMutation,
|
|
85
|
-
refreshAcceptanceReceipt
|
|
82
|
+
applyAcceptanceRecoveryProvenance, acceptanceBaselineGuidance, acceptanceProofGuidance, acceptanceSemanticConflicts,
|
|
83
|
+
buildAcceptanceReceipt, invalidateAcceptanceReceiptAfterMutation, refreshAcceptanceReceipt
|
|
86
84
|
} from "./acceptance-receipt.js";
|
|
87
85
|
import { acceptanceLanguageAdapterForPath, isAcceptanceTestPath } from "./acceptance-language-adapters.js";
|
|
88
86
|
import { allVerifyCommandsPassCurrentTree, changedSnapshotFiles, compactTaskDetails, mergeObservedTaskContext, passingVerifyCommandsForDigest, taskDeltaFilesFromSnapshot } from "./task-contract-view.js";
|
|
89
87
|
import { applyRuntimeLifecycleObservation, runtimeLifecycleMode, workingTreeEvidenceDigest } from "./task-lifecycle.js";
|
|
90
88
|
import { completeTaskDigestRefresh } from "./task-digest-migration.js";
|
|
91
89
|
import { WORKING_TREE_DIGEST_ALGORITHM, isCurrentWorkingTreeDigest, workingTreeObservation, workingTreeSnapshotUsesCurrentAlgorithm } from "./working-tree-digest.js";
|
|
90
|
+
import { currentWorkspaceRevisionDigest } from "./workspace-revision.js";
|
|
91
|
+
import { captureWorkspaceVerificationSnapshot } from "./workspace-verification-snapshot.js";
|
|
92
92
|
import { appendJsonlBounded } from "./state-retention.js";
|
|
93
93
|
import { ensurePrivateStateDirectory, resolveLocalStatePath } from "./local-state-path.js";
|
|
94
94
|
import { hasDurableContextEvidence } from "./context-evidence.js";
|
|
@@ -104,12 +104,17 @@ import {
|
|
|
104
104
|
import { cleanSessionNameInput, currentSessionName, hasOperatorSessionName } from "../runtime/session/message-signals.ts";
|
|
105
105
|
import { buildSemanticCompactionInstructions } from "../runtime/session/system-prompt.ts";
|
|
106
106
|
import { buildContextPreflight, buildUsageSnapshot, formatContextPreflight, formatCount, formatPercent, formatUsageSnapshot } from "../runtime/session/usage.ts";
|
|
107
|
+
import { registerTaskUsageHooks } from "../runtime/product/task-usage-hooks.ts";
|
|
107
108
|
import {
|
|
108
109
|
formatToolResultCaptureStatus,
|
|
109
110
|
readRecentToolResultCaptures
|
|
110
111
|
} from "../runtime/session/tool-result-compaction.ts";
|
|
111
112
|
import { RuntimeSessionState } from "../runtime/session/runtime-state.ts";
|
|
112
113
|
import type { ObservedTaskContext } from "../runtime/session/runtime-state.ts";
|
|
114
|
+
import { reuseCurrentTreeExactVerifier } from "../runtime/verification/exact-verifier-reuse.ts";
|
|
115
|
+
import { IndependentAcceptanceRuntime } from "../runtime/verification/independent-acceptance-runtime.ts";
|
|
116
|
+
import { independentAcceptanceState } from "./acceptance-independent-registry.js";
|
|
117
|
+
import { independentVerificationRecovery } from "../runtime/recovery/independent-verification-recovery.ts";
|
|
113
118
|
import {
|
|
114
119
|
PIAGENT_TOOL_GROUPS,
|
|
115
120
|
PIAGENT_TOOL_NAMES,
|
|
@@ -118,6 +123,7 @@ import {
|
|
|
118
123
|
} from "../runtime/tools/tool-groups.ts";
|
|
119
124
|
import type { PiagentToolGroup } from "../runtime/tools/tool-groups.ts";
|
|
120
125
|
import { freshRequestParts, shortTaskLabel } from "../runtime/workflows/input-routing.ts";
|
|
126
|
+
import { completedFollowupAcceptanceEvidenceFiles } from "../runtime/workflows/task-followup-policy.ts";
|
|
121
127
|
import {
|
|
122
128
|
automaticAcceptanceCriteria,
|
|
123
129
|
automaticReviewLenses,
|
|
@@ -141,7 +147,8 @@ import { readRuntimeVersionMetadata, RuntimeSnapshotCapture } from "../runtime/m
|
|
|
141
147
|
import { recordRuntimeSnapshotTelemetry } from "../runtime/model/snapshot-telemetry.ts";
|
|
142
148
|
import { captureAuthenticatedModelCatalogFromContext } from "../runtime/model/authenticated-catalog.ts";
|
|
143
149
|
import { normalizeOpenAiCodexReasoningPayload } from "../runtime/model/openai-codex-reasoning.ts";
|
|
144
|
-
import { buildOpenAiCodexWireFingerprint } from "../runtime/model/provider-wire-fingerprint.ts";
|
|
150
|
+
import { buildOpenAiCodexWireFingerprint, measureProviderPayload } from "../runtime/model/provider-wire-fingerprint.ts";
|
|
151
|
+
import { registerFastModeCommand, ServiceTierRuntime } from "../runtime/model/service-tier-runtime.ts";
|
|
145
152
|
import { ModelRouteRuntime, readModelRouteEvents } from "../runtime/model/model-route-runtime.ts";
|
|
146
153
|
import { parentRoutingModeFromEnvironment, routingObjectiveFromEnvironment } from "../runtime/model/model-route-policy.ts";
|
|
147
154
|
import { ModelSelectionProvenanceTracker } from "../runtime/model/model-selection-provenance.ts";
|
|
@@ -155,17 +162,21 @@ import { PhaseToolRuntime, phaseToolModeFromEnvironment } from "../runtime/tools
|
|
|
155
162
|
import { parseApplyPatchTargets, registerApplyPatchTool } from "../runtime/tools/apply-patch-tool.ts";
|
|
156
163
|
import { authorityReplacementState, ensureTaskAuthorityResumePolicy } from "../runtime/policy/authority-resume-policy.ts";
|
|
157
164
|
import { taskAuthorityDecision } from "../runtime/policy/task-authority-runtime.ts";
|
|
158
|
-
import { selectRecoveryDecision } from "../runtime/recovery/recovery-policy.ts";
|
|
165
|
+
import { applyProofCapabilityHandoff, selectRecoveryDecision } from "../runtime/recovery/recovery-policy.ts";
|
|
159
166
|
import type { RecoveryDecision } from "../runtime/recovery/recovery-policy.ts";
|
|
160
167
|
import { inspectTaskResumeState } from "../runtime/recovery/resume-state.ts";
|
|
161
168
|
import { SemanticRepairRuntime } from "../runtime/recovery/semantic-repair-runtime.ts";
|
|
162
169
|
import { defaultRolePolicy } from "../runtime/orchestration/role-policy.ts";
|
|
163
170
|
import { helpersMode } from "../runtime/orchestration/helper-lifecycle.ts";
|
|
171
|
+
import { evaluateDirectSubagentDispatch, recordDirectSubagentResult, reserveDirectSubagentDispatch, taskHelperUsageMode } from "../runtime/orchestration/subagent-tool-policy.ts";
|
|
164
172
|
import { buildLiveTaskStatus, formatLiveTaskStatus } from "../runtime/product/operator-projections.ts";
|
|
165
173
|
import { buildTaskEfficiencyMetrics } from "../runtime/product/efficiency-metrics.ts";
|
|
166
174
|
import { performanceReviewToolDecision, performanceReviewToolKind } from "../runtime/quality/performance-assurance.ts";
|
|
167
175
|
import { expectedModelMutationProof } from "../runtime/quality/model-mutation-proof.ts";
|
|
176
|
+
import { EditFreshnessGuard, editFreshnessModeFromEnvironment } from "../runtime/quality/edit-freshness-guard.ts";
|
|
168
177
|
import { captureVerifierFileSnapshot } from "../runtime/inspection/verifier-snapshot-store.ts";
|
|
178
|
+
import { finalGateConfig } from "./acceptance-diagnostic-policy.ts";
|
|
179
|
+
import { fallbackBasePolicy } from "./fallback-base-policy.ts";
|
|
169
180
|
import { prefixCompletions, registerPiagentTool, registerRuntimeCommand, registerRuntimeTool } from "../runtime/registration/extension-registration.ts";
|
|
170
181
|
import { FRESH_COMMAND_ACTIONS, FRESH_COMMAND_HELP, ONBOARDING_COMMAND_ACTIONS, WORKFLOW_COMMAND_EXCLUSIONS } from "../runtime/registration/operator-catalogs.ts";
|
|
171
182
|
import { registerPiagentStatusCommand } from "../runtime/registration/runtime-model-status.ts";
|
|
@@ -197,7 +208,6 @@ import type {
|
|
|
197
208
|
ContextIndexSettings,
|
|
198
209
|
ExecPolicyConfig,
|
|
199
210
|
ExternalActionPolicyConfig,
|
|
200
|
-
FinalGateConfig,
|
|
201
211
|
MemorySettings,
|
|
202
212
|
OrchestrationMode,
|
|
203
213
|
OrchestrationPolicySettings,
|
|
@@ -232,7 +242,7 @@ type TaskStartParameters = {
|
|
|
232
242
|
riskLane: "tiny" | "normal" | "high-risk";
|
|
233
243
|
intakeMode?: "model" | "runtime";
|
|
234
244
|
changeMode?: "source-change" | "read-only";
|
|
235
|
-
mutationPolicy?: "required" | "forbidden";
|
|
245
|
+
mutationPolicy?: "required" | "allowed" | "forbidden";
|
|
236
246
|
verifyGroup?: string;
|
|
237
247
|
maxAttempts?: number;
|
|
238
248
|
expectedOutput: string;
|
|
@@ -293,7 +303,6 @@ const TECH_OPTIONS: TechOption[] = [
|
|
|
293
303
|
{ id: "node-typescript", label: "Node TypeScript", role: "runtime", description: "Node.js TypeScript library/tooling project.", context7Query: "typescript node.js", topics: ["typescript", "node", "testing"] },
|
|
294
304
|
{ id: "python", label: "Python", role: "runtime", description: "Python app/library runtime.", context7Query: "python", topics: ["packaging", "typing", "testing"] }
|
|
295
305
|
];
|
|
296
|
-
|
|
297
306
|
const PROFILE_TECH_ROLES: Record<string, TechRole[]> = {
|
|
298
307
|
"web-frontend": ["frontend", "database"],
|
|
299
308
|
"backend-api": ["backend", "database"],
|
|
@@ -307,7 +316,6 @@ const PROFILE_TECH_ROLES: Record<string, TechRole[]> = {
|
|
|
307
316
|
docs: ["docs"],
|
|
308
317
|
generic: ["runtime"]
|
|
309
318
|
};
|
|
310
|
-
|
|
311
319
|
const DEFAULT_MEMORY_SETTINGS: Required<MemorySettings> = {
|
|
312
320
|
enabled: true,
|
|
313
321
|
mode: "manual",
|
|
@@ -320,7 +328,6 @@ const DEFAULT_MEMORY_SETTINGS: Required<MemorySettings> = {
|
|
|
320
328
|
maxInjectedChars: 4000,
|
|
321
329
|
externalPackages: []
|
|
322
330
|
};
|
|
323
|
-
|
|
324
331
|
const DEFAULT_CONTEXT_INDEX_SETTINGS: Required<ContextIndexSettings> = {
|
|
325
332
|
enabled: true,
|
|
326
333
|
path: CONTEXT_INDEX_FILE,
|
|
@@ -331,21 +338,19 @@ const DEFAULT_CONTEXT_INDEX_SETTINGS: Required<ContextIndexSettings> = {
|
|
|
331
338
|
includeTechStack: true,
|
|
332
339
|
includeMemoryPointers: true
|
|
333
340
|
};
|
|
334
|
-
|
|
335
341
|
const DEFAULT_RUNTIME_POLICY: Required<RuntimePolicySettings> = {
|
|
336
342
|
execPolicy: "enforce",
|
|
337
343
|
contextBudget: "enforce",
|
|
338
344
|
toolRegistry: "advisory",
|
|
339
345
|
finalGate: "enforce"
|
|
340
346
|
};
|
|
341
|
-
|
|
342
347
|
const DEFAULT_ORCHESTRATION_POLICY: ResolvedOrchestrationPolicy = {
|
|
343
348
|
defaultMode: "solo-first",
|
|
344
|
-
maxConcurrentSubagents:
|
|
349
|
+
maxConcurrentSubagents: 1,
|
|
345
350
|
defaultReviewLenses: ["correctness", "tests", "scope"],
|
|
346
351
|
roleModelGuidance: {
|
|
347
352
|
planner: "Use the strongest available model for decomposition, architecture, risk, and acceptance criteria.",
|
|
348
|
-
worker: "
|
|
353
|
+
worker: "Disabled by default. The parent model owns all implementation and mutation.",
|
|
349
354
|
reviewer: "Use a model or thinking setting decorrelated from the worker when review quality matters.",
|
|
350
355
|
watchdog: "Use a strong model only for final risk review, security, release, or high-impact changes."
|
|
351
356
|
},
|
|
@@ -357,14 +362,13 @@ const DEFAULT_ORCHESTRATION_POLICY: ResolvedOrchestrationPolicy = {
|
|
|
357
362
|
readBeforeTask: true
|
|
358
363
|
},
|
|
359
364
|
rules: [
|
|
360
|
-
"Default to
|
|
361
|
-
"Use
|
|
362
|
-
"
|
|
365
|
+
"Default to the parent model working directly; a helper is an exceptional token optimization, not a reasoning phase.",
|
|
366
|
+
"Use at most one fresh read-only helper only when runtime evidence proves at least two independent lanes and at least 30% projected net token savings.",
|
|
367
|
+
"Never delegate implementation, inherit parent history, retry a deterministic helper failure, or run parallel helpers/writers.",
|
|
363
368
|
"Treat Field Guide memory as advisory; verify every durable fact against current repository files.",
|
|
364
369
|
"Keep review lenses explicit so cheap review work catches drift before release."
|
|
365
370
|
]
|
|
366
371
|
};
|
|
367
|
-
|
|
368
372
|
const PERMISSION_PROFILE_MODES = ["read-only", "workspace-write", "trusted-full-access"] as const;
|
|
369
373
|
const PERMISSION_PROFILE_ALIASES: Record<string, PermissionProfileMode> = {
|
|
370
374
|
readonly: "read-only",
|
|
@@ -385,183 +389,11 @@ const WRITE_TOOL_NAMES = new Set(["write", "edit"]);
|
|
|
385
389
|
const SHELL_TOOL_NAMES = new Set(["bash", "shell", "exec"]);
|
|
386
390
|
const MAX_MCP_PROXY_ARGS_CHARS = 131_072;
|
|
387
391
|
const SESSION_PERMISSION_OVERRIDES = new Map<string, PermissionProfileMode>();
|
|
388
|
-
|
|
389
|
-
// The policy used when `policies/base-policy.json` cannot be read. It runs in
|
|
390
|
-
// exactly the case where something is already wrong, so it must never be the
|
|
391
|
-
// looser of the two: this copy had drifted behind the file and silently dropped
|
|
392
|
-
// `.pi/piagent-state/**` -- the guard's own state -- along with the `sudo ` and
|
|
393
|
-
// `chmod -R 777` blocks. A missing policy file is a reason to be stricter, not a
|
|
394
|
-
// quiet downgrade. `tests/policy-core.test.mjs` fails if this drifts again.
|
|
395
|
-
const DEFAULT_POLICY: BasePolicy = {
|
|
396
|
-
protectedPaths: [".git/**", "**/auth.json", "**/.env", "**/.env.*", "**/node_modules/**", "**/dist/**", ".pi/piagent-state/**", ".pi/settings.json", ".pi/piagent-profile.json", ".pi/piagent-profile.lock.json", CONTEXT_INDEX_FILE],
|
|
397
|
-
shellProtectedPaths: [".git/**", "**/auth.json", "**/.env", "**/.env.*", ".pi/piagent-state/**", ".pi/settings.json", ".pi/piagent-profile.json", ".pi/piagent-profile.lock.json", CONTEXT_INDEX_FILE],
|
|
398
|
-
blockedCommandPatterns: ["rm -rf /", "rm -rf ~", "rm -rf $HOME", "git reset --hard", "git clean -fd", "sudo ", "chmod -R 777"],
|
|
399
|
-
requireConfirmationPatterns: ["deploy", "release", "publish", "migration", "gh pr merge", "git push"],
|
|
400
|
-
defaultRequiredContext: ["AGENTS.md", "README.md"],
|
|
401
|
-
permissionProfiles: {
|
|
402
|
-
defaultMode: "workspace-write",
|
|
403
|
-
allowedModes: ["read-only", "workspace-write", "trusted-full-access"]
|
|
404
|
-
},
|
|
405
|
-
execPolicy: {
|
|
406
|
-
defaultMode: "enforce",
|
|
407
|
-
bannedPrefixSuggestions: [
|
|
408
|
-
["python"],
|
|
409
|
-
["python3"],
|
|
410
|
-
["node"],
|
|
411
|
-
["node", "-e"],
|
|
412
|
-
["bash"],
|
|
413
|
-
["bash", "-lc"],
|
|
414
|
-
["sh"],
|
|
415
|
-
["sh", "-c"],
|
|
416
|
-
["zsh"],
|
|
417
|
-
["zsh", "-lc"],
|
|
418
|
-
["git"],
|
|
419
|
-
["sudo"],
|
|
420
|
-
["env"]
|
|
421
|
-
],
|
|
422
|
-
rules: [
|
|
423
|
-
{
|
|
424
|
-
id: "prompt-git-add-broad",
|
|
425
|
-
action: "prompt",
|
|
426
|
-
match: "regex",
|
|
427
|
-
value: "(?:^|\\s)git\\s+(?:-C\\s+\\S+\\s+)?add\\s+(?:(?:--all|-A)(?:\\s+(?:\\.|:/))?|--\\s+(?:\\.|:/)|(?:\\.|:/))(?:\\s|$)",
|
|
428
|
-
reason: "Broad git staging can include unrelated or sensitive changes; inspect git status/diff and confirm the exact scope first."
|
|
429
|
-
}
|
|
430
|
-
]
|
|
431
|
-
},
|
|
432
|
-
contextBudget: {
|
|
433
|
-
defaultMode: "enforce",
|
|
434
|
-
contextDeltaShadow: "sample",
|
|
435
|
-
maxContextFileChars: 50000,
|
|
436
|
-
maxMemoryFileChars: 20000,
|
|
437
|
-
maxManifestFiles: 80,
|
|
438
|
-
warnFragmentChars: 4000
|
|
439
|
-
},
|
|
440
|
-
toolRegistry: {
|
|
441
|
-
defaultMode: "advisory",
|
|
442
|
-
alwaysAllowedTools: [
|
|
443
|
-
"piagent_tools",
|
|
444
|
-
"piagent_context_engine",
|
|
445
|
-
"piagent_context",
|
|
446
|
-
"piagent_permission_status",
|
|
447
|
-
"piagent_exec_policy_check",
|
|
448
|
-
"piagent_context_budget",
|
|
449
|
-
"piagent_tool_policy_check",
|
|
450
|
-
"piagent_task_gate_check",
|
|
451
|
-
"piagent_usage_snapshot",
|
|
452
|
-
"piagent_orchestration_policy",
|
|
453
|
-
"piagent_memory_status",
|
|
454
|
-
"piagent_memory_note",
|
|
455
|
-
"piagent_memory_search",
|
|
456
|
-
"piagent_memory_citation_record",
|
|
457
|
-
"piagent_context_index_status",
|
|
458
|
-
"piagent_context_index_record",
|
|
459
|
-
"piagent_context_index_search",
|
|
460
|
-
"piagent_profile_options",
|
|
461
|
-
"piagent_profile_apply",
|
|
462
|
-
"piagent_profile_tech_options",
|
|
463
|
-
"piagent_profile_tech_apply",
|
|
464
|
-
"piagent_profile_tech_context_record",
|
|
465
|
-
"piagent_project_onboarding_record",
|
|
466
|
-
"piagent_task_start",
|
|
467
|
-
"piagent_task_progress",
|
|
468
|
-
"piagent_source_checkout",
|
|
469
|
-
"piagent_context_record",
|
|
470
|
-
"piagent_verify_record",
|
|
471
|
-
"piagent_trace_record"
|
|
472
|
-
],
|
|
473
|
-
toolCapabilities: {
|
|
474
|
-
bash: ["shell"],
|
|
475
|
-
shell: ["shell"],
|
|
476
|
-
exec: ["shell"],
|
|
477
|
-
read: ["filesystem-readonly"],
|
|
478
|
-
grep: ["filesystem-readonly"],
|
|
479
|
-
find: ["filesystem-readonly"],
|
|
480
|
-
ls: ["filesystem-readonly"],
|
|
481
|
-
write: ["filesystem-write"],
|
|
482
|
-
edit: ["filesystem-write"],
|
|
483
|
-
apply_patch: ["filesystem-write"],
|
|
484
|
-
browser: ["browser"],
|
|
485
|
-
github: ["github"]
|
|
486
|
-
}
|
|
487
|
-
},
|
|
488
|
-
externalActionPolicy: {
|
|
489
|
-
defaultMode: "enforce",
|
|
490
|
-
providerKeywords: [
|
|
491
|
-
"github",
|
|
492
|
-
"gitlab",
|
|
493
|
-
"bitbucket",
|
|
494
|
-
"vercel",
|
|
495
|
-
"netlify",
|
|
496
|
-
"cloudflare",
|
|
497
|
-
"aws",
|
|
498
|
-
"gcp",
|
|
499
|
-
"azure",
|
|
500
|
-
"slack",
|
|
501
|
-
"teams",
|
|
502
|
-
"jira",
|
|
503
|
-
"linear",
|
|
504
|
-
"notion",
|
|
505
|
-
"figma",
|
|
506
|
-
"stripe",
|
|
507
|
-
"supabase",
|
|
508
|
-
"firebase"
|
|
509
|
-
],
|
|
510
|
-
writeVerbs: [
|
|
511
|
-
"add",
|
|
512
|
-
"approve",
|
|
513
|
-
"archive",
|
|
514
|
-
"assign",
|
|
515
|
-
"close",
|
|
516
|
-
"comment",
|
|
517
|
-
"create",
|
|
518
|
-
"delete",
|
|
519
|
-
"deploy",
|
|
520
|
-
"dispatch",
|
|
521
|
-
"merge",
|
|
522
|
-
"open",
|
|
523
|
-
"post",
|
|
524
|
-
"publish",
|
|
525
|
-
"push",
|
|
526
|
-
"release",
|
|
527
|
-
"remove",
|
|
528
|
-
"reopen",
|
|
529
|
-
"run",
|
|
530
|
-
"send",
|
|
531
|
-
"submit",
|
|
532
|
-
"trigger",
|
|
533
|
-
"update",
|
|
534
|
-
"upload",
|
|
535
|
-
"write"
|
|
536
|
-
],
|
|
537
|
-
safeVerbs: [
|
|
538
|
-
"fetch",
|
|
539
|
-
"find",
|
|
540
|
-
"get",
|
|
541
|
-
"inspect",
|
|
542
|
-
"list",
|
|
543
|
-
"read",
|
|
544
|
-
"search",
|
|
545
|
-
"show",
|
|
546
|
-
"view"
|
|
547
|
-
]
|
|
548
|
-
},
|
|
549
|
-
finalGate: {
|
|
550
|
-
defaultMode: "enforce",
|
|
551
|
-
requireTaskContract: true,
|
|
552
|
-
requireContextManifest: true,
|
|
553
|
-
requireVerifyEvidence: true,
|
|
554
|
-
requireTrace: true,
|
|
555
|
-
requirePassingVerify: true
|
|
556
|
-
},
|
|
557
|
-
orchestrationPolicy: DEFAULT_ORCHESTRATION_POLICY
|
|
558
|
-
};
|
|
559
|
-
|
|
392
|
+
const DEFAULT_POLICY = fallbackBasePolicy(CONTEXT_INDEX_FILE, DEFAULT_ORCHESTRATION_POLICY);
|
|
560
393
|
// Which platform supplies the adapters is fixed by where this file is installed,
|
|
561
394
|
// so it is resolved once here rather than threaded through every profile load.
|
|
562
395
|
const PLATFORM_ROOT = findPlatformRoot(path.dirname(fileURLToPath(import.meta.url)));
|
|
563
396
|
const UPDATE_CHECK_MODULE = fileURLToPath(new URL("./update-check.js", import.meta.url));
|
|
564
|
-
|
|
565
397
|
// The installed version, read from the package this file ships in. A maintainer
|
|
566
398
|
// working in the repository is not running a release and has nothing to update
|
|
567
399
|
// to, so only a tree Pi or npm placed is given a version to compare.
|
|
@@ -569,7 +401,6 @@ function installedPlatformVersion(): string | undefined {
|
|
|
569
401
|
if (!isInstalledPlatform(PLATFORM_ROOT)) return undefined;
|
|
570
402
|
return readJsonFile<{ version?: string }>(path.join(PLATFORM_ROOT, "package.json"))?.version;
|
|
571
403
|
}
|
|
572
|
-
|
|
573
404
|
function updateAvailabilityNotice(): string | undefined {
|
|
574
405
|
const installed = installedPlatformVersion();
|
|
575
406
|
if (!installed) return undefined;
|
|
@@ -1016,7 +847,12 @@ function inspectPathInputsFromInput(
|
|
|
1016
847
|
const seen = new Set<string>();
|
|
1017
848
|
const walked = walkStringInputs(input, [], 0, includeFilesystemContentFields);
|
|
1018
849
|
for (const item of walked.items) {
|
|
1019
|
-
const
|
|
850
|
+
const relative = normalizeRelative(cwd, item.value);
|
|
851
|
+
// `path.relative(root, root)` is the empty string. Treat that canonical
|
|
852
|
+
// project-root spelling as `.` so a capability such as `**/*` admits
|
|
853
|
+
// `ls .` and an absolute path equal to cwd. The empty candidate matched no
|
|
854
|
+
// scope and made fresh helpers unable to inspect even their own project.
|
|
855
|
+
const normalized = relative === "" ? "." : relative;
|
|
1020
856
|
if (normalized === undefined) continue;
|
|
1021
857
|
const key = `${item.field}\0${normalized}`;
|
|
1022
858
|
if (seen.has(key)) continue;
|
|
@@ -1126,6 +962,7 @@ function evaluatePathLikeToolAccess(
|
|
|
1126
962
|
forceScopeAware?: boolean;
|
|
1127
963
|
forceWrite?: boolean;
|
|
1128
964
|
allowAmbiguousFilesystemContentFields?: boolean;
|
|
965
|
+
sourceCheckoutReadRoots?: string[];
|
|
1129
966
|
} = {}
|
|
1130
967
|
): { block: boolean; reason?: string } {
|
|
1131
968
|
const scopeAwareTool = options.forceScopeAware === true || ["read", "write", "edit", "grep", "find", "ls"].includes(toolName)
|
|
@@ -1167,9 +1004,13 @@ function evaluatePathLikeToolAccess(
|
|
|
1167
1004
|
}
|
|
1168
1005
|
|
|
1169
1006
|
for (const item of inspectedPaths) {
|
|
1007
|
+
const fieldAccessMode = filesystemFieldAccessMode(toolName, item.field, writesFilesystem);
|
|
1008
|
+
const sourceCheckoutReadRoot = fieldAccessMode === "read"
|
|
1009
|
+
? grantedSourceCheckoutRootForPath(cwd, item.path, options.sourceCheckoutReadRoots ?? [])
|
|
1010
|
+
: undefined;
|
|
1170
1011
|
if (scopeAwareTool && isFilesystemScopeField(item.field)) {
|
|
1171
1012
|
const boundary = inspectRepositoryPathBoundary(cwd, item.path);
|
|
1172
|
-
if (boundary.reason) return { block: true, reason: `Blocked ${toolName}: ${boundary.reason}` };
|
|
1013
|
+
if (boundary.reason && !sourceCheckoutReadRoot) return { block: true, reason: `Blocked ${toolName}: ${boundary.reason}` };
|
|
1173
1014
|
}
|
|
1174
1015
|
const resolvedPath = resolveRepositoryPathCandidate(cwd, item.path);
|
|
1175
1016
|
const readMatched = matchesProtectedPath(item.path, readProtectedPaths)
|
|
@@ -1181,7 +1022,6 @@ function evaluatePathLikeToolAccess(
|
|
|
1181
1022
|
};
|
|
1182
1023
|
}
|
|
1183
1024
|
|
|
1184
|
-
const fieldAccessMode = filesystemFieldAccessMode(toolName, item.field, writesFilesystem);
|
|
1185
1025
|
if (fieldAccessMode === "write") {
|
|
1186
1026
|
const readOnlyMatched = matchesProtectedPath(item.path, readOnlyPaths)
|
|
1187
1027
|
?? (resolvedPath ? matchesProtectedPath(resolvedPath, readOnlyPaths) : undefined);
|
|
@@ -1205,7 +1045,8 @@ function evaluatePathLikeToolAccess(
|
|
|
1205
1045
|
reason: `Blocked ${toolName} write outside resolved filesystem scope from ${item.field}: ${item.path}`
|
|
1206
1046
|
};
|
|
1207
1047
|
}
|
|
1208
|
-
} else if (scopeAwareTool && filesystemRead && isFilesystemScopeField(item.field)
|
|
1048
|
+
} else if (scopeAwareTool && filesystemRead && isFilesystemScopeField(item.field)
|
|
1049
|
+
&& !sourceCheckoutReadRoot && !matchesAnyPath(item.path, filesystemRead)) {
|
|
1209
1050
|
return {
|
|
1210
1051
|
block: true,
|
|
1211
1052
|
reason: `Blocked ${toolName} read outside resolved filesystem scope from ${item.field}: ${item.path}`
|
|
@@ -1236,6 +1077,21 @@ function evaluatePathLikeToolAccess(
|
|
|
1236
1077
|
return { block: false };
|
|
1237
1078
|
}
|
|
1238
1079
|
|
|
1080
|
+
function grantedSourceCheckoutRootForPath(cwd: string, candidate: string, roots: string[]): string | undefined {
|
|
1081
|
+
if (roots.length === 0) return undefined;
|
|
1082
|
+
const absolute = path.resolve(cwd, normalizePathCandidate(candidate));
|
|
1083
|
+
let canonical: string;
|
|
1084
|
+
try {
|
|
1085
|
+
canonical = fs.realpathSync.native(absolute);
|
|
1086
|
+
} catch {
|
|
1087
|
+
return undefined;
|
|
1088
|
+
}
|
|
1089
|
+
return roots.find((root) => {
|
|
1090
|
+
const relative = path.relative(root, canonical);
|
|
1091
|
+
return relative === "" || (relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative));
|
|
1092
|
+
});
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1239
1095
|
function stateRoot(cwd: string): string {
|
|
1240
1096
|
return path.join(cwd, ".pi", "piagent-state");
|
|
1241
1097
|
}
|
|
@@ -1437,16 +1293,6 @@ function externalActionPolicyConfig(policy: BasePolicy): Required<ExternalAction
|
|
|
1437
1293
|
};
|
|
1438
1294
|
}
|
|
1439
1295
|
|
|
1440
|
-
function finalGateConfig(policy: BasePolicy): Required<FinalGateConfig> {
|
|
1441
|
-
return {
|
|
1442
|
-
defaultMode: policy.finalGate?.defaultMode ?? DEFAULT_POLICY.finalGate?.defaultMode ?? "enforce",
|
|
1443
|
-
requireTaskContract: policy.finalGate?.requireTaskContract ?? true,
|
|
1444
|
-
requireContextManifest: policy.finalGate?.requireContextManifest ?? true,
|
|
1445
|
-
requireVerifyEvidence: policy.finalGate?.requireVerifyEvidence ?? true,
|
|
1446
|
-
requireTrace: policy.finalGate?.requireTrace ?? true,
|
|
1447
|
-
requirePassingVerify: policy.finalGate?.requirePassingVerify ?? true
|
|
1448
|
-
};
|
|
1449
|
-
}
|
|
1450
1296
|
|
|
1451
1297
|
function boundedInteger(value: unknown, fallback: number, minimum: number, maximum: number): number {
|
|
1452
1298
|
const numberValue = typeof value === "number" ? value : Number(value);
|
|
@@ -1513,7 +1359,7 @@ function resolveOrchestrationPolicy(profile: ProjectProfile, policy: BasePolicy)
|
|
|
1513
1359
|
};
|
|
1514
1360
|
return {
|
|
1515
1361
|
defaultMode: normalizeOrchestrationMode(configured.defaultMode, defaultPolicy.defaultMode),
|
|
1516
|
-
maxConcurrentSubagents: boundedInteger(configured.maxConcurrentSubagents, defaultPolicy.maxConcurrentSubagents, 0,
|
|
1362
|
+
maxConcurrentSubagents: Math.min(1, boundedInteger(configured.maxConcurrentSubagents, defaultPolicy.maxConcurrentSubagents, 0, 1)),
|
|
1517
1363
|
defaultReviewLenses: normalizeReviewLenses(configured.defaultReviewLenses, defaultPolicy.defaultReviewLenses),
|
|
1518
1364
|
roleModelGuidance,
|
|
1519
1365
|
fieldGuide: {
|
|
@@ -1839,56 +1685,14 @@ function isTaskMutationTool(toolName: string, input: Record<string, unknown>): b
|
|
|
1839
1685
|
.some((token) => tokens.has(token));
|
|
1840
1686
|
}
|
|
1841
1687
|
|
|
1842
|
-
function
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
return false;
|
|
1688
|
+
function shellTouchesGrantedSourceCheckout(cwd: string, command: string, roots: string[]): boolean {
|
|
1689
|
+
if (roots.length === 0) return false;
|
|
1690
|
+
for (const root of roots) {
|
|
1691
|
+
const relative = path.relative(cwd, root).split(path.sep).join("/");
|
|
1692
|
+
if (command.includes(root) || (relative && command.includes(relative))) return true;
|
|
1848
1693
|
}
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
return segments.length > 0 && segments.every((segment) => {
|
|
1852
|
-
const words = segment.words.filter(Boolean);
|
|
1853
|
-
const executable = path.basename(words[0] ?? "");
|
|
1854
|
-
if (executable === "sed" && words.some((word) => /^-.*i/.test(word))) return false;
|
|
1855
|
-
if (executable === "find" && words.some((word) => ["-delete", "-exec", "-execdir", "-ok", "-okdir", "-fprint", "-fprint0", "-fprintf", "-fls"].includes(word))) return false;
|
|
1856
|
-
if (safeCommands.has(executable)) return true;
|
|
1857
|
-
if (executable === "git") return safeGitSubcommands.has(words[1] ?? "");
|
|
1858
|
-
if (executable === "command") return words[1] === "-v";
|
|
1859
|
-
return false;
|
|
1860
|
-
});
|
|
1861
|
-
}
|
|
1862
|
-
|
|
1863
|
-
const PROJECT_MUTATING_EXECUTABLES = new Set([
|
|
1864
|
-
"apply_patch", "bash", "chmod", "chown", "cp", "dd", "install", "ln", "make", "mkdir", "mv", "prename", "rename",
|
|
1865
|
-
"node", "patch", "perl", "php", "python", "python3", "rm", "rmdir", "rsync", "ruby", "scp", "sh",
|
|
1866
|
-
"tee", "touch", "truncate", "zsh"
|
|
1867
|
-
]);
|
|
1868
|
-
|
|
1869
|
-
function isProjectMutatingShellCommand(command: string, segments: Array<{ words: string[] }>): boolean {
|
|
1870
|
-
if (shellHasFileWriteRedirection(command)) return true;
|
|
1871
|
-
const noAliases = new Map<string, string>();
|
|
1872
|
-
for (const segment of segments) {
|
|
1873
|
-
const words = segment.words.filter(Boolean);
|
|
1874
|
-
if (words.length === 0) continue;
|
|
1875
|
-
if (externalExecutableIndex(words, PROJECT_MUTATING_EXECUTABLES, noAliases) !== undefined) return true;
|
|
1876
|
-
const executable = path.basename(words[0] ?? "").toLowerCase();
|
|
1877
|
-
if (executable === "find" && words.some((word) => ["-delete", "-exec", "-execdir", "-ok", "-okdir", "-fprint", "-fprint0", "-fprintf", "-fls"].includes(word))) return true;
|
|
1878
|
-
if (executable === "sed" && words.some((word) => /^-[^-]*i/.test(word) || word === "--in-place" || word.startsWith("--in-place="))) return true;
|
|
1879
|
-
if (executable === "git") {
|
|
1880
|
-
const subcommand = words.slice(1).find((word, index, values) => {
|
|
1881
|
-
if (!word.startsWith("-")) return index === 0 || !["-C", "-c", "--git-dir", "--work-tree"].includes(values[index - 1]);
|
|
1882
|
-
return false;
|
|
1883
|
-
});
|
|
1884
|
-
if (["apply", "checkout", "clean", "mv", "reset", "restore", "rm", "switch"].includes(subcommand ?? "")) return true;
|
|
1885
|
-
}
|
|
1886
|
-
if (["npm", "pnpm", "yarn", "bun"].includes(executable)) {
|
|
1887
|
-
const subcommand = words.find((word, index) => index > 0 && !word.startsWith("-"));
|
|
1888
|
-
if (["add", "ci", "install", "link", "remove", "uninstall", "update", "upgrade"].includes(subcommand ?? "")) return true;
|
|
1889
|
-
}
|
|
1890
|
-
}
|
|
1891
|
-
return false;
|
|
1694
|
+
return extractShellPathCandidates(command)
|
|
1695
|
+
.some((candidate) => Boolean(grantedSourceCheckoutRootForPath(cwd, normalizeRelative(cwd, candidate) ?? candidate, roots)));
|
|
1892
1696
|
}
|
|
1893
1697
|
|
|
1894
1698
|
const EXPLICIT_SHELL_MUTATORS = new Set([
|
|
@@ -2062,18 +1866,20 @@ function recordObservedTaskVerification(
|
|
|
2062
1866
|
},
|
|
2063
1867
|
pendingContext: ObservedTaskContext[],
|
|
2064
1868
|
maxManifestFiles: number, shellSnapshotBefore?: Record<string, string>,
|
|
2065
|
-
eventTree?: ReturnType<typeof
|
|
2066
|
-
readProtectedPaths: string[] = []
|
|
1869
|
+
eventTree?: ReturnType<typeof captureWorkspaceVerificationSnapshot>,
|
|
1870
|
+
readProtectedPaths: string[] = [], preWorkspaceRevisionDigest?: string, diagnosticFocused = false
|
|
2067
1871
|
): TaskContract | undefined {
|
|
2068
1872
|
const task = activeSessionTask(ctx.cwd, ctx.sessionManager.getSessionId()) as TaskContract | undefined;
|
|
2069
1873
|
if (!task || task.trace.outcome !== "pending") return;
|
|
2070
1874
|
const command = String(observed.normalizedCommand ?? observed.command ?? "").trim();
|
|
2071
1875
|
const observedAtMs = Date.parse(observed.recordedAt ?? "");
|
|
2072
1876
|
const taskCreatedAtMs = Date.parse(task.createdAt);
|
|
1877
|
+
const matchedProfileCommand = commandMatchesVerifyPlan(command, task.verifyCommands);
|
|
1878
|
+
const focusedTest = diagnosticFocused && observedFocusedTestSummary(observed.outputText);
|
|
2073
1879
|
if (
|
|
2074
1880
|
!command
|
|
2075
1881
|
|| !observed.commandHash
|
|
2076
|
-
|| !
|
|
1882
|
+
|| (!matchedProfileCommand && !focusedTest)
|
|
2077
1883
|
|| !Number.isFinite(observedAtMs)
|
|
2078
1884
|
|| !Number.isFinite(taskCreatedAtMs)
|
|
2079
1885
|
|| observedAtMs < taskCreatedAtMs
|
|
@@ -2082,6 +1888,7 @@ function recordObservedTaskVerification(
|
|
|
2082
1888
|
if (!eventTree?.proofCapable) return;
|
|
2083
1889
|
const currentDigests = eventTree.snapshot as Record<string, string>;
|
|
2084
1890
|
const currentDigest = eventTree.digest;
|
|
1891
|
+
const workspaceRevisionDigest = eventTree.workspaceRevisionDigest ?? undefined;
|
|
2085
1892
|
const preWorkingTreeDigest = shellSnapshotBefore && workingTreeSnapshotUsesCurrentAlgorithm(shellSnapshotBefore) ? workingTreeEvidenceDigest(shellSnapshotBefore) : undefined;
|
|
2086
1893
|
const exitCode = Number.isInteger(observed.exitCode) ? observed.exitCode as number : observed.isError ? 1 : 0;
|
|
2087
1894
|
const classification = classifyVerificationFailure(observed.outputText, exitCode);
|
|
@@ -2089,6 +1896,7 @@ function recordObservedTaskVerification(
|
|
|
2089
1896
|
evidence.command.trim() === command
|
|
2090
1897
|
&& evidence.exitCode === exitCode
|
|
2091
1898
|
&& evidence.workingTreeDigest === currentDigest && evidence.observedAt === observed.recordedAt
|
|
1899
|
+
&& evidence.workspaceRevisionDigest === workspaceRevisionDigest && evidence.preWorkspaceRevisionDigest === preWorkspaceRevisionDigest
|
|
2092
1900
|
));
|
|
2093
1901
|
const contextAdded = mergeObservedTaskContext(task, pendingContext, maxManifestFiles, redactText);
|
|
2094
1902
|
if (!duplicate) {
|
|
@@ -2097,16 +1905,17 @@ function recordObservedTaskVerification(
|
|
|
2097
1905
|
task.verifyEvidence.push({
|
|
2098
1906
|
command: redactText(command),
|
|
2099
1907
|
exitCode,
|
|
2100
|
-
summary: `Runtime observed configured verifier exit ${exitCode} (${classification.category}${classification.retryable ? ", retryable" : ""}).`,
|
|
1908
|
+
summary: `Runtime observed ${matchedProfileCommand ? "configured" : "focused"} verifier exit ${exitCode} (${classification.category}${classification.retryable ? ", retryable" : ""}).`,
|
|
2101
1909
|
recordedAt: evidenceRecordedAt,
|
|
2102
1910
|
observed: true,
|
|
2103
1911
|
observedAt,
|
|
2104
1912
|
isError: observed.isError === true,
|
|
2105
|
-
matchedProfileCommand
|
|
1913
|
+
matchedProfileCommand,
|
|
2106
1914
|
preWorkingTreeDigest,
|
|
2107
|
-
workingTreeDigest: currentDigest
|
|
1915
|
+
workingTreeDigest: currentDigest,
|
|
1916
|
+
preWorkspaceRevisionDigest, workspaceRevisionDigest
|
|
2108
1917
|
});
|
|
2109
|
-
task.verifyEvidence = task.verifyEvidence.slice(-100);
|
|
1918
|
+
task.verifyEvidence = diagnosticFocused ? retainFocusedVerification(task.verifyEvidence, currentDigest, workspaceRevisionDigest) : task.verifyEvidence.slice(-100);
|
|
2110
1919
|
try {
|
|
2111
1920
|
captureVerifierFileSnapshot({
|
|
2112
1921
|
projectRoot: ctx.cwd, taskId: task.taskId, taskRunId: task.taskRunId, sessionId: task.sessionId,
|
|
@@ -2119,18 +1928,20 @@ function recordObservedTaskVerification(
|
|
|
2119
1928
|
}
|
|
2120
1929
|
}
|
|
2121
1930
|
|
|
2122
|
-
const
|
|
2123
|
-
const
|
|
2124
|
-
const
|
|
1931
|
+
const taskLocalDelta = taskChangedFileEvidence(ctx.cwd, task, currentDigests).expected;
|
|
1932
|
+
const hasChanges = taskLocalDelta.length > 0;
|
|
1933
|
+
const verificationCanSettleSourceTask = hasChanges || task.mutationPolicy === "allowed";
|
|
1934
|
+
const allPassing = verificationCanSettleSourceTask && allVerifyCommandsPassCurrentTree(task, currentDigest, workspaceRevisionDigest ?? null);
|
|
1935
|
+
const lifecycle = verificationCanSettleSourceTask
|
|
2125
1936
|
? applyRuntimeLifecycleObservation(task, allPassing ? "verification-complete" : "verification-pending", nowIso())
|
|
2126
1937
|
: { changed: false, mode: runtimeLifecycleMode(task) };
|
|
2127
1938
|
const acceptance = refreshAcceptanceReceipt(task, {
|
|
2128
|
-
cwd: ctx.cwd,
|
|
2129
|
-
changedFiles:
|
|
1939
|
+
cwd: ctx.cwd, apiBaselineEvidence,
|
|
1940
|
+
changedFiles: taskAcceptanceEvidenceFiles(ctx.cwd, task, currentDigests, taskLocalDelta),
|
|
2130
1941
|
currentWorkingTreeDigest: currentDigest
|
|
2131
1942
|
});
|
|
2132
1943
|
task.acceptanceReceipt = acceptance.task.acceptanceReceipt;
|
|
2133
|
-
if (!task.workingTreeDigestMigration || (shellSnapshotBefore && changedSnapshotFiles(shellSnapshotBefore, currentDigests).length === 0)) Object.assign(task, completeTaskDigestRefresh(task, currentDigest));
|
|
1944
|
+
if (!task.workingTreeDigestMigration || (shellSnapshotBefore && changedSnapshotFiles(shellSnapshotBefore, currentDigests).length === 0)) Object.assign(task, completeTaskDigestRefresh(task, currentDigest, workspaceRevisionDigest ?? null));
|
|
2134
1945
|
if (duplicate && contextAdded.length === 0 && !lifecycle.changed) return task;
|
|
2135
1946
|
|
|
2136
1947
|
const written = writeTask(ctx.cwd, task);
|
|
@@ -2160,7 +1971,8 @@ function recordObservedTaskVerification(
|
|
|
2160
1971
|
retryable: classification.retryable,
|
|
2161
1972
|
failureClassification: classification,
|
|
2162
1973
|
preWorkingTreeDigest,
|
|
2163
|
-
workingTreeDigest: currentDigest
|
|
1974
|
+
workingTreeDigest: currentDigest,
|
|
1975
|
+
preWorkspaceRevisionDigest, workspaceRevisionDigest
|
|
2164
1976
|
}
|
|
2165
1977
|
});
|
|
2166
1978
|
return written;
|
|
@@ -2210,14 +2022,14 @@ function completionTaskProjection(
|
|
|
2210
2022
|
failureReason: undefined,
|
|
2211
2023
|
ruledOut: undefined,
|
|
2212
2024
|
trace: {
|
|
2213
|
-
outcome: "completed",
|
|
2025
|
+
outcome: "completed" as const,
|
|
2214
2026
|
notes: "Runtime finalized from observed context, working-tree changes, current verification, and completed work-plan evidence.",
|
|
2215
2027
|
recordedAt: nowIso()
|
|
2216
2028
|
}
|
|
2217
2029
|
};
|
|
2218
2030
|
return refreshAcceptanceReceipt(projected, {
|
|
2219
|
-
cwd,
|
|
2220
|
-
changedFiles,
|
|
2031
|
+
cwd, apiBaselineEvidence,
|
|
2032
|
+
changedFiles: taskAcceptanceEvidenceFiles(cwd, projected, finalFileDigests, changedFiles),
|
|
2221
2033
|
currentWorkingTreeDigest: workingTreeEvidenceDigest(finalFileDigests)
|
|
2222
2034
|
}).task as TaskContract;
|
|
2223
2035
|
}
|
|
@@ -3630,6 +3442,20 @@ function taskChangedFileEvidence(
|
|
|
3630
3442
|
};
|
|
3631
3443
|
}
|
|
3632
3444
|
|
|
3445
|
+
function taskAcceptanceEvidenceFiles(
|
|
3446
|
+
cwd: string,
|
|
3447
|
+
task: TaskContract,
|
|
3448
|
+
currentDigests: Record<string, string>,
|
|
3449
|
+
taskLocalDelta: string[] = taskChangedFileEvidence(cwd, task, currentDigests).expected
|
|
3450
|
+
): string[] {
|
|
3451
|
+
return completedFollowupAcceptanceEvidenceFiles(
|
|
3452
|
+
task,
|
|
3453
|
+
listTaskContracts(cwd) as TaskContract[],
|
|
3454
|
+
taskLocalDelta,
|
|
3455
|
+
currentDigests
|
|
3456
|
+
);
|
|
3457
|
+
}
|
|
3458
|
+
|
|
3633
3459
|
function exactReviewPathCoverage(expectedPaths: string[], reviewedPaths: string[] | undefined): boolean {
|
|
3634
3460
|
const expected = [...new Set(expectedPaths)].sort();
|
|
3635
3461
|
const reviewed = [...new Set(reviewedPaths ?? [])].sort();
|
|
@@ -3668,8 +3494,9 @@ function evaluateTaskGate(
|
|
|
3668
3494
|
warnings: string[];
|
|
3669
3495
|
currentWorkingTreeDigest?: string;
|
|
3670
3496
|
changedFileEvidence?: ReturnType<typeof taskChangedFileEvidence>;
|
|
3497
|
+
acceptanceProof?: { mode: "enforce" | "diagnostic"; pendingCriterionIds: string[]; missing: string[] };
|
|
3671
3498
|
} {
|
|
3672
|
-
const finalGate = finalGateConfig(policy);
|
|
3499
|
+
const finalGate = finalGateConfig(policy, DEFAULT_POLICY);
|
|
3673
3500
|
const missing: string[] = [];
|
|
3674
3501
|
const warnings: string[] = [];
|
|
3675
3502
|
if (!task) {
|
|
@@ -3677,14 +3504,24 @@ function evaluateTaskGate(
|
|
|
3677
3504
|
}
|
|
3678
3505
|
const currentDigests = options.currentDigests ?? workingTreeSnapshot(cwd) as Record<string, string>;
|
|
3679
3506
|
const currentWorkingTreeDigest = options.currentWorkingTreeDigest ?? workingTreeEvidenceDigest(currentDigests);
|
|
3507
|
+
const independentState = independentAcceptanceState(cwd, task, currentWorkingTreeDigest);
|
|
3508
|
+
if (independentState.block) missing.push(independentState.block);
|
|
3509
|
+
const compositeFacts = new Set<string>();
|
|
3510
|
+
for (const [id, assessment] of independentState.assessments) {
|
|
3511
|
+
if (assessment.verdict !== "pass") missing.push(`independent contract evidence (${id}:${assessment.verdict}${assessment.executionDiagnostics?.reasons.length ? `; ${assessment.executionDiagnostics.reasons.join(", ")}` : ""})`);
|
|
3512
|
+
else if (assessment.assurance === "bounded-composite-contract-tested" && Array.isArray(assessment.factKinds)) {
|
|
3513
|
+
for (const kind of assessment.factKinds) if (typeof kind === "string") compositeFacts.add(kind);
|
|
3514
|
+
}
|
|
3515
|
+
}
|
|
3516
|
+
const compositeContext = compositeFacts.has("context-current"), compositeVerifier = compositeFacts.has("project-verifier-current");
|
|
3680
3517
|
if (task.workingTreeDigestAlgorithm !== WORKING_TREE_DIGEST_ALGORITHM || task.workingTreeDigestMigration?.status === "verification-refresh-required" || !workingTreeSnapshotUsesCurrentAlgorithm(currentDigests) || !isCurrentWorkingTreeDigest(currentWorkingTreeDigest) || currentWorkingTreeDigest !== workingTreeEvidenceDigest(currentDigests) || Object.values(task.baselineFileDigests).some((digest) => !isCurrentWorkingTreeDigest(digest)) || (task.workingTreeDigestMigration && (!taskDigestMigrationArchiveStatus(cwd, task).valid || replayTaskCheckpoints(cwd, task.taskRunId, task).corruptions.length > 0))) missing.push("current working-tree digest evidence");
|
|
3681
3518
|
if (workingTreeSnapshotHasUnavailableEvidence(currentDigests)) missing.push("complete working-tree content evidence");
|
|
3682
3519
|
if (taskContractValidationErrors(task).length > 0) missing.push("valid session-bound task contract v2");
|
|
3683
3520
|
if (task.attempt > task.maxAttempts) missing.push(`attempt within maxAttempts (${task.attempt}/${task.maxAttempts})`);
|
|
3684
3521
|
const plannedVerifyCommands = meaningfulVerificationCommands(task.verifyCommands);
|
|
3685
|
-
if (task.changeMode === "source-change" && plannedVerifyCommands.length === 0) missing.push("meaningful verify command");
|
|
3686
|
-
if (finalGate.requireContextManifest && !hasDurableContextEvidence(task)) missing.push("context manifest");
|
|
3687
|
-
if (task.changeMode === "source-change" && finalGate.requireVerifyEvidence && task.verifyEvidence.length === 0) missing.push("verify evidence");
|
|
3522
|
+
if (task.changeMode === "source-change" && plannedVerifyCommands.length === 0 && !compositeVerifier) missing.push("meaningful verify command");
|
|
3523
|
+
if (finalGate.requireContextManifest && !hasDurableContextEvidence(task) && !compositeContext) missing.push("context manifest");
|
|
3524
|
+
if (task.changeMode === "source-change" && finalGate.requireVerifyEvidence && task.verifyEvidence.length === 0 && !compositeVerifier) missing.push("verify evidence");
|
|
3688
3525
|
if (task.verifyEvidence.some((evidence) => evidence.observed !== true)) {
|
|
3689
3526
|
warnings.push("Unobserved verify evidence is ignored by the passing verify gate.");
|
|
3690
3527
|
}
|
|
@@ -3699,48 +3536,74 @@ function evaluateTaskGate(
|
|
|
3699
3536
|
warnings.push("Verification evidence from a different working-tree snapshot is stale and is ignored.");
|
|
3700
3537
|
}
|
|
3701
3538
|
let missingVerifyCommands: string[] = [];
|
|
3702
|
-
if (task.changeMode === "source-change" && finalGate.requirePassingVerify && plannedVerifyCommands.length > 0) {
|
|
3703
|
-
const passingCommands = passingVerifyCommandsForDigest(task, currentWorkingTreeDigest);
|
|
3539
|
+
if (task.changeMode === "source-change" && finalGate.requirePassingVerify && plannedVerifyCommands.length > 0 && !compositeVerifier) {
|
|
3540
|
+
const passingCommands = passingVerifyCommandsForDigest(task, currentWorkingTreeDigest, currentWorkspaceRevisionDigest(cwd));
|
|
3704
3541
|
missingVerifyCommands = plannedVerifyCommands.filter((command) => !passingCommands.has(command.trim()));
|
|
3705
3542
|
if (missingVerifyCommands.length > 0) missing.push(`observed passing verify evidence for every configured command (${missingVerifyCommands.length} missing)`);
|
|
3706
3543
|
}
|
|
3544
|
+
if (finalGate.acceptanceProofMode === "diagnostic" && unresolvedFocusedVerification(task.verifyEvidence, currentWorkingTreeDigest, currentWorkspaceRevisionDigest(cwd)).length > 0) missing.push("current passing rerun of failed focused verification");
|
|
3707
3545
|
if (finalGate.requireTrace && task.trace.outcome !== "completed") missing.push("completed final trace");
|
|
3708
3546
|
const incompleteSteps = (task.workPlan ?? []).filter((step) => step.status === "pending" || step.status === "in-progress" || step.status === "failed");
|
|
3709
3547
|
if (task.trace.outcome === "completed" && incompleteSteps.length > 0) {
|
|
3710
3548
|
missing.push(`completed work plan (${incompleteSteps.map((step) => `${step.id}:${step.status}`).join(", ")})`);
|
|
3711
3549
|
}
|
|
3712
3550
|
const changedFileEvidence = taskChangedFileEvidence(cwd, task, currentDigests);
|
|
3551
|
+
const acceptanceEvidenceFiles = taskAcceptanceEvidenceFiles(cwd, task, currentDigests, changedFileEvidence.expected);
|
|
3713
3552
|
if (task.changeMode === "source-change" && task.trace.outcome === "completed" && task.mutationPolicy !== "forbidden") {
|
|
3714
|
-
if (task.changedFiles.length === 0) missing.push("changed files");
|
|
3553
|
+
if (task.mutationPolicy !== "allowed" && task.changedFiles.length === 0) missing.push("changed files");
|
|
3715
3554
|
if (changedFileEvidence.undeclared.length > 0) missing.push(`declared observed changes (${changedFileEvidence.undeclared.join(", ")})`);
|
|
3716
3555
|
if (changedFileEvidence.unsupportedClaims.length > 0) missing.push(`supported changed-file claims (${changedFileEvidence.unsupportedClaims.join(", ")})`);
|
|
3717
|
-
if (changedFileEvidence.outsideScope.length > 0)
|
|
3556
|
+
if (changedFileEvidence.outsideScope.length > 0) {
|
|
3557
|
+
warnings.push(`Task focus expanded beyond the initial scope (${changedFileEvidence.outsideScope.join(", ")}).`);
|
|
3558
|
+
}
|
|
3718
3559
|
}
|
|
3719
3560
|
if ((task.changeMode === "read-only" || task.mutationPolicy === "forbidden") && changedFileEvidence.expected.length > 0) {
|
|
3720
3561
|
missing.push(`mutation-forbidden task has observed changes (${changedFileEvidence.expected.join(", ")})`);
|
|
3721
3562
|
}
|
|
3722
3563
|
const acceptance = refreshAcceptanceReceipt(task, {
|
|
3723
|
-
cwd,
|
|
3724
|
-
changedFiles:
|
|
3564
|
+
cwd, apiBaselineEvidence,
|
|
3565
|
+
changedFiles: acceptanceEvidenceFiles,
|
|
3725
3566
|
currentWorkingTreeDigest
|
|
3726
3567
|
});
|
|
3727
3568
|
const semanticEnforcement = taskAuthorityDecision(task, "CAP-13", "block").allowed;
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3569
|
+
// Runtime-derived critical proof gates completion. A zero-delta review
|
|
3570
|
+
// uses its strictly bound evidence scope without claiming a new mutation.
|
|
3571
|
+
// Neutral artifacts with missing content proof use source-proof-required;
|
|
3572
|
+
// unsupported language policy remains under the existing CAP-13 authority.
|
|
3573
|
+
const proofMissing: string[] = [];
|
|
3574
|
+
const runtimeCriticalProofEnforcement = task.changeMode === "source-change"
|
|
3575
|
+
&& task.acceptanceReceipt?.source === "runtime";
|
|
3576
|
+
const abstainedIds = new Set(acceptance.adapterAbstained.map((criterion) => criterion.id));
|
|
3577
|
+
const independentIds = new Set(acceptance.independentRequired.map((criterion) => criterion.id));
|
|
3578
|
+
const sourceProofIds = new Set(acceptance.sourceProofRequired.map((criterion) => criterion.id));
|
|
3579
|
+
const adapterCritical = acceptance.criticalMissing.filter((criterion) => abstainedIds.has(criterion.id) && !independentIds.has(criterion.id));
|
|
3580
|
+
const linkedCritical = acceptance.criticalMissing.filter((criterion) => !abstainedIds.has(criterion.id) && !independentIds.has(criterion.id) && !sourceProofIds.has(criterion.id));
|
|
3581
|
+
if ((semanticEnforcement || runtimeCriticalProofEnforcement) && sourceProofIds.size > 0) proofMissing.push(`critical acceptance evidence source-proof-required (${acceptance.sourceProofRequired.map((criterion) => `${criterion.id}:${criterion.obligation}`).join(", ")}); remedy: source proof remains unestablished after current focused tests passed; seek assessment, not source repair without a counterexample`);
|
|
3582
|
+
if ((semanticEnforcement || runtimeCriticalProofEnforcement) && independentIds.size > 0) proofMissing.push(`critical acceptance evidence independent-required (${acceptance.independentRequired.map((criterion) => `${criterion.id}:${criterion.obligation}`).join(", ")}); remedy: an approved independent assessment must cover every clause; missing proof is not an observed source defect`);
|
|
3583
|
+
if ((semanticEnforcement || runtimeCriticalProofEnforcement) && linkedCritical.length > 0) proofMissing.push(`critical acceptance evidence (${linkedCritical.map((criterion) => `${criterion.id}:${criterion.obligation}`).join(", ")})`);
|
|
3584
|
+
if (semanticEnforcement && adapterCritical.length > 0) proofMissing.push(`critical acceptance evidence adapter-unresolved (${adapterCritical.map((criterion) => `${criterion.id}:${criterion.obligation}`).join(", ")}); remedy: add a direct-relative focused test or configure a deterministic adapter`);
|
|
3731
3585
|
const acceptanceConflicts = acceptanceSemanticConflicts(task, {
|
|
3732
3586
|
cwd,
|
|
3733
|
-
changedFiles:
|
|
3587
|
+
changedFiles: acceptanceEvidenceFiles
|
|
3734
3588
|
});
|
|
3735
3589
|
if (semanticEnforcement && acceptanceConflicts.length > 0) {
|
|
3736
3590
|
missing.push(`acceptance semantic conflicts (${acceptanceConflicts.join(", ")})`);
|
|
3737
3591
|
}
|
|
3738
|
-
const
|
|
3739
|
-
|
|
3592
|
+
const criticalIds = new Set(acceptance.criticalMissing.map((criterion) => criterion.id));
|
|
3593
|
+
const normalMissing = acceptance.missing.filter((criterion) => !criticalIds.has(criterion.id));
|
|
3594
|
+
if (semanticEnforcement && acceptance.adapterAbstained.length > 0) {
|
|
3595
|
+
warnings.push(`Acceptance proof adapter abstained; rigorous criteria remain pending and hand off without an automatic model retry: ${acceptance.adapterAbstained.map((criterion) => `${criterion.id}:${criterion.obligation}`).join(", ")}`);
|
|
3596
|
+
}
|
|
3597
|
+
if (!semanticEnforcement && (adapterCritical.length > 0 || acceptanceConflicts.length > 0)) warnings.push("Adapter-unknown acceptance proof and semantic conflicts remain advisory under the pinned task authority; known runtime-linked critical proof still gates source-task completion.");
|
|
3740
3598
|
if (normalMissing.length > 0) {
|
|
3741
3599
|
warnings.push(`Acceptance criteria pending evidence: ${normalMissing.map((criterion) => `${criterion.id}:${criterion.obligation}`).join(", ")}`);
|
|
3742
3600
|
}
|
|
3743
|
-
|
|
3601
|
+
const acceptanceProof = { mode: finalGate.acceptanceProofMode,
|
|
3602
|
+
pendingCriterionIds: acceptance.missing.map(criterion => criterion.id), missing: proofMissing };
|
|
3603
|
+
if (finalGate.acceptanceProofMode === "diagnostic" && acceptanceProof.pendingCriterionIds.length > 0) {
|
|
3604
|
+
warnings.push(`Diagnostic acceptance: ${acceptanceProof.pendingCriterionIds.length} criteria remain unproved; no quality claim. ${proofMissing.join("; ")}`);
|
|
3605
|
+
} else missing.push(...proofMissing);
|
|
3606
|
+
return { decision: missing.length === 0 ? "pass" : "fail", missing, missingVerifyCommands, warnings, currentWorkingTreeDigest, changedFileEvidence, ...(finalGate.acceptanceProofMode === "diagnostic" ? { acceptanceProof } : {}) };
|
|
3744
3607
|
}
|
|
3745
3608
|
|
|
3746
3609
|
function appendTrace(cwd: string, payload: Record<string, unknown>): void {
|
|
@@ -3912,14 +3775,28 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
3912
3775
|
const routingObjective = routingObjectiveFromEnvironment(process.env.PIAGENT_ROUTING_OBJECTIVE);
|
|
3913
3776
|
const autoContextEnabled = environmentFeatureEnabled("PIAGENT_AUTO_CONTEXT");
|
|
3914
3777
|
const autoRecoveryEnabled = environmentFeatureEnabled("PIAGENT_AUTO_RECOVERY");
|
|
3915
|
-
const
|
|
3916
|
-
maxObservedContext: contextBudgetConfig(policy).maxManifestFiles
|
|
3917
|
-
|
|
3778
|
+
const independentVerificationConfigPath = process.env.PIAGENT_INDEPENDENT_VERIFICATION_CONFIG,
|
|
3779
|
+
runtimeState = new RuntimeSessionState({ maxObservedContext: contextBudgetConfig(policy).maxManifestFiles });
|
|
3780
|
+
const independentAcceptance = new IndependentAcceptanceRuntime({ state: runtimeState, installedRoot: PLATFORM_ROOT,
|
|
3781
|
+
configPath: independentVerificationConfigPath,
|
|
3782
|
+
writeTask,
|
|
3783
|
+
activeTask: (ctx) => activeSessionTask(ctx.cwd, ctx.sessionManager.getSessionId()) as TaskContract | undefined,
|
|
3784
|
+
authorizeSourceRead: (ctx, sourcePath) => {
|
|
3785
|
+
if (!ctx.isProjectTrusted()) return false;
|
|
3786
|
+
const profile = loadProfileFromContext(ctx), paths = effectiveProtectedPaths(policy, profile);
|
|
3787
|
+
const capabilities = verifyProjectCapabilityState(extensionDir, ctx.cwd, true, { sessionId: ctx.sessionManager.getSessionId() });
|
|
3788
|
+
if (!capabilities.ok) return false;
|
|
3789
|
+
const permission = resolvePermissionProfile(profile, policy, permissionOverrideFromContext(ctx));
|
|
3790
|
+
return !evaluatePathLikeToolAccess(ctx.cwd, "read", { path: sourcePath }, paths.writeProtectedPaths, paths.readProtectedPaths,
|
|
3791
|
+
paths.readOnlyPaths, permission.mode === "trusted-full-access" ? undefined : capabilities.filesystemRead).block;
|
|
3792
|
+
} });
|
|
3793
|
+
const editFreshnessGuard = new EditFreshnessGuard(editFreshnessModeFromEnvironment(process.env.PIAGENT_EDIT_FRESHNESS));
|
|
3918
3794
|
const sourceMutationGuardBindings = createSourceMutationGuardBindings(policy, loadProfileFromContext);
|
|
3919
3795
|
const runtimeSnapshotCapture = new RuntimeSnapshotCapture(), runtimeVersions = readRuntimeVersionMetadata(PLATFORM_ROOT);
|
|
3920
3796
|
const solverShadow = solverMode === "off" ? undefined : new SolverShadowRuntime(solverMode);
|
|
3921
3797
|
const modelRouteRuntime = new ModelRouteRuntime(parentRoutingMode, routingObjective);
|
|
3922
3798
|
const modelSelectionProvenance = new ModelSelectionProvenanceTracker();
|
|
3799
|
+
const serviceTierRuntime = new ServiceTierRuntime({ environmentValue: process.env.PIAGENT_FAST_MODE });
|
|
3923
3800
|
const trajectoryRuntime = new TrajectoryRuntime(), phaseToolRuntime = new PhaseToolRuntime(pi, dynamicToolsEnabled ? phaseToolModeFromEnvironment(process.env.PIAGENT_PHASE_TOOLS) : "off", telemetry, (ctx) => {
|
|
3924
3801
|
const task = activeSessionTask(ctx.cwd, ctx.sessionManager.getSessionId()) as TaskContract | undefined; return task && authorityReplacementState(ctx.cwd, task).required ? "new-attempt-required" : task?.workingTreeDigestMigration?.status;
|
|
3925
3802
|
}, (ctx) => {
|
|
@@ -3963,8 +3840,25 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
3963
3840
|
providerReasoningReasonCode: normalized.reasonCode
|
|
3964
3841
|
});
|
|
3965
3842
|
}
|
|
3843
|
+
const serviceTier = serviceTierRuntime.applyProviderRequest(
|
|
3844
|
+
pi,
|
|
3845
|
+
ctx,
|
|
3846
|
+
normalized.changed ? normalized.payload : event.payload
|
|
3847
|
+
);
|
|
3848
|
+
if (serviceTier.receipt.enabled || serviceTier.observationChanged) {
|
|
3849
|
+
telemetry(ctx, {
|
|
3850
|
+
event: "provider_request_service_tier",
|
|
3851
|
+
fastMode: serviceTier.receipt.mode,
|
|
3852
|
+
requestedServiceTier: serviceTier.receipt.requestedServiceTier,
|
|
3853
|
+
observedRequestServiceTier: serviceTier.receipt.observedRequestServiceTier,
|
|
3854
|
+
providerResponseServiceTier: serviceTier.receipt.providerResponseServiceTier,
|
|
3855
|
+
providerResponseEvidence: serviceTier.receipt.providerResponseEvidence,
|
|
3856
|
+
applied: serviceTier.receipt.applied,
|
|
3857
|
+
reasonCode: serviceTier.receipt.reasonCode
|
|
3858
|
+
});
|
|
3859
|
+
}
|
|
3966
3860
|
const wire = buildOpenAiCodexWireFingerprint({
|
|
3967
|
-
payload:
|
|
3861
|
+
payload: serviceTier.payload,
|
|
3968
3862
|
provider: ctx.model?.provider,
|
|
3969
3863
|
modelId: ctx.model?.id,
|
|
3970
3864
|
workingDirectory: ctx.cwd,
|
|
@@ -3989,10 +3883,11 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
3989
3883
|
providerTextVerbosity: wire.textVerbosity,
|
|
3990
3884
|
providerToolChoiceKind: wire.toolChoiceKind,
|
|
3991
3885
|
providerToolChoiceHash: wire.toolChoiceHash,
|
|
3992
|
-
requestPrefixFingerprint: wire.requestPrefixFingerprint
|
|
3886
|
+
requestPrefixFingerprint: wire.requestPrefixFingerprint,
|
|
3887
|
+
payloadMeasurement: measureProviderPayload(serviceTier.payload)
|
|
3993
3888
|
});
|
|
3994
3889
|
}
|
|
3995
|
-
return normalized.changed ?
|
|
3890
|
+
return normalized.changed || serviceTier.changed ? serviceTier.payload : undefined;
|
|
3996
3891
|
});
|
|
3997
3892
|
|
|
3998
3893
|
function freshModelRouteBoundary(ctx: ExtensionContext): boolean {
|
|
@@ -4073,6 +3968,15 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4073
3968
|
}
|
|
4074
3969
|
}
|
|
4075
3970
|
|
|
3971
|
+
function preferApplyPatchBeforeWriters(toolNames: string[]): string[] {
|
|
3972
|
+
if (!toolNames.includes("apply_patch")) return [...toolNames];
|
|
3973
|
+
const withoutPatch = toolNames.filter((toolName) => toolName !== "apply_patch");
|
|
3974
|
+
const firstWriter = withoutPatch.findIndex((toolName) => toolName === "edit" || toolName === "write");
|
|
3975
|
+
if (firstWriter < 0) return [...toolNames];
|
|
3976
|
+
withoutPatch.splice(firstWriter, 0, "apply_patch");
|
|
3977
|
+
return withoutPatch;
|
|
3978
|
+
}
|
|
3979
|
+
|
|
4076
3980
|
function activateToolGroups(ctx: ExtensionContext, groups: PiagentToolGroup[], additive = false): string[] {
|
|
4077
3981
|
const current = pi.getActiveTools();
|
|
4078
3982
|
if (!dynamicToolsEnabled) return current;
|
|
@@ -4091,7 +3995,7 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4091
3995
|
}
|
|
4092
3996
|
}
|
|
4093
3997
|
const ordered = [
|
|
4094
|
-
...current.filter((toolName) => selected.has(toolName) && !PIAGENT_TOOL_NAMES.has(toolName)),
|
|
3998
|
+
...preferApplyPatchBeforeWriters(current.filter((toolName) => selected.has(toolName) && !PIAGENT_TOOL_NAMES.has(toolName))),
|
|
4095
3999
|
...PIAGENT_TOOL_ORDER.filter((toolName) => selected.has(toolName))
|
|
4096
4000
|
];
|
|
4097
4001
|
const unchanged = ordered.length === current.length && ordered.every((toolName, index) => toolName === current[index]);
|
|
@@ -4120,25 +4024,28 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4120
4024
|
let recordedClassification: FailureClassification | undefined;
|
|
4121
4025
|
try {
|
|
4122
4026
|
const replay = replayTaskCheckpoints(ctx.cwd, task.taskRunId, task);
|
|
4123
|
-
if (replay.corruptions.length === 0)
|
|
4124
|
-
|
|
4125
|
-
|
|
4126
|
-
.at(-1) as any;
|
|
4127
|
-
recordedClassification = checkpoint?.evidence?.failureClassification as FailureClassification | undefined;
|
|
4128
|
-
}
|
|
4027
|
+
if (replay.corruptions.length === 0 && failed) recordedClassification = recordedFailureForObservation(
|
|
4028
|
+
replay.checkpoints, failed, currentTreeDigest, currentWorkspaceRevisionDigest(ctx.cwd)
|
|
4029
|
+
) as FailureClassification | undefined;
|
|
4129
4030
|
} catch {
|
|
4130
4031
|
// A missing/corrupt journal cannot grant recovery mutation; the fallback
|
|
4131
4032
|
// classifier remains fail-closed for unknown evidence.
|
|
4132
4033
|
}
|
|
4133
|
-
const
|
|
4034
|
+
const gateClassification = selectCompletionRecoveryClassification(
|
|
4134
4035
|
recordedClassification,
|
|
4135
4036
|
gate?.missing,
|
|
4136
4037
|
summary,
|
|
4137
4038
|
failed?.exitCode ?? 1
|
|
4138
4039
|
);
|
|
4040
|
+
const independentRecovery = independentVerificationRecovery(ctx.cwd, task, currentTreeDigest ?? workingTreeEvidenceDigest(workingTreeSnapshot(ctx.cwd)));
|
|
4041
|
+
const classification = gateClassification.category === "scope-protected-path"
|
|
4042
|
+
? gateClassification : independentRecovery?.classification ?? gateClassification;
|
|
4139
4043
|
const trajectory = trajectoryRuntime.status(ctx.cwd, task.taskRunId);
|
|
4140
|
-
|
|
4141
|
-
|
|
4044
|
+
// Task scope is a retrieval/review hint, not filesystem authority. Recovery
|
|
4045
|
+
// may update a dependency or config file when repository evidence requires
|
|
4046
|
+
// it; protected-path and approval policy still run on the exact call.
|
|
4047
|
+
const dependencyMutationAuthorized = true;
|
|
4048
|
+
const selected = selectRecoveryDecision({
|
|
4142
4049
|
featureEnabled: autoRecoveryEnabled && taskAuthorityDecision(task, "CAP-12", "model-turn").allowed,
|
|
4143
4050
|
task: {
|
|
4144
4051
|
taskId: task.taskId,
|
|
@@ -4150,13 +4057,16 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4150
4057
|
classification,
|
|
4151
4058
|
currentPhase: trajectory.enforcementSafe ? trajectory.phase ?? "verify" : "handoff",
|
|
4152
4059
|
history: runtimeState.recoveryHistory(task.taskId),
|
|
4153
|
-
proposedHypothesisRef: classification.reasonCodes[0] ? `reason:${classification.reasonCodes[0]}` : null,
|
|
4060
|
+
proposedHypothesisRef: independentRecovery?.hypothesisRef ?? (classification.reasonCodes[0] ? `reason:${classification.reasonCodes[0]}` : null),
|
|
4154
4061
|
exactVerifierAvailable: (gate?.missingVerifyCommands.length ?? task.verifyCommands.length) > 0,
|
|
4155
4062
|
currentTreeMatchesEvidence: currentTreeDigest && latestExactVerifier?.workingTreeDigest
|
|
4156
|
-
? currentTreeDigest === latestExactVerifier.workingTreeDigest
|
|
4063
|
+
? currentTreeDigest === latestExactVerifier.workingTreeDigest && latestExactVerifier.preWorkspaceRevisionDigest === currentWorkspaceRevisionDigest(ctx.cwd)
|
|
4064
|
+
&& latestExactVerifier.workspaceRevisionDigest === latestExactVerifier.preWorkspaceRevisionDigest
|
|
4157
4065
|
: true,
|
|
4158
|
-
dependencyMutationAuthorized
|
|
4066
|
+
dependencyMutationAuthorized,
|
|
4067
|
+
independentDisposition: independentRecovery?.independentDisposition
|
|
4159
4068
|
});
|
|
4069
|
+
return applyProofCapabilityHandoff(selected, gate?.missing, Boolean(independentRecovery));
|
|
4160
4070
|
}
|
|
4161
4071
|
|
|
4162
4072
|
function trajectoryRecoveryOptions(ctx: ExtensionContext, task: TaskContract, options: any): any {
|
|
@@ -4194,6 +4104,7 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4194
4104
|
resolveTaskAny: (cwd, reference) => resolveTaskContract(cwd, reference, undefined) as TaskContract | undefined,
|
|
4195
4105
|
bindTask: bindSessionTask,
|
|
4196
4106
|
writeTask,
|
|
4107
|
+
appendTrace,
|
|
4197
4108
|
capabilityState: (ctx) => verifyProjectCapabilityState(extensionDir, ctx.cwd, ctx.isProjectTrusted(), { allowRepin: true, forceFull: true, sessionId: ctx.sessionManager.getSessionId() }),
|
|
4198
4109
|
permissionProfile: (ctx, profile) => resolvePermissionProfile(profile, policy, permissionOverrideFromContext(ctx)),
|
|
4199
4110
|
legacyProjectWarning: legacyProjectStateWarning,
|
|
@@ -4221,7 +4132,15 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4221
4132
|
})));
|
|
4222
4133
|
},
|
|
4223
4134
|
telemetry,
|
|
4224
|
-
afterStart: async (ctx) => {
|
|
4135
|
+
afterStart: async (ctx) => {
|
|
4136
|
+
await independentAcceptance.activate(ctx);
|
|
4137
|
+
const serviceTier = serviceTierRuntime.restore(ctx);
|
|
4138
|
+
if (serviceTier.enabled && serviceTier.reasonCode === "provider-not-supported") {
|
|
4139
|
+
ctx.ui.notify("Piagent Fast mode is enabled, but the active provider is not OpenAI Codex; no service tier was changed.", "warning");
|
|
4140
|
+
}
|
|
4141
|
+
sourceMutationGuardBindings.bind(ctx);
|
|
4142
|
+
await activityInspector.refresh(ctx);
|
|
4143
|
+
}
|
|
4225
4144
|
});
|
|
4226
4145
|
|
|
4227
4146
|
registerSessionHooks(pi, {
|
|
@@ -4235,12 +4154,17 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4235
4154
|
flushObservedTaskContext,
|
|
4236
4155
|
onTurnEnd: activityInspector.refresh,
|
|
4237
4156
|
onAgentSettled: activityInspector.refresh,
|
|
4238
|
-
beforeShutdown: (ctx) => {
|
|
4157
|
+
beforeShutdown: async (ctx) => {
|
|
4158
|
+
await independentAcceptance.clear(ctx);
|
|
4159
|
+
serviceTierRuntime.forget(ctx);
|
|
4239
4160
|
sourceMutationGuardBindings.unbind(ctx);
|
|
4161
|
+
editFreshnessGuard.clear(ctx);
|
|
4240
4162
|
activityInspector.dispose(ctx);
|
|
4241
4163
|
sessionCapabilityDigests.delete(`${ctx.cwd}\0${ctx.sessionManager.getSessionId()}`);
|
|
4242
4164
|
}
|
|
4243
4165
|
});
|
|
4166
|
+
registerTaskUsageHooks(pi, { activeTask: (ctx) => activeSessionTask(ctx.cwd, ctx.sessionManager.getSessionId()) as TaskContract | undefined, telemetry });
|
|
4167
|
+
pi.on("turn_end", (event, ctx) => independentAcceptance.observeTurnEnd(ctx, event.message));
|
|
4244
4168
|
|
|
4245
4169
|
registerInputHook(pi, {
|
|
4246
4170
|
state: runtimeState,
|
|
@@ -4292,10 +4216,15 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4292
4216
|
|
|
4293
4217
|
registerCompletionHook(pi, {
|
|
4294
4218
|
state: runtimeState,
|
|
4219
|
+
prepareIndependentAcceptance: (ctx, task, response) => independentAcceptance.prepare(ctx, task, response),
|
|
4220
|
+
deferIndependentCompletion: (ctx, task, response, finalizer) => independentAcceptance.deferCompletion(ctx, task, response, finalizer),
|
|
4221
|
+
projectIndependentLifecycle: (ctx, task, candidate) => independentAcceptance.projectLifecycle(ctx, task, candidate),
|
|
4222
|
+
nativeRefusalFallbackAllowed: () => !independentVerificationConfigPath,
|
|
4295
4223
|
maxManifestFiles: contextBudgetConfig(policy).maxManifestFiles,
|
|
4296
4224
|
activeTask: (ctx) => activeSessionTask(ctx.cwd, ctx.sessionManager.getSessionId()) as TaskContract | undefined,
|
|
4297
4225
|
flushObservedTaskContext,
|
|
4298
4226
|
completionProjection: completionTaskProjection,
|
|
4227
|
+
acceptanceEvidenceFiles: taskAcceptanceEvidenceFiles,
|
|
4299
4228
|
evaluateGate: (cwd, task, currentDigests, currentDigest) => {
|
|
4300
4229
|
const gate = evaluateTaskGate(cwd, task, policy, { currentDigests, currentWorkingTreeDigest: currentDigest });
|
|
4301
4230
|
const repairBlock = (taskAuthorityDecision(task, "CAP-13", "block").allowed
|
|
@@ -4327,13 +4256,43 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4327
4256
|
redactText,
|
|
4328
4257
|
observedTaskContext: observedTaskContextFromToolResult,
|
|
4329
4258
|
recordObservedTaskChanges,
|
|
4330
|
-
recordObservedTaskVerification,
|
|
4259
|
+
recordObservedTaskVerification: (...args) => recordObservedTaskVerification(...args, policy.finalGate?.acceptanceProofMode === "diagnostic"),
|
|
4331
4260
|
extractLikelyPath: extractLikelyPathFromInput,
|
|
4332
4261
|
mutationTargets: taskMutationTargets,
|
|
4333
4262
|
isShellTool: (toolName) => SHELL_TOOL_NAMES.has(toolName),
|
|
4334
4263
|
telemetry,
|
|
4335
4264
|
activity: recordActivity,
|
|
4336
4265
|
now: nowIso,
|
|
4266
|
+
recordSubagentResult: (ctx, event, result) => {
|
|
4267
|
+
const task = activeSessionTask(ctx.cwd, ctx.sessionManager.getSessionId()) as TaskContract | undefined;
|
|
4268
|
+
const written = recordDirectSubagentResult(task, event, result, {
|
|
4269
|
+
now: nowIso,
|
|
4270
|
+
persist: (candidate) => writeTask(ctx.cwd, candidate),
|
|
4271
|
+
trace: (payload) => appendTrace(ctx.cwd, payload),
|
|
4272
|
+
sessionTrace: (payload) => appendSessionTrace(pi, payload)
|
|
4273
|
+
});
|
|
4274
|
+
telemetry(ctx, {
|
|
4275
|
+
event: "helper_result_classified",
|
|
4276
|
+
recordedAt: nowIso(),
|
|
4277
|
+
taskRunId: written?.taskRunId,
|
|
4278
|
+
toolCallId: event.toolCallId,
|
|
4279
|
+
spawned: result.spawned,
|
|
4280
|
+
failed: result.failed,
|
|
4281
|
+
disposition: result.disposition,
|
|
4282
|
+
reasonCode: result.reasonCode,
|
|
4283
|
+
calls: result.calls,
|
|
4284
|
+
tokens: result.tokens
|
|
4285
|
+
});
|
|
4286
|
+
},
|
|
4287
|
+
observeEditFreshness: (ctx, event, metadata) => {
|
|
4288
|
+
if (!metadata.successful || !metadata.taskRunId) return;
|
|
4289
|
+
const protectedPaths = effectiveProtectedPaths(policy, loadProfileFromContext(ctx)).readProtectedPaths;
|
|
4290
|
+
const source = event.toolName === "read" ? "read" : ["edit", "write", "apply_patch"].includes(event.toolName) ? "mutation" : undefined;
|
|
4291
|
+
const candidates = source === "read" && metadata.targetPath ? [metadata.targetPath] : source === "mutation" ? metadata.mutationTargets : [];
|
|
4292
|
+
const safeTargets = candidates.filter((file) => !matchesProtectedPath(file, protectedPaths));
|
|
4293
|
+
const observed = source ? editFreshnessGuard.observe(ctx, metadata.taskRunId, safeTargets, source, nowIso()) : [];
|
|
4294
|
+
if (observed.length) telemetry(ctx, { event: "edit_freshness_snapshot_observed", taskRunId: metadata.taskRunId, source, paths: observed.map(redactText) });
|
|
4295
|
+
},
|
|
4337
4296
|
completeSemanticRepair: (ctx, event, metadata) => {
|
|
4338
4297
|
const task = activeSessionTask(ctx.cwd, ctx.sessionManager.getSessionId()) as TaskContract | undefined;
|
|
4339
4298
|
return task && (taskAuthorityDecision(task, "CAP-13", "mutate").allowed
|
|
@@ -4354,10 +4313,43 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4354
4313
|
activity: recordActivity,
|
|
4355
4314
|
beforeAuthorize: (event, ctx) => {
|
|
4356
4315
|
const toolInput = isPlainRecord(event.input) ? event.input : {};
|
|
4316
|
+
const task = activeSessionTask(ctx.cwd, ctx.sessionManager.getSessionId()) as TaskContract | undefined;
|
|
4317
|
+
const helperPreflight = evaluateDirectSubagentDispatch({
|
|
4318
|
+
toolName: event.toolName,
|
|
4319
|
+
toolInput,
|
|
4320
|
+
cwd: ctx.cwd,
|
|
4321
|
+
helpersMode: task ? taskHelperUsageMode(task) : helpersMode(),
|
|
4322
|
+
taskPending: task?.trace.outcome === "pending",
|
|
4323
|
+
dispatchAuthority: Boolean(task && taskAuthorityDecision(task, "CAP-14", "dispatch").allowed),
|
|
4324
|
+
durableSubagentState: task?.orchestration?.subagents
|
|
4325
|
+
});
|
|
4326
|
+
if (helperPreflight.applicable && helperPreflight.dispatch && !helperPreflight.allowed) {
|
|
4327
|
+
telemetry(ctx, {
|
|
4328
|
+
event: "helper_dispatch_blocked",
|
|
4329
|
+
recordedAt: nowIso(),
|
|
4330
|
+
taskRunId: task?.taskRunId,
|
|
4331
|
+
toolCallId: event.toolCallId,
|
|
4332
|
+
reasonCode: helperPreflight.reasonCode,
|
|
4333
|
+
role: helperPreflight.role,
|
|
4334
|
+
requestCount: helperPreflight.requestCount
|
|
4335
|
+
});
|
|
4336
|
+
return { block: true, reason: `Blocked ${event.toolName}: ${helperPreflight.reason} Do not retry this helper; continue in the parent.` };
|
|
4337
|
+
}
|
|
4338
|
+
const verifierReuse = reuseCurrentTreeExactVerifier({ cwd: ctx.cwd, task, toolName: event.toolName, toolInput, sessionEntries: ctx.sessionManager.getEntries() as unknown[],
|
|
4339
|
+
getHostProjectVerificationDigest: (snapshot, command) => task ? runtimeState.projectVerification.currentDigest(ctx, task, snapshot, command) : null });
|
|
4340
|
+
if (verifierReuse.reused) {
|
|
4341
|
+
telemetry(ctx, { event: "verifier_evidence_reused", recordedAt: nowIso(), taskRunId: task?.taskRunId, toolCallId: event.toolCallId, reasonCode: verifierReuse.reasonCode, commandDigest: verifierReuse.commandDigest, workingTreeDigest: verifierReuse.workingTreeDigest }); return;
|
|
4342
|
+
}
|
|
4357
4343
|
const targetInspection = authorizationMutationTargetInspection(ctx.cwd, event.toolName, toolInput);
|
|
4358
4344
|
if (targetInspection.reason) return { block: true, reason: `Blocked ${event.toolName}: ${targetInspection.reason}.` };
|
|
4345
|
+
if (task?.trace.outcome === "pending" && task.changeMode === "source-change" && (event.toolName === "edit" || targetInspection.exactLocalPatchExecutor)) {
|
|
4346
|
+
const freshness = editFreshnessGuard.evaluate(ctx, task.taskRunId, targetInspection.targets);
|
|
4347
|
+
if (freshness.decision === "stale") {
|
|
4348
|
+
telemetry(ctx, { event: "edit_freshness_stale", taskRunId: task.taskRunId, toolCallId: event.toolCallId, enforce: freshness.enforce, paths: freshness.stalePaths.map(redactText) });
|
|
4349
|
+
if (freshness.enforce) return { block: true, reason: `Blocked ${event.toolName}: the previously observed source snapshot is stale for ${freshness.stalePaths.map(redactText).join(", ")}. Reread the affected file once; no patch hunk was started.` };
|
|
4350
|
+
}
|
|
4351
|
+
}
|
|
4359
4352
|
if (!["edit", "write"].includes(event.toolName) && !targetInspection.exactLocalPatchExecutor) return;
|
|
4360
|
-
const task = activeSessionTask(ctx.cwd, ctx.sessionManager.getSessionId()) as TaskContract | undefined;
|
|
4361
4353
|
if (!task || task.trace.outcome !== "pending" || task.changeMode !== "source-change") return;
|
|
4362
4354
|
const semanticRepairEnabled = taskAuthorityDecision(task, "CAP-13", "mutate").allowed;
|
|
4363
4355
|
const semanticRepairExactlyOff = !taskAuthorityDecision(task, "CAP-13", "observe").allowed;
|
|
@@ -4374,11 +4366,10 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4374
4366
|
const currentDigest = workingTreeEvidenceDigest(currentSnapshot);
|
|
4375
4367
|
const expectedReviewPaths = taskDeltaFilesFromSnapshot(task, currentSnapshot);
|
|
4376
4368
|
const targets = targetInspection.targets;
|
|
4377
|
-
const
|
|
4378
|
-
|
|
4379
|
-
const verifierCurrent = allVerifyCommandsPassCurrentTree(task, currentDigest);
|
|
4369
|
+
const boundedTargetMutation = targets.length > 0;
|
|
4370
|
+
const verifierCurrent = allVerifyCommandsPassCurrentTree(task, currentDigest, currentWorkspaceRevisionDigest(ctx.cwd));
|
|
4380
4371
|
|
|
4381
|
-
if (phase.phase === "verify" &&
|
|
4372
|
+
if (phase.phase === "verify" && boundedTargetMutation && semanticRepairEnabled && semanticRepairRuntime.prepare({
|
|
4382
4373
|
ctx, task, event, currentDigest, currentDeltaPaths: expectedReviewPaths, targetPaths: targets,
|
|
4383
4374
|
verifierCurrent
|
|
4384
4375
|
})) return;
|
|
@@ -4388,7 +4379,7 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4388
4379
|
// model catches its own omission in the same task/run/session. The call
|
|
4389
4380
|
// still traverses every normal authorization check; verify -> repair is
|
|
4390
4381
|
// committed only by the tool-result hook after a successful tree change.
|
|
4391
|
-
if (phase.phase === "verify" && boundedRecoveryEnabled && verifierCurrent &&
|
|
4382
|
+
if (phase.phase === "verify" && boundedRecoveryEnabled && verifierCurrent && boundedTargetMutation) {
|
|
4392
4383
|
const authoredFileDigests = runtimeState.successfulModelMutationDigests(
|
|
4393
4384
|
{ taskId: task.taskId, taskRunId: task.taskRunId, sessionId: task.sessionId },
|
|
4394
4385
|
currentSnapshot
|
|
@@ -4436,7 +4427,7 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4436
4427
|
return reviewDecision;
|
|
4437
4428
|
}
|
|
4438
4429
|
|
|
4439
|
-
if (targets.length === 0
|
|
4430
|
+
if (targets.length === 0) return;
|
|
4440
4431
|
const result = trajectoryRuntime.sync(ctx.cwd, ctx.sessionManager.getSessionId(), task, {
|
|
4441
4432
|
sourceHook: "tool-call",
|
|
4442
4433
|
recoveryRequested: true,
|
|
@@ -4460,11 +4451,9 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4460
4451
|
const targetInspection = authorizationMutationTargetInspection(ctx.cwd, event.toolName, toolInput);
|
|
4461
4452
|
if (targetInspection.reason) return { block: true, reason: `Blocked ${event.toolName}: ${targetInspection.reason}.` };
|
|
4462
4453
|
const targets = targetInspection.targets;
|
|
4463
|
-
if ((["edit", "write"].includes(event.toolName) || targetInspection.patchCarrier) &&
|
|
4464
|
-
targets.length === 0 || targets.some((file) => !taskScopeIncludesPath(task.scope, file))
|
|
4465
|
-
)) {
|
|
4454
|
+
if ((["edit", "write"].includes(event.toolName) || targetInspection.patchCarrier) && targets.length === 0) {
|
|
4466
4455
|
runtimeState.denyPerformanceReviewTool(task.taskRunId);
|
|
4467
|
-
return { block: true, reason: `Task ${task.taskId} semantic repair
|
|
4456
|
+
return { block: true, reason: `Task ${task.taskId} semantic repair requires an exact statically bounded target.` };
|
|
4468
4457
|
}
|
|
4469
4458
|
const reviewDecision = performanceReviewToolDecision({
|
|
4470
4459
|
toolName: event.toolName,
|
|
@@ -4492,6 +4481,30 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4492
4481
|
},
|
|
4493
4482
|
afterAuthorized: (event, ctx, metadata) => {
|
|
4494
4483
|
const task = activeSessionTask(ctx.cwd, ctx.sessionManager.getSessionId()) as TaskContract | undefined;
|
|
4484
|
+
const helperPreflight = evaluateDirectSubagentDispatch({
|
|
4485
|
+
toolName: event.toolName,
|
|
4486
|
+
toolInput: event.input,
|
|
4487
|
+
cwd: ctx.cwd,
|
|
4488
|
+
helpersMode: task ? taskHelperUsageMode(task) : helpersMode(),
|
|
4489
|
+
taskPending: task?.trace.outcome === "pending",
|
|
4490
|
+
dispatchAuthority: Boolean(task && taskAuthorityDecision(task, "CAP-14", "dispatch").allowed),
|
|
4491
|
+
durableSubagentState: task?.orchestration?.subagents
|
|
4492
|
+
});
|
|
4493
|
+
if (helperPreflight.applicable && helperPreflight.dispatch && helperPreflight.allowed) {
|
|
4494
|
+
const reserved = reserveDirectSubagentDispatch(task, metadata.toolCallId, {
|
|
4495
|
+
now: nowIso,
|
|
4496
|
+
persist: (candidate) => writeTask(ctx.cwd, candidate),
|
|
4497
|
+
trace: (payload) => appendTrace(ctx.cwd, payload)
|
|
4498
|
+
});
|
|
4499
|
+
telemetry(ctx, {
|
|
4500
|
+
event: "helper_dispatch_reserved",
|
|
4501
|
+
recordedAt: nowIso(),
|
|
4502
|
+
taskRunId: reserved?.taskRunId,
|
|
4503
|
+
toolCallId: metadata.toolCallId,
|
|
4504
|
+
role: helperPreflight.role,
|
|
4505
|
+
requestCount: helperPreflight.requestCount
|
|
4506
|
+
});
|
|
4507
|
+
}
|
|
4495
4508
|
if (task?.trace.outcome === "pending") {
|
|
4496
4509
|
const snapshot = workingTreeSnapshot(ctx.cwd) as Record<string, string>;
|
|
4497
4510
|
const currentDigest = workingTreeEvidenceDigest(snapshot);
|
|
@@ -4604,7 +4617,7 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4604
4617
|
const governedTaskProfile = !profileMode.startsWith("unprofiled") && !profileMode.includes("unreadable");
|
|
4605
4618
|
const taskContractRequired = governedTaskProfile
|
|
4606
4619
|
&& runtime.finalGate === "enforce"
|
|
4607
|
-
&& finalGateConfig(policy).requireTaskContract;
|
|
4620
|
+
&& finalGateConfig(policy, DEFAULT_POLICY).requireTaskContract;
|
|
4608
4621
|
if (sessionTask?.trace.outcome === "pending" && (sessionTask.changeMode === "read-only" || sessionTask.mutationPolicy === "forbidden")
|
|
4609
4622
|
&& !SHELL_TOOL_NAMES.has(event.toolName) && isTaskMutationTool(event.toolName, toolInput)) {
|
|
4610
4623
|
return {
|
|
@@ -4639,7 +4652,13 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4639
4652
|
const execDecision = evaluateExecPolicy(command, profile, policy);
|
|
4640
4653
|
authorizedShellCommand = command;
|
|
4641
4654
|
authorizedShellSegments = execDecision.segments;
|
|
4642
|
-
|
|
4655
|
+
if (shellTouchesGrantedSourceCheckout(ctx.cwd, command, runtimeState.sourceCheckoutReadRoots(ctx))) {
|
|
4656
|
+
return {
|
|
4657
|
+
block: true,
|
|
4658
|
+
reason: "Shared source checkouts are shell-inaccessible. Inspect the exact session-granted checkout with read, grep, find, or ls; cache mutation is never authorized."
|
|
4659
|
+
};
|
|
4660
|
+
}
|
|
4661
|
+
shellProjectMutation = isProjectMutatingShellCommand(command, execDecision.segments, ctx.cwd);
|
|
4643
4662
|
configuredVerifierShell = Boolean(sessionTask && commandMatchesVerifyPlan(command, sessionTask.verifyCommands));
|
|
4644
4663
|
const shellWriteCandidates = extractShellWritePathCandidates(command);
|
|
4645
4664
|
shellMutationTargetBounded = shellWriteCandidates.length > 0;
|
|
@@ -4655,7 +4674,7 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4655
4674
|
const mutationForbidden = sessionTask?.trace.outcome === "pending"
|
|
4656
4675
|
&& (sessionTask.changeMode === "read-only" || sessionTask.mutationPolicy === "forbidden");
|
|
4657
4676
|
const exactForbiddenTaskVerifier = mutationForbidden && sessionTask.changeMode === "source-change" && configuredVerifierShell;
|
|
4658
|
-
if (mutationForbidden && !exactForbiddenTaskVerifier && !isReadOnlyTaskShellCommand(command, execDecision.segments)) {
|
|
4677
|
+
if (mutationForbidden && !exactForbiddenTaskVerifier && !isReadOnlyTaskShellCommand(command, execDecision.segments, ctx.cwd)) {
|
|
4659
4678
|
return {
|
|
4660
4679
|
block: true,
|
|
4661
4680
|
reason: `Task ${sessionTask.taskId} ${sessionTask.changeMode === "read-only" ? "is read-only; this shell command is not in the read-only inspection allowlist" : "forbids source mutation; this shell command is neither bounded inspection nor an exact configured verifier"}.`
|
|
@@ -4730,7 +4749,8 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4730
4749
|
{
|
|
4731
4750
|
forceScopeAware: authorizationTargetInspection.patchCarrier || Boolean(preparedInput.proxyToolName),
|
|
4732
4751
|
forceWrite: authorizationTargetInspection.patchCarrier || preparedInput.proxyAction?.decision === "confirm",
|
|
4733
|
-
allowAmbiguousFilesystemContentFields: !usesKnownExternalProvider && !isPiagentTool(event.toolName)
|
|
4752
|
+
allowAmbiguousFilesystemContentFields: !usesKnownExternalProvider && !isPiagentTool(event.toolName),
|
|
4753
|
+
sourceCheckoutReadRoots: runtimeState.sourceCheckoutReadRoots(ctx)
|
|
4734
4754
|
}
|
|
4735
4755
|
);
|
|
4736
4756
|
if (pathDecision.block) {
|
|
@@ -4816,32 +4836,18 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4816
4836
|
+ " Call `piagent_task_start` once with explicit project-relative scope, then retry."
|
|
4817
4837
|
};
|
|
4818
4838
|
}
|
|
4819
|
-
if (
|
|
4820
|
-
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
}
|
|
4830
|
-
}
|
|
4831
|
-
const outsideScope = mutationTargets.filter((file) => !taskScopeIncludesPath(sessionTask.scope, file));
|
|
4832
|
-
if (outsideScope.length > 0) {
|
|
4833
|
-
return {
|
|
4834
|
-
block: true,
|
|
4835
|
-
reason: `Task ${sessionTask.taskId} cannot mutate paths outside its declared scope: ${outsideScope.join(", ")}.`
|
|
4836
|
-
};
|
|
4837
|
-
}
|
|
4838
|
-
const outsideEvidenceRoot = mutationTargets.filter((file) => !pathWithinChangeEvidenceRoot(ctx.cwd, file));
|
|
4839
|
-
if (outsideEvidenceRoot.length > 0) {
|
|
4840
|
-
return {
|
|
4841
|
-
block: true,
|
|
4842
|
-
reason: `Task ${sessionTask.taskId} cannot mutate paths outside a change evidence root: ${outsideEvidenceRoot.join(", ")}. In a parent workspace with separate repos, write under a child repo or a scoped workspace directory such as plans/**.`
|
|
4843
|
-
};
|
|
4844
|
-
}
|
|
4839
|
+
if (
|
|
4840
|
+
sessionTask?.trace.outcome === "pending"
|
|
4841
|
+
&& sessionTask.changeMode === "source-change"
|
|
4842
|
+
&& shellProjectMutation
|
|
4843
|
+
&& opaqueShellMutationNeedsBoundedTarget(authorizedShellCommand, authorizedShellSegments)
|
|
4844
|
+
&& !shellMutationTargetBounded
|
|
4845
|
+
&& !configuredVerifierShell
|
|
4846
|
+
) {
|
|
4847
|
+
return {
|
|
4848
|
+
block: true,
|
|
4849
|
+
reason: `Task ${sessionTask.taskId} cannot run an opaque shell mutation whose write target is not statically bounded. Use edit/write/apply_patch, an explicit project-local redirection, or the exact configured verifier.`
|
|
4850
|
+
};
|
|
4845
4851
|
}
|
|
4846
4852
|
if (runtime.contextBudget !== "off" && (["write", "edit"].includes(event.toolName) || authorizationTargetInspection.patchCarrier)) {
|
|
4847
4853
|
const budgetTargets = authorizationTargetInspection.patchCarrier
|
|
@@ -4873,7 +4879,7 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4873
4879
|
&& sessionTask.changeMode === "source-change"
|
|
4874
4880
|
&& (shellProjectMutation || configuredVerifierShell)
|
|
4875
4881
|
) {
|
|
4876
|
-
runtimeState.rememberShellMutationSnapshot(ctx, event.toolName, event.input);
|
|
4882
|
+
runtimeState.rememberShellMutationSnapshot(ctx, event.toolName, event.input, event.toolCallId);
|
|
4877
4883
|
}
|
|
4878
4884
|
}
|
|
4879
4885
|
});
|
|
@@ -4895,6 +4901,8 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4895
4901
|
createTaskRunId, crypto, currentSessionName, defaultRolePolicy, defaultWorkPlan, digestJson,
|
|
4896
4902
|
dynamicToolsEnabled, effectiveProtectedPaths, emitRuntimeMessage, ensureContextIndexV2, estimateContextTokens,
|
|
4897
4903
|
evaluateExecPolicy, evaluateModelRoute, evaluateRetrievalRoute, evaluateRuntimeSolver, evaluateTaskGate, evaluateToolPolicy, execPolicyConfig,
|
|
4904
|
+
prepareIndependentAcceptance: (ctx: ExtensionContext, task: TaskContract, response?: { origin: "assistant"; bytes: string }) =>
|
|
4905
|
+
independentAcceptance.prepare(ctx, task, response),
|
|
4898
4906
|
extensionDir, externalActionPolicyConfig, extractDocument, finalGateConfig, findMatchingObservedBashResult,
|
|
4899
4907
|
formatContextPreflight, formatCount, formatLiveTaskStatus, formatPercent, formatTechOptionsText, formatTechSelectionSummary,
|
|
4900
4908
|
formatToolResultCaptureStatus, formatUsageSnapshot, fs, hasGitEvidenceRoot, hasOperatorSessionName, helpersMode,
|
|
@@ -4912,7 +4920,7 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4912
4920
|
safeTaskId, searchContextIndex, searchContextIndexV2, searchMemoryFiles, selectRuntimeAction,
|
|
4913
4921
|
selectValueFromUi, selectVerificationPlan, semanticCompactionInstructions, sendWorkflowFollowUp, setPermissionOverrideForContext,
|
|
4914
4922
|
semanticRepairCompletionBlock: (cwd: string, taskRunId: string) => semanticRepairRuntime.completionBlock(cwd, taskRunId),
|
|
4915
|
-
freshRequestParts, shellArg, shortTaskLabel, solverShadow, summarizeAttempt, taskChangedFileEvidence,
|
|
4923
|
+
freshRequestParts, shellArg, shortTaskLabel, solverShadow, summarizeAttempt, taskAcceptanceEvidenceFiles, taskChangedFileEvidence,
|
|
4916
4924
|
techContextDirPath, techContextFilePath, techContextRelativePath, techOptionById, techStackPath,
|
|
4917
4925
|
telemetry, toolRegistryConfig, trajectoryRuntime, uniqueStrings, usageExactCommands,
|
|
4918
4926
|
validTaskScopePattern, validateNewWorkPlan, verifierCommandInstructions, verifyProjectCapabilityState, workingTreeEvidenceDigest,
|
|
@@ -4943,9 +4951,10 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4943
4951
|
|
|
4944
4952
|
function commandArgs(raw: string): { action: string; rest: string; tokens: string[] } {
|
|
4945
4953
|
const trimmed = String(raw ?? "").trim();
|
|
4946
|
-
const
|
|
4947
|
-
const action = (
|
|
4948
|
-
|
|
4954
|
+
const match = /^(\S+)(?:\s+([\s\S]*))?$/.exec(trimmed);
|
|
4955
|
+
const action = (match?.[1] ?? "").toLowerCase();
|
|
4956
|
+
const rest = match?.[2] ?? "";
|
|
4957
|
+
return { action, rest, tokens: rest.split(/\s+/).filter(Boolean) };
|
|
4949
4958
|
}
|
|
4950
4959
|
|
|
4951
4960
|
function shellArg(value: string): string {
|
|
@@ -4977,6 +4986,7 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4977
4986
|
}
|
|
4978
4987
|
|
|
4979
4988
|
registerPermissionCommands(pi, registrationDeps);
|
|
4989
|
+
registerFastModeCommand(pi, serviceTierRuntime);
|
|
4980
4990
|
const profileCommandApi = registerProfileCommands(pi, registrationDeps);
|
|
4981
4991
|
registerMemoryMcpCommands(pi, registrationDeps);
|
|
4982
4992
|
const contextCommandApi = registerContextCommands(pi, registrationDeps);
|