@unbrained/pm-cli 2026.9.6 → 2026.9.8
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/.agents/skills/pm-developer/SKILL.md +12 -4
- package/.agents/skills/pm-developer/references/MULTI_AGENT_MERGE.md +19 -10
- package/.agents/skills/pm-extensions/SKILL.md +6 -0
- package/.agents/skills/pm-sdk/SKILL.md +11 -2
- package/.agents/skills/pm-user/SKILL.md +5 -0
- package/.agents/skills/pm-user/references/ECOSYSTEM_PLANNING.md +95 -0
- package/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +218 -182
- package/dist/cli/after-command-context-usage.js +1 -48
- package/dist/cli/argv-utils.js +1 -40
- package/dist/cli/bootstrap-args.js +1 -9
- package/dist/cli/bundle-integrity.js +2 -110
- package/dist/cli/commander-usage.js +11 -771
- package/dist/cli/commands/activity.js +1 -9
- package/dist/cli/commands/aggregate.js +1 -5
- package/dist/cli/commands/append.js +1 -5
- package/dist/cli/commands/claim.js +1 -5
- package/dist/cli/commands/close-many.js +1 -5
- package/dist/cli/commands/close.js +1 -9
- package/dist/cli/commands/comments.js +1 -5
- package/dist/cli/commands/config.js +1 -9
- package/dist/cli/commands/context.js +1 -9
- package/dist/cli/commands/contracts.js +1 -5
- package/dist/cli/commands/copy.js +1 -9
- package/dist/cli/commands/create.js +1 -9
- package/dist/cli/commands/delete.js +1 -9
- package/dist/cli/commands/deps.js +1 -9
- package/dist/cli/commands/docs.js +1 -9
- package/dist/cli/commands/duplicates.js +1 -9
- package/dist/cli/commands/eval.js +1 -9
- package/dist/cli/commands/extension/describe.js +1 -5
- package/dist/cli/commands/extension/scaffold.js +1 -5
- package/dist/cli/commands/extension/shared.js +1 -5
- package/dist/cli/commands/extension.js +1 -9
- package/dist/cli/commands/files.js +1 -9
- package/dist/cli/commands/focus.js +1 -9
- package/dist/cli/commands/gc.js +1 -9
- package/dist/cli/commands/get.js +1 -9
- package/dist/cli/commands/graph.js +1 -10
- package/dist/cli/commands/health.js +1 -9
- package/dist/cli/commands/history-compact.js +1 -10
- package/dist/cli/commands/history-redact.js +1 -11
- package/dist/cli/commands/history-repair.js +1 -10
- package/dist/cli/commands/history.js +1 -5
- package/dist/cli/commands/index.js +1 -58
- package/dist/cli/commands/init-agent-guidance.js +1 -9
- package/dist/cli/commands/init.js +1 -9
- package/dist/cli/commands/learnings.js +1 -5
- package/dist/cli/commands/lifecycle-transitions.js +1 -5
- package/dist/cli/commands/list.js +1 -9
- package/dist/cli/commands/merge.js +1 -11
- package/dist/cli/commands/next.js +1 -9
- package/dist/cli/commands/notes.js +1 -5
- package/dist/cli/commands/plan.js +1 -9
- package/dist/cli/commands/profile.js +1 -9
- package/dist/cli/commands/restore.js +1 -9
- package/dist/cli/commands/scheduling-shortcuts.js +1 -9
- package/dist/cli/commands/schema.js +1 -10
- package/dist/cli/commands/search.js +1 -9
- package/dist/cli/commands/stats.js +1 -9
- package/dist/cli/commands/telemetry.js +1 -9
- package/dist/cli/commands/test-all.js +1 -9
- package/dist/cli/commands/test-runs.js +1 -9
- package/dist/cli/commands/test.js +1 -9
- package/dist/cli/commands/update-many.js +1 -5
- package/dist/cli/commands/update.js +1 -9
- package/dist/cli/commands/upgrade.js +1 -5
- package/dist/cli/commands/validate.js +1 -15
- package/dist/cli/context-intent-invocation.js +1 -20
- package/dist/cli/description-stdin.js +1 -17
- package/dist/cli/error-guidance.js +1 -1353
- package/dist/cli/extension-command-help.js +5 -636
- package/dist/cli/extension-command-options.js +1 -427
- package/dist/cli/extension-recovery.js +1 -126
- package/dist/cli/help-content.js +2 -1001
- package/dist/cli/help-json-payload.js +4 -570
- package/dist/cli/main.d.ts +4 -0
- package/dist/cli/main.js +5 -2573
- package/dist/cli/migration-gates.js +1 -289
- package/dist/cli/public.js +1 -20
- package/dist/cli/register-annotations.js +1 -270
- package/dist/cli/register-assurance.js +1 -62
- package/dist/cli/register-files-lookup.js +1 -56
- package/dist/cli/register-history-activity.d.ts +8 -0
- package/dist/cli/register-history-activity.js +2 -0
- package/dist/cli/register-history-author.js +1 -38
- package/dist/cli/register-history-maintenance.d.ts +9 -0
- package/dist/cli/register-history-maintenance.js +2 -0
- package/dist/cli/register-list-query.js +10 -943
- package/dist/cli/register-mutation-options.js +1 -9
- package/dist/cli/register-mutation.js +19 -1893
- package/dist/cli/register-operations.js +1 -920
- package/dist/cli/register-setup.js +1 -716
- package/dist/cli/register-structured-mutation.js +1 -196
- package/dist/cli/registration-helpers.js +1 -5
- package/dist/cli/runtime-compatibility-boundary.js +4 -42
- package/dist/cli/schema-registration-helpers.js +1 -73
- package/dist/cli/search-refresh.js +1 -13
- package/dist/cli/stats-analytics-json.js +1 -68
- package/dist/cli/telemetry-flush.js +1 -10
- package/dist/cli-bundle/bundle-manifest.json +164 -156
- package/dist/cli-bundle/chunks/chunk-3BZZA6A3.js +5 -0
- package/dist/cli-bundle/chunks/chunk-AMRDVX36.js +235 -0
- package/dist/cli-bundle/chunks/chunk-DAM4CBBR.js +2202 -0
- package/dist/cli-bundle/chunks/{chunk-WYRZZ5ZE.js → chunk-DEZPZOQ7.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-FLDWYEND.js +77 -0
- package/dist/cli-bundle/chunks/{chunk-NPN5I67J.js → chunk-G5ADGQ2D.js} +3 -3
- package/dist/cli-bundle/chunks/chunk-JAAEYHUA.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-JX4DH4WC.js → chunk-KR3RP4FH.js} +3 -3
- package/dist/cli-bundle/chunks/chunk-LEZOUXG6.js +2 -0
- package/dist/cli-bundle/chunks/chunk-NSAPNEYH.js +2 -0
- package/dist/cli-bundle/chunks/chunk-QOEKOECV.js +29 -0
- package/dist/cli-bundle/chunks/chunk-RHSFOMHU.js +2 -0
- package/dist/cli-bundle/chunks/chunk-XOD2PCB6.js +20 -0
- package/dist/cli-bundle/chunks/{chunk-JT6XF6GE.js → chunk-YVEQ2AMO.js} +4 -4
- package/dist/cli-bundle/chunks/register-list-query-KSK3R63M.js +11 -0
- package/dist/cli-bundle/chunks/register-mutation-IQ5C7U6O.js +20 -0
- package/dist/cli-bundle/chunks/{register-operations-I5W3KMGB.js → register-operations-DWVHR2NC.js} +2 -2
- package/dist/cli-bundle/chunks/register-setup-BQ5SVD4B.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-3WRPWLA7.js +3 -0
- package/dist/cli-bundle/focused-chunks/chunk-7MBUII7U.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-COPBO5HW.js +8 -0
- package/dist/cli-bundle/focused-chunks/chunk-DUN4IXYN.js +20 -0
- package/dist/cli-bundle/focused-chunks/{chunk-LIJIA4TY.js → chunk-EE5QSM4Z.js} +3 -3
- package/dist/cli-bundle/focused-chunks/chunk-HJVARYM3.js +6 -0
- package/dist/cli-bundle/focused-chunks/chunk-IAUOUGVR.js +177 -0
- package/dist/cli-bundle/focused-chunks/chunk-KOOMJ54F.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-MZDXX7JY.js +56 -0
- package/dist/cli-bundle/focused-chunks/{chunk-M6PBRFSH.js → chunk-OPFHFGDD.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-QHNETP77.js +9 -0
- package/dist/cli-bundle/focused-chunks/{chunk-3BZEOXLT.js → chunk-RMWES4M6.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-RXT4P5QH.js +10 -0
- package/dist/cli-bundle/focused-chunks/chunk-SDOL6FM2.js +12 -0
- package/dist/cli-bundle/focused-chunks/chunk-SQV4AAUC.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-PEFABF7E.js → chunk-WE3IUNIW.js} +3 -3
- package/dist/cli-bundle/focused-chunks/chunk-YALOUBWJ.js +2 -0
- package/dist/cli-bundle/main.js +20 -20
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +2 -2
- package/dist/cli-bundle/sdk-core.js +29 -29
- package/dist/cli-bundle/sdk-governance.js +1 -1
- package/dist/cli-bundle/sdk-graph.js +1 -1
- package/dist/cli-bundle/sdk-merge.js +42 -42
- package/dist/cli-bundle/sdk-query.js +1 -1
- package/dist/cli-bundle/sdk-runtime.js +1 -1
- package/dist/cli-bundle/sdk-testing.js +1 -1
- package/dist/cli-bundle/sdk.js +11 -11
- package/dist/cli.js +1 -104
- package/dist/core/checkpoint/checkpoint-gc.js +1 -169
- package/dist/core/checkpoint/mutation-checkpoint.js +2 -133
- package/dist/core/config/nested-settings.js +1 -534
- package/dist/core/config/positional-value.js +1 -109
- package/dist/core/diagnostics/remediation.js +1 -506
- package/dist/core/extensions/activation-summary-markdown.js +2 -145
- package/dist/core/extensions/activation-summary.js +1 -92
- package/dist/core/extensions/activation-transaction.js +1 -46
- package/dist/core/extensions/capability-usage.js +1 -173
- package/dist/core/extensions/command-hook-context.js +1 -13
- package/dist/core/extensions/command-metadata-contract.js +1 -22
- package/dist/core/extensions/command-visibility-tier.js +1 -29
- package/dist/core/extensions/contribution-inventory.js +1 -173
- package/dist/core/extensions/exporter-output-contract.js +1 -66
- package/dist/core/extensions/extension-candidate.js +1 -18
- package/dist/core/extensions/extension-capability-aliases.js +1 -158
- package/dist/core/extensions/extension-hook-runtime.js +1 -699
- package/dist/core/extensions/extension-policy.js +1 -599
- package/dist/core/extensions/extension-registries.js +1 -62
- package/dist/core/extensions/extension-runtime-helpers.js +1 -33
- package/dist/core/extensions/extension-types.js +1 -102
- package/dist/core/extensions/flag-definition-validation.js +1 -52
- package/dist/core/extensions/flag-value-types.js +1 -64
- package/dist/core/extensions/index.js +1 -526
- package/dist/core/extensions/item-field-types.js +1 -39
- package/dist/core/extensions/item-fields.js +1 -261
- package/dist/core/extensions/loader.js +1 -2223
- package/dist/core/extensions/manifest-schema.js +1 -69
- package/dist/core/extensions/module-graph-snapshot.js +1 -33
- package/dist/core/extensions/preflight-ownership.js +1 -41
- package/dist/core/extensions/registration-validation.js +1 -82
- package/dist/core/extensions/registration-values.js +1 -209
- package/dist/core/extensions/reserved-host-flags.js +1 -36
- package/dist/core/extensions/runtime-registrations.js +1 -67
- package/dist/core/extensions/service-ownership.js +1 -19
- package/dist/core/extensions/version-compat.js +1 -216
- package/dist/core/fs/fs-utils.js +2 -158
- package/dist/core/fs/host-environment-errors.js +1 -141
- package/dist/core/fs/index.js +1 -9
- package/dist/core/fs/path-utils.js +1 -17
- package/dist/core/governance/content-fields.js +1 -160
- package/dist/core/governance/issue-codes.js +1 -151
- package/dist/core/governance/metadata-coverage.js +1 -358
- package/dist/core/history/drift-cache.js +3 -72
- package/dist/core/history/drift-scan.js +1 -342
- package/dist/core/history/event-classification.js +1 -109
- package/dist/core/history/event-index.js +8 -784
- package/dist/core/history/history-compact-bulk.js +1 -104
- package/dist/core/history/history-diff.js +1 -158
- package/dist/core/history/history-rewrite.d.ts +6 -1
- package/dist/core/history/history-rewrite.js +1 -107
- package/dist/core/history/history-storage-stats.js +1 -102
- package/dist/core/history/history-stream-policy.js +1 -62
- package/dist/core/history/history.js +2 -617
- package/dist/core/history/identity.js +1 -30
- package/dist/core/history/index.js +1 -9
- package/dist/core/history/projection.js +1 -196
- package/dist/core/history/read.d.ts +9 -0
- package/dist/core/history/read.js +1 -57
- package/dist/core/history/replay.js +2 -439
- package/dist/core/history/version-address.js +1 -32
- package/dist/core/history/workspace-history.js +2 -433
- package/dist/core/io/body-file.js +1 -62
- package/dist/core/io/bulk-ids-input.js +1 -112
- package/dist/core/item/actionability.js +1 -327
- package/dist/core/item/dependency-reference.js +1 -20
- package/dist/core/item/id.js +1 -112
- package/dist/core/item/index.js +1 -12
- package/dist/core/item/item-format-version.js +1 -78
- package/dist/core/item/item-format.js +5 -1473
- package/dist/core/item/item-record.js +1 -23
- package/dist/core/item/item-type-definition.js +1 -133
- package/dist/core/item/parent-reference-policy.js +1 -57
- package/dist/core/item/parse.js +2 -603
- package/dist/core/item/plan-lifecycle.js +1 -19
- package/dist/core/item/priority.js +1 -61
- package/dist/core/item/sprint-release-format.js +1 -38
- package/dist/core/item/status-filter.js +1 -115
- package/dist/core/item/status.js +1 -43
- package/dist/core/item/toon-decode.js +1 -29
- package/dist/core/item/type-registry.js +1 -715
- package/dist/core/item/type-synonyms.js +1 -38
- package/dist/core/lock/index.js +1 -9
- package/dist/core/lock/lock-gc.js +1 -240
- package/dist/core/lock/lock.js +3 -590
- package/dist/core/output/mutation-projection.js +1 -217
- package/dist/core/output/output-control.js +1 -25
- package/dist/core/output/output.js +11 -494
- package/dist/core/output/query-summary.js +1 -58
- package/dist/core/output/tabular.js +1 -77
- package/dist/core/packages/manifest.js +1 -244
- package/dist/core/packages/root.js +1 -84
- package/dist/core/profile/profile-describe.js +1 -83
- package/dist/core/profile/profile-lint.js +1 -415
- package/dist/core/profile/profile-plan.js +0 -0
- package/dist/core/profile/profile-presets.js +1 -370
- package/dist/core/reproducibility/context.js +1 -82
- package/dist/core/schema/fields-file.js +2 -288
- package/dist/core/schema/item-types-file.js +2 -296
- package/dist/core/schema/runtime-field-filters.js +1 -49
- package/dist/core/schema/runtime-field-values.js +1 -313
- package/dist/core/schema/runtime-schema.js +2 -826
- package/dist/core/schema/status-defs-file.js +2 -227
- package/dist/core/schema/status-token.js +1 -31
- package/dist/core/schema/type-inference.js +1 -95
- package/dist/core/schema/type-presets.js +1 -87
- package/dist/core/schema/type-workflows.js +1 -104
- package/dist/core/search/background-refresh.js +2 -286
- package/dist/core/search/bm25.js +1 -146
- package/dist/core/search/cache.js +2 -534
- package/dist/core/search/corpus.js +1 -311
- package/dist/core/search/embedding-batches.js +1 -163
- package/dist/core/search/eval.js +1 -225
- package/dist/core/search/http-client.js +1 -75
- package/dist/core/search/providers.js +1 -242
- package/dist/core/search/relevance.js +1 -244
- package/dist/core/search/semantic-defaults.js +1 -199
- package/dist/core/search/staleness.js +1 -30
- package/dist/core/search/vector-stores.js +2 -664
- package/dist/core/search/vectorization-metadata.js +1 -81
- package/dist/core/sentry/helpers.js +1 -272
- package/dist/core/sentry/instrument.js +1 -387
- package/dist/core/session/session-state.js +1 -260
- package/dist/core/shared/agent-session-context.js +1 -133
- package/dist/core/shared/author.js +1 -1172
- package/dist/core/shared/command-types.js +1 -4
- package/dist/core/shared/conflict-markers.js +1 -31
- package/dist/core/shared/constants.js +1 -405
- package/dist/core/shared/errors.js +1 -20
- package/dist/core/shared/html-entity-decode.js +1 -131
- package/dist/core/shared/index.js +1 -12
- package/dist/core/shared/item-metadata-contract.js +1 -89
- package/dist/core/shared/lazy-module.js +1 -16
- package/dist/core/shared/levenshtein.js +1 -61
- package/dist/core/shared/memo.js +1 -19
- package/dist/core/shared/numeric-parsers.js +1 -20
- package/dist/core/shared/option-alias-visibility.js +1 -67
- package/dist/core/shared/primitives.js +1 -127
- package/dist/core/shared/serial-queue.js +1 -79
- package/dist/core/shared/serialization.js +1 -210
- package/dist/core/shared/split-comma-list.js +1 -30
- package/dist/core/shared/text-normalization.js +1 -38
- package/dist/core/shared/time.js +1 -306
- package/dist/core/store/index.js +1 -12
- package/dist/core/store/item-format-migration.js +1 -125
- package/dist/core/store/item-metadata-cache.js +1 -1116
- package/dist/core/store/item-metadata-query-index.js +9 -394
- package/dist/core/store/item-metadata-read-work.js +1 -43
- package/dist/core/store/item-store.js +1 -693
- package/dist/core/store/paths.d.ts +1 -1
- package/dist/core/store/paths.js +1 -214
- package/dist/core/store/settings-read-cache.js +1 -85
- package/dist/core/store/settings-validator.js +1 -421
- package/dist/core/store/settings.js +3 -1309
- package/dist/core/store/tracker-preflight.js +1 -141
- package/dist/core/telemetry/consent.js +5 -108
- package/dist/core/telemetry/observability.js +1 -246
- package/dist/core/telemetry/runtime.js +4 -1988
- package/dist/core/test/background-runs.js +4 -945
- package/dist/core/test/item-test-run-tracking.js +1 -63
- package/dist/core/test/run-selectors.js +1 -120
- package/dist/core/validate/estimate-defaults.js +1 -89
- package/dist/core/validate/fix-planning.js +1 -189
- package/dist/core/validate/linked-artifact-reference.js +1 -36
- package/dist/core/validate/missing-by-type.js +1 -34
- package/dist/core/validate/missing-link-owners.js +1 -95
- package/dist/core/validate/stale-file-classification.js +1 -82
- package/dist/mcp/http-server.js +5 -448
- package/dist/mcp/legacy-adapter.js +1 -77
- package/dist/mcp/runtime-capabilities.js +1 -200
- package/dist/mcp/server.js +4 -1233
- package/dist/mcp/tool-definitions.js +1 -804
- package/dist/sdk/actionability.js +1 -13
- package/dist/sdk/agent/closed-domain-contracts.js +1 -161
- package/dist/sdk/agent/command-recovery.js +1 -59
- package/dist/sdk/agent/command-suggestions.js +1 -66
- package/dist/sdk/agent/create-option-policy.js +1 -31
- package/dist/sdk/agent/identity-config.js +1 -106
- package/dist/sdk/agent/item-addressing.js +1 -207
- package/dist/sdk/agent/refusal-closure-census.js +1 -151
- package/dist/sdk/agent/refusal-closure.js +1 -133
- package/dist/sdk/agent/refusal-corpus-contracts.js +1 -193
- package/dist/sdk/agent/refusal-reachability.js +1 -593
- package/dist/sdk/agent/subcommand-recovery.js +1 -83
- package/dist/sdk/agent/task-transcript-contracts.js +1 -197
- package/dist/sdk/agent/tracker-preflight-contracts.js +1 -126
- package/dist/sdk/agent-capability-contracts.js +1 -428
- package/dist/sdk/agent-session-context.js +1 -9
- package/dist/sdk/annotations.js +1 -448
- package/dist/sdk/author-attribution.js +1 -468
- package/dist/sdk/authoring.js +1 -20
- package/dist/sdk/cli-bootstrap.js +1 -838
- package/dist/sdk/cli-contracts/agent-output-contracts.d.ts +1 -1
- package/dist/sdk/cli-contracts/agent-output-contracts.js +4 -476
- package/dist/sdk/cli-contracts/bootstrap-command-scanner.js +1 -79
- package/dist/sdk/cli-contracts/command-aliases.d.ts +4 -0
- package/dist/sdk/cli-contracts/command-aliases.js +1 -107
- package/dist/sdk/cli-contracts/command-exit-contracts.js +1 -151
- package/dist/sdk/cli-contracts/commander-mutation-options.js +1 -1081
- package/dist/sdk/cli-contracts/commander-types.js +1 -159
- package/dist/sdk/cli-contracts/completeness.js +1 -393
- package/dist/sdk/cli-contracts/enum-contracts.js +1 -222
- package/dist/sdk/cli-contracts/flag-contracts.js +1 -1947
- package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +1 -347
- package/dist/sdk/cli-contracts/grammar-contracts.js +1 -986
- package/dist/sdk/cli-contracts/registration-helpers.js +7 -990
- package/dist/sdk/cli-contracts/runtime-contracts.d.ts +5 -0
- package/dist/sdk/cli-contracts/runtime-contracts.js +1 -2090
- package/dist/sdk/cli-contracts/schemas/assurance-definition.js +1 -324
- package/dist/sdk/cli-contracts/string-lists.js +1 -16
- package/dist/sdk/cli-contracts/tool-option-contracts.js +1 -461
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +1 -2167
- package/dist/sdk/cli-contracts/tool-schema.d.ts +3 -1
- package/dist/sdk/cli-contracts/tool-schema.js +1 -1664
- package/dist/sdk/cli-contracts/typed-action-inputs.js +1 -4
- package/dist/sdk/cli-contracts.d.ts +1 -1
- package/dist/sdk/cli-contracts.js +1 -17
- package/dist/sdk/cli-program.js +1 -49
- package/dist/sdk/command-line.d.ts +2 -5
- package/dist/sdk/command-line.js +1 -78
- package/dist/sdk/comments.js +1 -133
- package/dist/sdk/compile-cache.js +1 -73
- package/dist/sdk/completion.js +157 -837
- package/dist/sdk/compose.js +1 -1090
- package/dist/sdk/config.js +1 -1204
- package/dist/sdk/context/recency.js +1 -33
- package/dist/sdk/context/semantic-session-attribution.js +1 -82
- package/dist/sdk/context/usage-egress.js +1 -29
- package/dist/sdk/context/usage-ledger.js +3 -185
- package/dist/sdk/context-intent-contracts.js +1 -709
- package/dist/sdk/context-intent-runtime.js +1 -115
- package/dist/sdk/context-packing.js +1 -218
- package/dist/sdk/context-relevance.js +1 -503
- package/dist/sdk/context-signal-store.js +2 -426
- package/dist/sdk/context-usage.js +1 -367
- package/dist/sdk/contracts.js +1 -23
- package/dist/sdk/core-governance.js +1 -14
- package/dist/sdk/core.js +1 -14
- package/dist/sdk/corpus-shape.js +1 -401
- package/dist/sdk/define.js +1 -220
- package/dist/sdk/dependencies.js +1 -718
- package/dist/sdk/dependency-flag-validation.js +1 -156
- package/dist/sdk/dependency-provenance.js +1 -135
- package/dist/sdk/docs.js +1 -14
- package/dist/sdk/duplicates.js +1 -40
- package/dist/sdk/environment/agent-environment.js +1 -466
- package/dist/sdk/environment/host-environment-errors.js +1 -8
- package/dist/sdk/environment/project-runtime-compatibility.js +1 -481
- package/dist/sdk/environment/source-context.js +1 -28
- package/dist/sdk/environment/tracker-preflight.js +1 -9
- package/dist/sdk/error-code-catalog.js +1 -153
- package/dist/sdk/error-runtime.js +1 -58
- package/dist/sdk/errors.js +1 -58
- package/dist/sdk/eval.js +1 -190
- package/dist/sdk/extension/author-manifest.js +1 -92
- package/dist/sdk/extension/bundled-catalog.js +1 -332
- package/dist/sdk/extension/concurrency.js +1 -25
- package/dist/sdk/extension/copy-scope.d.ts +2 -0
- package/dist/sdk/extension/copy-scope.js +2 -0
- package/dist/sdk/extension/custom-field-collisions.js +1 -30
- package/dist/sdk/extension/describe.js +3 -189
- package/dist/sdk/extension/doctor.js +1 -606
- package/dist/sdk/extension/install-plan.d.ts +69 -0
- package/dist/sdk/extension/install-plan.js +2 -0
- package/dist/sdk/extension/install-receipts.d.ts +7 -0
- package/dist/sdk/extension/install-receipts.js +2 -0
- package/dist/sdk/extension/install-runtime.js +3 -313
- package/dist/sdk/extension/install-snapshot.js +1 -66
- package/dist/sdk/extension/install-sources.js +5 -1057
- package/dist/sdk/extension/managed-state.js +2 -252
- package/dist/sdk/extension/migrations.js +2 -174
- package/dist/sdk/extension/output-ownership.js +1 -25
- package/dist/sdk/extension/runtime-summary.js +1 -18
- package/dist/sdk/extension/scaffold.js +4 -2308
- package/dist/sdk/extension/shared.js +1 -147
- package/dist/sdk/extension/source-resolution.js +1 -65
- package/dist/sdk/extension/update-check.js +1 -67
- package/dist/sdk/extension-command-context.js +1 -44
- package/dist/sdk/extension-contracts.js +1 -73
- package/dist/sdk/extension.d.ts +7 -2
- package/dist/sdk/extension.js +1 -2196
- package/dist/sdk/files.js +1 -535
- package/dist/sdk/flag-invocation-contracts.d.ts +0 -5
- package/dist/sdk/flag-invocation-contracts.js +1 -344
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -2224
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1 -2236
- package/dist/sdk/generated-error-code-catalog.js +1 -16
- package/dist/sdk/governance/assurance-action-contracts.js +1 -4
- package/dist/sdk/governance/assurance-action.js +1 -411
- package/dist/sdk/governance/assurance-limits.js +1 -10
- package/dist/sdk/governance/assurance-mutation-error.js +1 -81
- package/dist/sdk/governance/assurance-presets.js +1 -135
- package/dist/sdk/governance/assurance-runtime.js +1 -238
- package/dist/sdk/governance/assurance.js +4 -1182
- package/dist/sdk/governance/boundary-fixtures.js +1 -200
- package/dist/sdk/governance/coverage-assurance.js +1 -60
- package/dist/sdk/governance/defect-recurrence-coverage.js +1 -188
- package/dist/sdk/governance/defect-recurrence-graph.js +1 -120
- package/dist/sdk/governance/defect-recurrence-signals.js +1 -24
- package/dist/sdk/governance/defect-recurrence.js +1 -623
- package/dist/sdk/governance/extension-host-version.js +1 -115
- package/dist/sdk/governance/gc.js +1 -368
- package/dist/sdk/governance/health.js +1 -2367
- package/dist/sdk/governance/hierarchy-validation.js +1 -108
- package/dist/sdk/governance/linked-file-report.js +1 -71
- package/dist/sdk/governance/merge-receipt-history.js +1 -206
- package/dist/sdk/governance/provenance-health.js +1 -282
- package/dist/sdk/governance/reindex.js +4 -761
- package/dist/sdk/governance/stale-work.js +1 -82
- package/dist/sdk/governance/status-role-diagnostics.js +1 -35
- package/dist/sdk/governance/storage-integrity.js +1 -280
- package/dist/sdk/governance/tracked-runtime-cache.js +1 -106
- package/dist/sdk/governance/upgrade.js +2 -327
- package/dist/sdk/governance/validate-history-drift.js +1 -81
- package/dist/sdk/governance/validate-item-reader.js +1 -17
- package/dist/sdk/governance/validate-normalization.js +1 -36
- package/dist/sdk/governance/validate.js +1 -2261
- package/dist/sdk/governance/workspace-position.js +1 -163
- package/dist/sdk/governance.d.ts +1 -0
- package/dist/sdk/governance.js +1 -31
- package/dist/sdk/graph/adapter.js +1 -181
- package/dist/sdk/graph/analytics.js +1 -474
- package/dist/sdk/graph/assembly.js +1 -377
- package/dist/sdk/graph/cache.js +1 -160
- package/dist/sdk/graph/centrality.js +1 -258
- package/dist/sdk/graph/conformance.js +1 -130
- package/dist/sdk/graph/deadline-scheduling.d.ts +90 -0
- package/dist/sdk/graph/deadline-scheduling.js +2 -0
- package/dist/sdk/graph/durable-cache.d.ts +1 -1
- package/dist/sdk/graph/durable-cache.js +1 -361
- package/dist/sdk/graph/governance-contracts.js +1 -34
- package/dist/sdk/graph/governance.d.ts +13 -1
- package/dist/sdk/graph/governance.js +1 -735
- package/dist/sdk/graph/hierarchy-integrity.js +1 -310
- package/dist/sdk/graph/index.d.ts +3 -2
- package/dist/sdk/graph/index.js +1 -26
- package/dist/sdk/graph/lifecycle-coverage.d.ts +32 -0
- package/dist/sdk/graph/lifecycle-coverage.js +2 -0
- package/dist/sdk/graph/mutation-advisory.js +1 -176
- package/dist/sdk/graph/remediation.js +1 -197
- package/dist/sdk/graph/run.d.ts +15 -1
- package/dist/sdk/graph/run.js +1 -768
- package/dist/sdk/graph/scheduling.js +1 -124
- package/dist/sdk/graph/traversal.js +1 -284
- package/dist/sdk/graph/workspace-relationship-kind-registry.js +1 -27
- package/dist/sdk/graph.js +1 -15
- package/dist/sdk/guide-topics.js +1 -707
- package/dist/sdk/guide.js +1 -279
- package/dist/sdk/history/maintenance.d.ts +71 -0
- package/dist/sdk/history/maintenance.js +2 -0
- package/dist/sdk/history/salvage.js +2 -247
- package/dist/sdk/history/subject.d.ts +19 -0
- package/dist/sdk/history/subject.js +2 -0
- package/dist/sdk/history-analytics.js +1 -282
- package/dist/sdk/history-compact.js +1 -527
- package/dist/sdk/history-mcp.js +1 -68
- package/dist/sdk/history-provenance.js +1 -182
- package/dist/sdk/history-read.js +1 -96
- package/dist/sdk/history-redact.d.ts +1 -14
- package/dist/sdk/history-redact.js +1 -643
- package/dist/sdk/history-repair.d.ts +5 -0
- package/dist/sdk/history-repair.js +1 -657
- package/dist/sdk/improvement-ledger-validation.js +1 -62
- package/dist/sdk/improvement-ledger.js +2 -257
- package/dist/sdk/index.d.ts +4 -0
- package/dist/sdk/index.js +1 -183
- package/dist/sdk/init-agent-guidance.js +2 -496
- package/dist/sdk/init.js +2 -820
- package/dist/sdk/invocation-author.js +1 -39
- package/dist/sdk/item-children.js +1 -90
- package/dist/sdk/item-metadata-index.js +1 -15
- package/dist/sdk/item-schedule.js +1 -27
- package/dist/sdk/item-transaction.js +1 -396
- package/dist/sdk/learnings.js +1 -29
- package/dist/sdk/lifecycle/append.js +2 -53
- package/dist/sdk/lifecycle/claim.d.ts +2 -0
- package/dist/sdk/lifecycle/claim.js +1 -242
- package/dist/sdk/lifecycle/close-many.js +1 -438
- package/dist/sdk/lifecycle/close.js +1 -468
- package/dist/sdk/lifecycle/copy.js +1 -212
- package/dist/sdk/lifecycle/create.js +1 -1949
- package/dist/sdk/lifecycle/delete.js +1 -45
- package/dist/sdk/lifecycle/event-validation-messages.js +1 -91
- package/dist/sdk/lifecycle/focus.js +1 -91
- package/dist/sdk/lifecycle/hierarchy-mutation-lock.js +1 -24
- package/dist/sdk/lifecycle/legacy-none-tokens.js +1 -149
- package/dist/sdk/lifecycle/lifecycle-transitions.js +1 -40
- package/dist/sdk/lifecycle/mcp-actions.d.ts +2 -0
- package/dist/sdk/lifecycle/mcp-actions.js +1 -51
- package/dist/sdk/lifecycle/metadata-normalizers.js +1 -46
- package/dist/sdk/lifecycle/mutation-command-options.js +1 -9
- package/dist/sdk/lifecycle/plan.js +1 -1606
- package/dist/sdk/lifecycle/recurrence-parsers.js +1 -147
- package/dist/sdk/lifecycle/reopen.js +1 -68
- package/dist/sdk/lifecycle/repeatable-metadata-parsers.js +1 -143
- package/dist/sdk/lifecycle/restore.d.ts +1 -0
- package/dist/sdk/lifecycle/restore.js +1 -330
- package/dist/sdk/lifecycle/shared-unset-fields.js +1 -295
- package/dist/sdk/lifecycle/update-many.js +1 -861
- package/dist/sdk/lifecycle/update.js +1 -2136
- package/dist/sdk/lifecycle-completion.js +1 -92
- package/dist/sdk/lifecycle-policy.js +1 -120
- package/dist/sdk/linked-artifacts.js +1 -530
- package/dist/sdk/mcp/apps.js +4 -133
- package/dist/sdk/mcp/authorization.js +1 -404
- package/dist/sdk/mcp/discovery.js +1 -494
- package/dist/sdk/mcp/interactions.js +1 -336
- package/dist/sdk/mcp/protocol.d.ts +7 -0
- package/dist/sdk/mcp/protocol.js +1 -184
- package/dist/sdk/mcp/skills.js +1 -389
- package/dist/sdk/mcp/subscriptions.js +1 -211
- package/dist/sdk/mcp/tasks.js +2 -430
- package/dist/sdk/mcp/transport.js +1 -260
- package/dist/sdk/merge/abandoned-receipts.js +1 -46
- package/dist/sdk/merge/driver.js +1 -212
- package/dist/sdk/merge/index.js +1 -16
- package/dist/sdk/merge/install.js +3 -561
- package/dist/sdk/merge/receipt-file-boundary.js +1 -46
- package/dist/sdk/merge/receipt-operation.js +1 -96
- package/dist/sdk/merge/receipt-schema.js +1 -397
- package/dist/sdk/merge/receipts.js +4 -525
- package/dist/sdk/merge/reconcile.js +1 -352
- package/dist/sdk/merge/three-way.js +3 -775
- package/dist/sdk/merge.js +1 -10
- package/dist/sdk/mutation-events.js +1 -292
- package/dist/sdk/mutation-guard.js +1 -216
- package/dist/sdk/notes.js +1 -139
- package/dist/sdk/output-contracts.js +1 -172
- package/dist/sdk/output-projection.js +1 -430
- package/dist/sdk/output-token-accounting.js +1 -140
- package/dist/sdk/output.js +1 -64
- package/dist/sdk/ownership-source.js +1 -21
- package/dist/sdk/package-import-adapters.js +1 -442
- package/dist/sdk/package-migrations.js +1 -20
- package/dist/sdk/package-runtime-options.js +1 -80
- package/dist/sdk/pagination.js +1 -162
- package/dist/sdk/profile.js +1 -454
- package/dist/sdk/provenance.js +1 -258
- package/dist/sdk/public-surface.json +1 -1
- package/dist/sdk/query/activity.js +1 -401
- package/dist/sdk/query/aggregate.d.ts +16 -0
- package/dist/sdk/query/aggregate.js +1 -390
- package/dist/sdk/query/calendar.js +1 -964
- package/dist/sdk/query/complete-list.js +1 -215
- package/dist/sdk/query/context.js +1 -1702
- package/dist/sdk/query/duplicate-candidates.js +1 -70
- package/dist/sdk/query/get.js +1 -450
- package/dist/sdk/query/history.js +1 -186
- package/dist/sdk/query/item-filter-options.js +1 -9
- package/dist/sdk/query/light-metadata.js +1 -18
- package/dist/sdk/query/list-filter-shared.js +1 -81
- package/dist/sdk/query/list.js +1 -1304
- package/dist/sdk/query/multi-value-filters.js +1 -78
- package/dist/sdk/query/next.js +1 -513
- package/dist/sdk/query/parsers.js +1 -44
- package/dist/sdk/query/projection-contracts.js +1 -184
- package/dist/sdk/query/search-contracts.js +1 -230
- package/dist/sdk/query/search-pagination.js +1 -35
- package/dist/sdk/query/search-rendering.js +1 -105
- package/dist/sdk/query/search.js +2 -1987
- package/dist/sdk/query.js +1 -35
- package/dist/sdk/read-output/continuation.js +1 -194
- package/dist/sdk/read-output-budget.js +1 -135
- package/dist/sdk/read-output-contracts.js +1 -1225
- package/dist/sdk/read-output-rows.js +1 -186
- package/dist/sdk/read-output-session.js +1 -208
- package/dist/sdk/relationship-analytics.js +1 -410
- package/dist/sdk/relationship-context.js +1 -284
- package/dist/sdk/relationship-history.js +4 -519
- package/dist/sdk/relationship-kinds/contract.js +1 -22
- package/dist/sdk/relationship-migration.js +1 -77
- package/dist/sdk/relationships.js +1 -579
- package/dist/sdk/reproducibility/process.js +1 -87
- package/dist/sdk/runtime-action-aliases.js +1 -59
- package/dist/sdk/runtime-extended-actions.js +1 -177
- package/dist/sdk/runtime-input.js +1 -614
- package/dist/sdk/runtime-primitives.js +1 -84
- package/dist/sdk/runtime-public-contracts.js +1 -4
- package/dist/sdk/runtime-stats-options.js +1 -38
- package/dist/sdk/runtime.js +1 -1928
- package/dist/sdk/scheduling-shortcuts.js +1 -63
- package/dist/sdk/schema-migration.js +3 -856
- package/dist/sdk/schema.js +1 -1376
- package/dist/sdk/search-refresh-worker.js +1 -18
- package/dist/sdk/similarity-scoring.js +1 -53
- package/dist/sdk/similarity.js +1 -326
- package/dist/sdk/start-task-status.js +1 -14
- package/dist/sdk/stats.js +1 -270
- package/dist/sdk/structured-mutations.js +1 -580
- package/dist/sdk/telemetry-flush.js +1 -13
- package/dist/sdk/telemetry.js +1 -405
- package/dist/sdk/templates.js +2 -292
- package/dist/sdk/test/batch.js +2 -509
- package/dist/sdk/test/entry.js +1 -70
- package/dist/sdk/test/execution.js +6 -2211
- package/dist/sdk/test/linked-command-detection.js +1 -546
- package/dist/sdk/test/measurements.js +1 -91
- package/dist/sdk/test/parsers.js +1 -545
- package/dist/sdk/test/runs.js +1 -193
- package/dist/sdk/test/trust.js +2 -206
- package/dist/sdk/testing.js +4 -1391
- package/dist/sdk/traceability/runtime-files-lookup.js +1 -32
- package/dist/sdk/traceability/source-traceability.js +1 -292
- package/dist/sdk/tracker-root-discovery.js +1 -9
- package/dist/sdk/workspace-contracts-cache.js +1 -28
- package/dist/sdk/workspace-contracts.js +1 -33
- package/dist/sdk/workspace-memory.js +2 -318
- package/dist/sdk/workspace-recipe.js +1 -71
- package/dist/sdk/workspace-snapshot.js +4 -613
- package/dist/sdk/workspace-transaction-gc.js +1 -149
- package/dist/sdk/workspace-transaction.js +2 -363
- package/dist/sdk/workspace.js +3 -127
- package/dist/types/index.js +1 -9
- package/dist/types.js +1 -245
- package/docs/AGENT_GUIDE.md +1 -1
- package/docs/CONTEXT_ALGORITHM_PORTFOLIO.md +167 -0
- package/docs/DIAGNOSTIC_OUTPUT_CONTRACTS.md +9 -3
- package/docs/EXTENSIONS.md +1 -0
- package/docs/HISTORY_MAINTENANCE.md +125 -0
- package/docs/MCP_2026_07_28_CONFORMANCE.md +20 -10
- package/docs/PACKAGE_EVIDENCE.md +92 -0
- package/docs/PLANNING_MEASUREMENTS.md +183 -0
- package/docs/README.md +3 -0
- package/docs/RELEASING.md +1 -0
- package/docs/SCRIPTING.md +21 -0
- package/docs/TESTING.md +23 -0
- package/docs/generated/FLAG_LEXICON_BUDGETS.md +5 -5
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +2 -2
- package/marketplace.json +2 -2
- package/package.json +1 -1
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-digital-twin/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/packages/pm-vcs/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/scripts/finalize-build.mjs +45 -3
- package/dist/cli-bundle/chunks/chunk-AZDFJGH6.js +0 -9
- package/dist/cli-bundle/chunks/chunk-BAX2BYUW.js +0 -2111
- package/dist/cli-bundle/chunks/chunk-CKOL5U7J.js +0 -77
- package/dist/cli-bundle/chunks/chunk-OF76PSDQ.js +0 -5
- package/dist/cli-bundle/chunks/chunk-QUWFABDM.js +0 -232
- package/dist/cli-bundle/chunks/chunk-QWRRFYK3.js +0 -2
- package/dist/cli-bundle/chunks/chunk-RWWBOWJ5.js +0 -2
- package/dist/cli-bundle/chunks/chunk-WGAOYSYH.js +0 -40
- package/dist/cli-bundle/chunks/chunk-WI2AYPA7.js +0 -2
- package/dist/cli-bundle/chunks/register-list-query-5JL52D33.js +0 -11
- package/dist/cli-bundle/chunks/register-mutation-ZPG7KMVP.js +0 -20
- package/dist/cli-bundle/chunks/register-setup-H4SVAVX7.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-AL5ON6K6.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-CHC2IDXA.js +0 -6
- package/dist/cli-bundle/focused-chunks/chunk-CK6QFAPZ.js +0 -20
- package/dist/cli-bundle/focused-chunks/chunk-EZR3GHFE.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-H2WJWK7L.js +0 -56
- package/dist/cli-bundle/focused-chunks/chunk-NTPY5GSO.js +0 -3
- package/dist/cli-bundle/focused-chunks/chunk-P5O7MP5Y.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-PDMW2E36.js +0 -177
- package/dist/cli-bundle/focused-chunks/chunk-QTVCLMSZ.js +0 -6
- package/dist/cli-bundle/focused-chunks/chunk-QTZRBUYA.js +0 -8
- package/dist/cli-bundle/focused-chunks/chunk-SGQST3PQ.js +0 -12
- package/dist/cli-bundle/focused-chunks/chunk-UKHASMMP.js +0 -10
- package/dist/cli-bundle/focused-chunks/chunk-ZPEKQHOC.js +0 -2
|
@@ -1,1173 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module core/shared/author
|
|
3
|
-
*
|
|
4
|
-
* Provides shared primitives and utilities for Author.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="dfbf4eb8-1f02-5880-a70a-0e7ed9b9784a")}catch(e){}}();
|
|
8
|
-
import { AsyncLocalStorage } from "node:async_hooks";
|
|
9
|
-
import { createHash } from "node:crypto";
|
|
10
|
-
import fs from "node:fs";
|
|
11
|
-
import os from "node:os";
|
|
12
|
-
import path from "node:path";
|
|
13
|
-
import { resolveAgentSessionContextFromSignals, } from "./agent-session-context.js";
|
|
14
|
-
import { readAgentSemanticAttributionSync, } from "../session/session-state.js";
|
|
15
|
-
import { isFileAbsentError } from "../fs/fs-utils.js";
|
|
16
|
-
/** Stable built-in provenance dimensions understood by the default runtime. */
|
|
17
|
-
export const AGENT_PROVENANCE_DIMENSIONS = [
|
|
18
|
-
"model",
|
|
19
|
-
"effort",
|
|
20
|
-
"role",
|
|
21
|
-
"topic",
|
|
22
|
-
"version",
|
|
23
|
-
];
|
|
24
|
-
const authorIdentityStorage = new AsyncLocalStorage();
|
|
25
|
-
const harnessDetectionStorage = new AsyncLocalStorage();
|
|
26
|
-
const workspaceHarnessSignalsStorage = new AsyncLocalStorage();
|
|
27
|
-
/** Built-in agent descriptors evaluated before package and workspace additions. */
|
|
28
|
-
export const BUILTIN_HARNESS_SIGNAL_DESCRIPTORS = [
|
|
29
|
-
{
|
|
30
|
-
harness: "claude-code",
|
|
31
|
-
environment_keys: ["CLAUDE_CODE", "CLAUDECODE"],
|
|
32
|
-
model_environment_keys: ["ANTHROPIC_MODEL", "CLAUDE_MODEL"],
|
|
33
|
-
session_environment_keys: ["CLAUDE_CODE_SESSION_ID"],
|
|
34
|
-
provenance_environment_keys: {
|
|
35
|
-
effort: ["CLAUDE_EFFORT"],
|
|
36
|
-
},
|
|
37
|
-
provenance_resolvers: {
|
|
38
|
-
model: "claude_session_file",
|
|
39
|
-
version: "claude_session_file",
|
|
40
|
-
},
|
|
41
|
-
provenance_unavailable_dimensions: ["role", "topic"],
|
|
42
|
-
argv_markers: ["claude", "claude-code"],
|
|
43
|
-
client_names: ["claude", "claude-code", "claude code"],
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
harness: "codex",
|
|
47
|
-
environment_keys: ["CODEX_HOME", "CODEX_CI", "CODEX_THREAD_ID"],
|
|
48
|
-
model_environment_keys: ["CODEX_MODEL"],
|
|
49
|
-
session_environment_keys: ["CODEX_THREAD_ID"],
|
|
50
|
-
provenance_environment_keys: {
|
|
51
|
-
effort: ["CODEX_REASONING_EFFORT", "CODEX_EFFORT"],
|
|
52
|
-
role: ["CODEX_SESSION_ROLE"],
|
|
53
|
-
},
|
|
54
|
-
provenance_resolvers: {
|
|
55
|
-
model: "codex_session_file",
|
|
56
|
-
effort: "codex_session_file",
|
|
57
|
-
version: "ai_agent_version",
|
|
58
|
-
},
|
|
59
|
-
provenance_unavailable_dimensions: ["topic"],
|
|
60
|
-
argv_markers: ["codex"],
|
|
61
|
-
client_names: ["codex"],
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
harness: "pi",
|
|
65
|
-
environment_keys: ["PI_AGENT", "PI_CODING_AGENT"],
|
|
66
|
-
model_environment_keys: ["PI_MODEL"],
|
|
67
|
-
session_environment_keys: ["PI_SESSION_ID"],
|
|
68
|
-
provenance_unavailable_dimensions: ["effort", "role", "topic"],
|
|
69
|
-
argv_markers: ["pi"],
|
|
70
|
-
client_names: ["pi"],
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
harness: "opencode",
|
|
74
|
-
environment_keys: ["OPENCODE", "OPENCODE_SESSION_ID"],
|
|
75
|
-
model_environment_keys: ["OPENCODE_MODEL"],
|
|
76
|
-
session_environment_keys: ["OPENCODE_SESSION_ID"],
|
|
77
|
-
provenance_unavailable_dimensions: ["effort", "role", "topic"],
|
|
78
|
-
argv_markers: ["opencode"],
|
|
79
|
-
client_names: ["opencode"],
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
harness: "cursor",
|
|
83
|
-
environment_keys: ["CURSOR_AGENT", "CURSOR_TRACE_ID"],
|
|
84
|
-
model_environment_keys: ["CURSOR_MODEL"],
|
|
85
|
-
session_environment_keys: ["CURSOR_TRACE_ID"],
|
|
86
|
-
provenance_unavailable_dimensions: ["effort", "role", "topic"],
|
|
87
|
-
argv_markers: ["cursor"],
|
|
88
|
-
client_names: ["cursor"],
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
harness: "aider",
|
|
92
|
-
environment_keys: ["AIDER", "AIDER_MODEL"],
|
|
93
|
-
model_environment_keys: ["AIDER_MODEL"],
|
|
94
|
-
session_environment_keys: ["AIDER_SESSION_ID"],
|
|
95
|
-
provenance_unavailable_dimensions: ["effort", "role", "topic"],
|
|
96
|
-
argv_markers: ["aider"],
|
|
97
|
-
client_names: ["aider"],
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
harness: "gemini-cli",
|
|
101
|
-
environment_keys: ["GEMINI_CLI", "GEMINI_CLI_HOME"],
|
|
102
|
-
model_environment_keys: ["GEMINI_MODEL"],
|
|
103
|
-
session_environment_keys: ["GEMINI_CLI_SESSION_ID"],
|
|
104
|
-
provenance_unavailable_dimensions: ["effort", "role", "topic"],
|
|
105
|
-
argv_markers: ["gemini", "gemini-cli"],
|
|
106
|
-
client_names: ["gemini", "gemini-cli", "gemini cli"],
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
harness: "ci",
|
|
110
|
-
environment_keys: ["CI", "GITHUB_ACTIONS", "BUILDKITE", "GITLAB_CI"],
|
|
111
|
-
provenance_unavailable_dimensions: ["model", "effort", "role", "topic"],
|
|
112
|
-
argv_markers: [],
|
|
113
|
-
client_names: [],
|
|
114
|
-
},
|
|
115
|
-
];
|
|
116
|
-
const PROVENANCE_PROBE_POLICY = Object.freeze({
|
|
117
|
-
max_bytes: 1_048_576,
|
|
118
|
-
max_lines: 4_096,
|
|
119
|
-
network_access: false,
|
|
120
|
-
subprocess_access: false,
|
|
121
|
-
});
|
|
122
|
-
const CODEX_PROVENANCE_PROBE_POLICY = Object.freeze({
|
|
123
|
-
...PROVENANCE_PROBE_POLICY,
|
|
124
|
-
max_bytes: 4_194_304,
|
|
125
|
-
});
|
|
126
|
-
const HARNESS_NAMESPACE_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/u;
|
|
127
|
-
function buildBuiltinProvenanceAdapter(descriptor) {
|
|
128
|
-
const unavailableDimensions = normalizeHarnessSignalDescriptor(descriptor).provenance_unavailable_dimensions;
|
|
129
|
-
const dimensions = new Set([
|
|
130
|
-
"model",
|
|
131
|
-
"version",
|
|
132
|
-
...Object.keys(descriptor.provenance_environment_keys ?? {}),
|
|
133
|
-
...Object.keys(descriptor.provenance_resolvers ?? {}),
|
|
134
|
-
]);
|
|
135
|
-
return Object.freeze({
|
|
136
|
-
contract_version: 1,
|
|
137
|
-
adapter_version: "v1",
|
|
138
|
-
priority: 0,
|
|
139
|
-
harness: descriptor.harness,
|
|
140
|
-
descriptor,
|
|
141
|
-
supported_dimensions: Object.freeze([...dimensions].sort()),
|
|
142
|
-
native_sources: Object.freeze([
|
|
143
|
-
"environment",
|
|
144
|
-
"argv",
|
|
145
|
-
"mcp_client",
|
|
146
|
-
...(Object.values(descriptor.provenance_resolvers ?? {}).some((resolver) => resolver?.endsWith("session_file"))
|
|
147
|
-
? ["session_file"]
|
|
148
|
-
: []),
|
|
149
|
-
]),
|
|
150
|
-
probe_policy: descriptor.harness === "codex"
|
|
151
|
-
? CODEX_PROVENANCE_PROBE_POLICY
|
|
152
|
-
: PROVENANCE_PROBE_POLICY,
|
|
153
|
-
normalization: Object.freeze({
|
|
154
|
-
model_family: "v1",
|
|
155
|
-
effort: "v1",
|
|
156
|
-
preserve_raw: true,
|
|
157
|
-
}),
|
|
158
|
-
confidence: "high",
|
|
159
|
-
waivers: Object.freeze(Object.fromEntries(unavailableDimensions.map((dimension) => [
|
|
160
|
-
dimension,
|
|
161
|
-
"Harness does not expose this dimension.",
|
|
162
|
-
]))),
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
/** Built-in versioned adapters for supported interactive agent harnesses. */
|
|
166
|
-
export const BUILTIN_AGENT_PROVENANCE_ADAPTERS = Object.freeze(BUILTIN_HARNESS_SIGNAL_DESCRIPTORS.filter((descriptor) => descriptor.harness !== "ci")
|
|
167
|
-
.map(buildBuiltinProvenanceAdapter)
|
|
168
|
-
.sort((left, right) => left.harness.localeCompare(right.harness)));
|
|
169
|
-
const registeredAgentProvenanceAdapters = new Map();
|
|
170
|
-
const registeredHarnessSignalDescriptors = new Map();
|
|
171
|
-
function nonBlank(value) {
|
|
172
|
-
const trimmed = typeof value === "string" ? value.trim() : undefined;
|
|
173
|
-
return trimmed && trimmed.length > 0 ? trimmed : undefined;
|
|
174
|
-
}
|
|
175
|
-
function boundedUniqueStrings(values) {
|
|
176
|
-
return [
|
|
177
|
-
...new Set((values ?? [])
|
|
178
|
-
.slice(0, 64)
|
|
179
|
-
.map((value) => value.trim())
|
|
180
|
-
.filter((value) => value.length > 0)
|
|
181
|
-
.map((value) => value.slice(0, 128))),
|
|
182
|
-
];
|
|
183
|
-
}
|
|
184
|
-
function normalizeHarnessSignalDescriptor(descriptor) {
|
|
185
|
-
const harness = descriptor.harness.trim().toLowerCase();
|
|
186
|
-
if (!HARNESS_NAMESPACE_PATTERN.test(harness)) {
|
|
187
|
-
throw new Error(`Invalid harness signal descriptor namespace: ${descriptor.harness}`);
|
|
188
|
-
}
|
|
189
|
-
return {
|
|
190
|
-
harness,
|
|
191
|
-
environment_keys: boundedUniqueStrings(descriptor.environment_keys),
|
|
192
|
-
model_environment_keys: boundedUniqueStrings(descriptor.model_environment_keys),
|
|
193
|
-
session_environment_keys: boundedUniqueStrings(descriptor.session_environment_keys),
|
|
194
|
-
provenance_environment_keys: Object.fromEntries(Object.entries(descriptor.provenance_environment_keys ?? {})
|
|
195
|
-
.slice(0, 32)
|
|
196
|
-
.map(([dimension, keys]) => [
|
|
197
|
-
dimension.trim().toLowerCase().slice(0, 64),
|
|
198
|
-
boundedUniqueStrings(keys),
|
|
199
|
-
])
|
|
200
|
-
.filter(([dimension]) => HARNESS_NAMESPACE_PATTERN.test(dimension))),
|
|
201
|
-
provenance_resolvers: Object.fromEntries(Object.entries(descriptor.provenance_resolvers ?? {})
|
|
202
|
-
.slice(0, 32)
|
|
203
|
-
.map(([dimension, resolver]) => [
|
|
204
|
-
dimension.trim().toLowerCase().slice(0, 64),
|
|
205
|
-
resolver,
|
|
206
|
-
])
|
|
207
|
-
.filter((entry) => typeof entry[0] === "string" &&
|
|
208
|
-
HARNESS_NAMESPACE_PATTERN.test(entry[0]) &&
|
|
209
|
-
(entry[1] === "ai_agent_version" ||
|
|
210
|
-
entry[1] === "claude_session_file" ||
|
|
211
|
-
entry[1] === "codex_session_file"))),
|
|
212
|
-
provenance_unavailable_dimensions: boundedUniqueStrings(descriptor.provenance_unavailable_dimensions).map((value) => value.toLowerCase()),
|
|
213
|
-
argv_markers: boundedUniqueStrings(descriptor.argv_markers).map((value) => value.toLowerCase()),
|
|
214
|
-
client_names: boundedUniqueStrings(descriptor.client_names).map((value) => value.toLowerCase()),
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
const NORMALIZED_BUILTIN_HARNESS_SIGNAL_DESCRIPTORS = BUILTIN_HARNESS_SIGNAL_DESCRIPTORS.map(normalizeHarnessSignalDescriptor);
|
|
218
|
-
function descriptorEquals(left, right) {
|
|
219
|
-
return JSON.stringify(left) === JSON.stringify(right);
|
|
220
|
-
}
|
|
221
|
-
function literalSignalMatches(value, marker) {
|
|
222
|
-
const segments = value
|
|
223
|
-
.toLowerCase()
|
|
224
|
-
.slice(0, 512)
|
|
225
|
-
.split(/[/\\\s:=]+/u)
|
|
226
|
-
.filter((segment) => segment.length > 0);
|
|
227
|
-
return segments.includes(marker) || value.trim().toLowerCase() === marker;
|
|
228
|
-
}
|
|
229
|
-
function currentHarnessSignalDescriptors(localDescriptors = []) {
|
|
230
|
-
const adapterDescriptors = new Map(BUILTIN_HARNESS_SIGNAL_DESCRIPTORS.filter((descriptor) => descriptor.harness !== "ci").map((descriptor) => [
|
|
231
|
-
descriptor.harness,
|
|
232
|
-
normalizeHarnessSignalDescriptor(descriptor),
|
|
233
|
-
]));
|
|
234
|
-
for (const { adapter } of registeredAgentProvenanceAdapters.values()) {
|
|
235
|
-
adapterDescriptors.set(adapter.harness, normalizeHarnessSignalDescriptor(adapter.descriptor));
|
|
236
|
-
}
|
|
237
|
-
const descriptors = [
|
|
238
|
-
...adapterDescriptors.values(),
|
|
239
|
-
...NORMALIZED_BUILTIN_HARNESS_SIGNAL_DESCRIPTORS.filter((descriptor) => descriptor.harness === "ci"),
|
|
240
|
-
...[...registeredHarnessSignalDescriptors.values()].map((entry) => entry.descriptor),
|
|
241
|
-
...(workspaceHarnessSignalsStorage.getStore()?.descriptors ?? []),
|
|
242
|
-
...localDescriptors.map(normalizeHarnessSignalDescriptor),
|
|
243
|
-
];
|
|
244
|
-
const seen = new Set();
|
|
245
|
-
for (const descriptor of descriptors) {
|
|
246
|
-
if (seen.has(descriptor.harness)) {
|
|
247
|
-
throw new Error(`Harness signal descriptor collision for "${descriptor.harness}"`);
|
|
248
|
-
}
|
|
249
|
-
seen.add(descriptor.harness);
|
|
250
|
-
}
|
|
251
|
-
return descriptors;
|
|
252
|
-
}
|
|
253
|
-
function firstEnvironmentValue(env, keys) {
|
|
254
|
-
for (const key of keys ?? []) {
|
|
255
|
-
const value = nonBlank(env[key]);
|
|
256
|
-
if (value)
|
|
257
|
-
return value.slice(0, 256);
|
|
258
|
-
}
|
|
259
|
-
return undefined;
|
|
260
|
-
}
|
|
261
|
-
function provenanceFromArgv(argv, dimension) {
|
|
262
|
-
if (dimension === "role") {
|
|
263
|
-
const command = argv
|
|
264
|
-
.slice(0, 8)
|
|
265
|
-
.map((token) => token.trim().toLowerCase())
|
|
266
|
-
.find((token) => ["claim", "create", "update", "close", "release", "review"].includes(token));
|
|
267
|
-
if (command === "review")
|
|
268
|
-
return "reviewer";
|
|
269
|
-
if (command)
|
|
270
|
-
return "implementer";
|
|
271
|
-
}
|
|
272
|
-
return undefined;
|
|
273
|
-
}
|
|
274
|
-
function provenanceFlagValue(argv, dimension) {
|
|
275
|
-
const acceptedFlags = dimension === "model"
|
|
276
|
-
? ["--model", "--agent-model"]
|
|
277
|
-
: [`--agent-${dimension}`];
|
|
278
|
-
const tokens = argv.slice(0, 8);
|
|
279
|
-
for (let index = 0; index < tokens.length; index += 1) {
|
|
280
|
-
const token = tokens[index].slice(0, 512);
|
|
281
|
-
if (acceptedFlags.includes(token)) {
|
|
282
|
-
return nonBlank(tokens[index + 1])?.slice(0, 256);
|
|
283
|
-
}
|
|
284
|
-
const prefix = acceptedFlags.find((flag) => token.startsWith(`${flag}=`));
|
|
285
|
-
if (prefix) {
|
|
286
|
-
return nonBlank(token.slice(prefix.length + 1))?.slice(0, 256);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
return undefined;
|
|
290
|
-
}
|
|
291
|
-
const AGENT_ROLE_VALUES = new Set([
|
|
292
|
-
"implementation",
|
|
293
|
-
"implementer",
|
|
294
|
-
"investigator",
|
|
295
|
-
"orchestrator",
|
|
296
|
-
"planner",
|
|
297
|
-
"release-operator",
|
|
298
|
-
"reviewer",
|
|
299
|
-
]);
|
|
300
|
-
function normalizeProvenanceValue(dimension, value) {
|
|
301
|
-
if (dimension !== "role" || value === undefined)
|
|
302
|
-
return value;
|
|
303
|
-
const normalized = value
|
|
304
|
-
.trim()
|
|
305
|
-
.toLowerCase()
|
|
306
|
-
.replaceAll(/[_\s]+/gu, "-");
|
|
307
|
-
return AGENT_ROLE_VALUES.has(normalized) ? normalized : undefined;
|
|
308
|
-
}
|
|
309
|
-
function boundedProvenanceValue(provenance, dimension) {
|
|
310
|
-
return nonBlank(provenance?.[dimension])?.slice(0, 256);
|
|
311
|
-
}
|
|
312
|
-
const MAX_PROVENANCE_PROBE_BYTES = 1_048_576;
|
|
313
|
-
const MAX_CODEX_PROVENANCE_PROBE_BYTES = 4_194_304;
|
|
314
|
-
const codexProvenanceSnapshotCache = new Map();
|
|
315
|
-
const EMPTY_CODEX_PROVENANCE_SNAPSHOT = Object.freeze({});
|
|
316
|
-
const claudeProvenanceSnapshotCache = new Map();
|
|
317
|
-
const EMPTY_CLAUDE_PROVENANCE_SNAPSHOT = Object.freeze({});
|
|
318
|
-
function asProvenanceRecord(value) {
|
|
319
|
-
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
320
|
-
? value
|
|
321
|
-
: undefined;
|
|
322
|
-
}
|
|
323
|
-
function parseClaudeProvenanceLine(line) {
|
|
324
|
-
let parsed;
|
|
325
|
-
try {
|
|
326
|
-
parsed = JSON.parse(line);
|
|
327
|
-
}
|
|
328
|
-
catch {
|
|
329
|
-
return EMPTY_CLAUDE_PROVENANCE_SNAPSHOT;
|
|
330
|
-
}
|
|
331
|
-
const record = asProvenanceRecord(parsed);
|
|
332
|
-
if (!record)
|
|
333
|
-
return EMPTY_CLAUDE_PROVENANCE_SNAPSHOT;
|
|
334
|
-
const queue = [
|
|
335
|
-
{ value: record, depth: 0 },
|
|
336
|
-
];
|
|
337
|
-
let visited = 0;
|
|
338
|
-
let model;
|
|
339
|
-
let version;
|
|
340
|
-
while (queue.length > 0 && visited < 64) {
|
|
341
|
-
const current = queue.shift();
|
|
342
|
-
visited += 1;
|
|
343
|
-
model ??= nonBlank(current.value.model)?.slice(0, 256);
|
|
344
|
-
version ??= nonBlank(current.value.version)?.slice(0, 256);
|
|
345
|
-
if (model && version)
|
|
346
|
-
break;
|
|
347
|
-
if (current.depth >= 4)
|
|
348
|
-
continue;
|
|
349
|
-
for (const value of Object.values(current.value)) {
|
|
350
|
-
const nested = asProvenanceRecord(value);
|
|
351
|
-
if (nested) {
|
|
352
|
-
queue.push({
|
|
353
|
-
value: nested,
|
|
354
|
-
depth: current.depth + 1,
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
return Object.freeze({ model, version });
|
|
360
|
-
}
|
|
361
|
-
/** Classify one candidate without following symlinks or leaking filesystem detail. */
|
|
362
|
-
function claudeTranscriptCandidateStatus(candidate) {
|
|
363
|
-
try {
|
|
364
|
-
return fs.lstatSync(candidate).isFile() ? "available" : "missing";
|
|
365
|
-
}
|
|
366
|
-
catch (error) {
|
|
367
|
-
return isFileAbsentError(error) ? "missing" : "failed";
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
/** Resolve a bounded cross-workspace Claude transcript discovery result. */
|
|
371
|
-
function discoverClaudeSessionFile(projectsRoot, session) {
|
|
372
|
-
let discovered;
|
|
373
|
-
try {
|
|
374
|
-
discovered = fs
|
|
375
|
-
.readdirSync(projectsRoot, { withFileTypes: true })
|
|
376
|
-
.filter((entry) => entry.isDirectory())
|
|
377
|
-
.sort((left, right) => left.name.localeCompare(right.name))
|
|
378
|
-
.slice(0, 512)
|
|
379
|
-
.map((entry) => {
|
|
380
|
-
const candidate = path.join(projectsRoot, entry.name, `${session}.jsonl`);
|
|
381
|
-
return {
|
|
382
|
-
candidate,
|
|
383
|
-
status: claudeTranscriptCandidateStatus(candidate),
|
|
384
|
-
};
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
|
-
catch (error) {
|
|
388
|
-
return { status: isFileAbsentError(error) ? "missing" : "failed" };
|
|
389
|
-
}
|
|
390
|
-
const matches = discovered
|
|
391
|
-
.filter(({ status }) => status === "available")
|
|
392
|
-
.map(({ candidate }) => candidate);
|
|
393
|
-
if (matches.length === 0) {
|
|
394
|
-
return {
|
|
395
|
-
status: discovered.some(({ status }) => status === "failed")
|
|
396
|
-
? "failed"
|
|
397
|
-
: "missing",
|
|
398
|
-
};
|
|
399
|
-
}
|
|
400
|
-
if (matches.length > 1)
|
|
401
|
-
return { status: "ambiguous" };
|
|
402
|
-
return { status: "available", path: matches[0] };
|
|
403
|
-
}
|
|
404
|
-
/** Resolve one Claude transcript by stable session identity without exposing its path. */
|
|
405
|
-
function resolveClaudeSessionFile(signals, env) {
|
|
406
|
-
const session = nonBlank(env.CLAUDE_CODE_SESSION_ID);
|
|
407
|
-
if (!session || !/^[A-Za-z0-9_-]{1,128}$/u.test(session)) {
|
|
408
|
-
return { status: "unavailable" };
|
|
409
|
-
}
|
|
410
|
-
const workspace = path.resolve(signals.cwd ?? process.cwd());
|
|
411
|
-
const encodedWorkspace = workspace.replaceAll(/[^A-Za-z0-9-]/gu, "-");
|
|
412
|
-
const projectsRoot = path.join(signals.home_dir ?? os.homedir(), ".claude", "projects");
|
|
413
|
-
const directPath = path.join(projectsRoot, encodedWorkspace, `${session}.jsonl`);
|
|
414
|
-
const explicitPath = nonBlank(signals.session_file);
|
|
415
|
-
const suppliedPath = explicitPath && path.basename(explicitPath) === `${session}.jsonl`
|
|
416
|
-
? explicitPath
|
|
417
|
-
: undefined;
|
|
418
|
-
for (const candidate of [suppliedPath, directPath]) {
|
|
419
|
-
if (!candidate)
|
|
420
|
-
continue;
|
|
421
|
-
const status = claudeTranscriptCandidateStatus(candidate);
|
|
422
|
-
if (status === "available")
|
|
423
|
-
return { status, path: candidate };
|
|
424
|
-
if (status === "failed")
|
|
425
|
-
return { status };
|
|
426
|
-
}
|
|
427
|
-
return discoverClaudeSessionFile(projectsRoot, session);
|
|
428
|
-
}
|
|
429
|
-
function readClaudeSessionProvenance(dimension, signals, env) {
|
|
430
|
-
const resolution = resolveClaudeSessionFile(signals, env);
|
|
431
|
-
if (resolution.status !== "available")
|
|
432
|
-
return undefined;
|
|
433
|
-
try {
|
|
434
|
-
const file = fs.openSync(resolution.path, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);
|
|
435
|
-
try {
|
|
436
|
-
const stats = fs.fstatSync(file);
|
|
437
|
-
const cacheKey = `${resolution.path}\u0000${stats.size}\u0000${stats.mtimeMs}`;
|
|
438
|
-
const cached = claudeProvenanceSnapshotCache.get(cacheKey);
|
|
439
|
-
if (cached)
|
|
440
|
-
return cached[dimension];
|
|
441
|
-
const probeLength = Math.min(stats.size, MAX_PROVENANCE_PROBE_BYTES);
|
|
442
|
-
const headLength = Math.min(probeLength, Math.ceil(probeLength / 2));
|
|
443
|
-
const tailLength = Math.min(probeLength - headLength, stats.size - headLength);
|
|
444
|
-
const head = Buffer.alloc(headLength);
|
|
445
|
-
fs.readSync(file, head, 0, headLength, 0);
|
|
446
|
-
const tail = Buffer.alloc(tailLength);
|
|
447
|
-
if (tailLength > 0) {
|
|
448
|
-
fs.readSync(file, tail, 0, tailLength, stats.size - tailLength);
|
|
449
|
-
}
|
|
450
|
-
const snapshot = {};
|
|
451
|
-
const lines = stats.size <= probeLength
|
|
452
|
-
? Buffer.concat([head, tail]).toString("utf8").split("\n")
|
|
453
|
-
: [
|
|
454
|
-
...head.toString("utf8").split("\n").slice(0, 4_096),
|
|
455
|
-
...tail.toString("utf8").split("\n").slice(-4_096),
|
|
456
|
-
];
|
|
457
|
-
for (const line of lines) {
|
|
458
|
-
if (line.length === 0 || line.length > 262_144)
|
|
459
|
-
continue;
|
|
460
|
-
const parsed = parseClaudeProvenanceLine(line);
|
|
461
|
-
snapshot.model ??= parsed.model;
|
|
462
|
-
snapshot.version ??= parsed.version;
|
|
463
|
-
if (snapshot.model && snapshot.version)
|
|
464
|
-
break;
|
|
465
|
-
}
|
|
466
|
-
const frozen = Object.freeze(snapshot);
|
|
467
|
-
claudeProvenanceSnapshotCache.clear();
|
|
468
|
-
claudeProvenanceSnapshotCache.set(cacheKey, frozen);
|
|
469
|
-
return frozen[dimension];
|
|
470
|
-
}
|
|
471
|
-
finally {
|
|
472
|
-
fs.closeSync(file);
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
catch {
|
|
476
|
-
return undefined;
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
function findCodexSessionFile(root, session) {
|
|
480
|
-
let visited = 0;
|
|
481
|
-
const visit = (directory, depth) => {
|
|
482
|
-
if (depth > 4 || visited >= 512)
|
|
483
|
-
return undefined;
|
|
484
|
-
let entries;
|
|
485
|
-
try {
|
|
486
|
-
entries = fs
|
|
487
|
-
.readdirSync(directory, { withFileTypes: true })
|
|
488
|
-
.sort((left, right) => right.name.localeCompare(left.name));
|
|
489
|
-
}
|
|
490
|
-
catch {
|
|
491
|
-
return undefined;
|
|
492
|
-
}
|
|
493
|
-
for (const entry of entries) {
|
|
494
|
-
visited += 1;
|
|
495
|
-
if (visited > 512)
|
|
496
|
-
return undefined;
|
|
497
|
-
const entryPath = path.join(directory, entry.name);
|
|
498
|
-
if (entry.isFile() && entry.name.endsWith(`-${session}.jsonl`)) {
|
|
499
|
-
return entryPath;
|
|
500
|
-
}
|
|
501
|
-
if (entry.isDirectory()) {
|
|
502
|
-
const found = visit(entryPath, depth + 1);
|
|
503
|
-
if (found)
|
|
504
|
-
return found;
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
return undefined;
|
|
508
|
-
};
|
|
509
|
-
return visit(root, 0);
|
|
510
|
-
}
|
|
511
|
-
function codexProvenanceWindows(size) {
|
|
512
|
-
if (size <= MAX_CODEX_PROVENANCE_PROBE_BYTES) {
|
|
513
|
-
return [{ offset: 0, length: size }];
|
|
514
|
-
}
|
|
515
|
-
const halfBudget = Math.floor(MAX_CODEX_PROVENANCE_PROBE_BYTES / 2);
|
|
516
|
-
return [
|
|
517
|
-
{ offset: size - halfBudget, length: halfBudget },
|
|
518
|
-
{ offset: 0, length: halfBudget },
|
|
519
|
-
];
|
|
520
|
-
}
|
|
521
|
-
function mergeCodexTurnContext(snapshot, line) {
|
|
522
|
-
if (line.length === 0 || line.length > 262_144)
|
|
523
|
-
return;
|
|
524
|
-
let parsed;
|
|
525
|
-
try {
|
|
526
|
-
parsed = JSON.parse(line);
|
|
527
|
-
}
|
|
528
|
-
catch {
|
|
529
|
-
return;
|
|
530
|
-
}
|
|
531
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
532
|
-
return;
|
|
533
|
-
}
|
|
534
|
-
const record = parsed;
|
|
535
|
-
if (record.type !== "turn_context")
|
|
536
|
-
return;
|
|
537
|
-
const payload = typeof record.payload === "object" && record.payload !== null
|
|
538
|
-
? record.payload
|
|
539
|
-
: undefined;
|
|
540
|
-
snapshot.model ??= nonBlank(payload?.model)?.slice(0, 256);
|
|
541
|
-
snapshot.effort ??= nonBlank(payload?.effort)?.slice(0, 256);
|
|
542
|
-
}
|
|
543
|
-
function readCodexProvenanceSnapshot(file, size) {
|
|
544
|
-
const snapshot = {};
|
|
545
|
-
let linesRemaining = 4_096;
|
|
546
|
-
for (const window of codexProvenanceWindows(size)) {
|
|
547
|
-
const buffer = Buffer.alloc(window.length);
|
|
548
|
-
fs.readSync(file, buffer, 0, window.length, window.offset);
|
|
549
|
-
const lines = buffer
|
|
550
|
-
.toString("utf8")
|
|
551
|
-
.split("\n")
|
|
552
|
-
.reverse()
|
|
553
|
-
.slice(0, linesRemaining);
|
|
554
|
-
linesRemaining -= lines.length;
|
|
555
|
-
for (const line of lines) {
|
|
556
|
-
mergeCodexTurnContext(snapshot, line);
|
|
557
|
-
if (snapshot.model && snapshot.effort)
|
|
558
|
-
break;
|
|
559
|
-
}
|
|
560
|
-
if ((snapshot.model && snapshot.effort) || linesRemaining <= 0)
|
|
561
|
-
break;
|
|
562
|
-
}
|
|
563
|
-
return snapshot;
|
|
564
|
-
}
|
|
565
|
-
function readCodexSessionProvenance(dimension, signals, env) {
|
|
566
|
-
const session = nonBlank(env.CODEX_THREAD_ID);
|
|
567
|
-
if (!session || !/^[A-Za-z0-9_-]{1,128}$/u.test(session))
|
|
568
|
-
return undefined;
|
|
569
|
-
const sessionsRoot = path.join(signals.home_dir ?? os.homedir(), ".codex", "sessions");
|
|
570
|
-
const cacheKey = `${sessionsRoot}\0${session}`;
|
|
571
|
-
const cached = codexProvenanceSnapshotCache.get(cacheKey);
|
|
572
|
-
if (cached)
|
|
573
|
-
return cached[dimension];
|
|
574
|
-
const sessionPath = findCodexSessionFile(sessionsRoot, session);
|
|
575
|
-
if (!sessionPath) {
|
|
576
|
-
codexProvenanceSnapshotCache.set(cacheKey, EMPTY_CODEX_PROVENANCE_SNAPSHOT);
|
|
577
|
-
return undefined;
|
|
578
|
-
}
|
|
579
|
-
try {
|
|
580
|
-
const file = fs.openSync(sessionPath, "r");
|
|
581
|
-
try {
|
|
582
|
-
const size = fs.fstatSync(file).size;
|
|
583
|
-
const snapshot = readCodexProvenanceSnapshot(file, size);
|
|
584
|
-
codexProvenanceSnapshotCache.set(cacheKey, snapshot);
|
|
585
|
-
return snapshot[dimension];
|
|
586
|
-
}
|
|
587
|
-
finally {
|
|
588
|
-
fs.closeSync(file);
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
catch {
|
|
592
|
-
codexProvenanceSnapshotCache.set(cacheKey, EMPTY_CODEX_PROVENANCE_SNAPSHOT);
|
|
593
|
-
return undefined;
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
function resolveProvenanceProbe(dimension, signals, env, descriptor) {
|
|
597
|
-
const workspaceSignals = workspaceHarnessSignalsStorage.getStore();
|
|
598
|
-
const enabled = signals.probes_enabled !== false &&
|
|
599
|
-
workspaceSignals?.probesEnabled !== false &&
|
|
600
|
-
!["0", "false", "off"].includes(nonBlank(env.PM_AGENT_PROBES)?.toLowerCase() ?? "");
|
|
601
|
-
if (!enabled)
|
|
602
|
-
return undefined;
|
|
603
|
-
const resolver = descriptor?.provenance_resolvers[dimension];
|
|
604
|
-
if (resolver === "claude_session_file") {
|
|
605
|
-
return readClaudeSessionProvenance(dimension, signals, env);
|
|
606
|
-
}
|
|
607
|
-
if (resolver === "codex_session_file") {
|
|
608
|
-
return readCodexSessionProvenance(dimension, signals, env);
|
|
609
|
-
}
|
|
610
|
-
if (resolver === "ai_agent_version") {
|
|
611
|
-
const value = nonBlank(env.AI_AGENT);
|
|
612
|
-
if (!value ||
|
|
613
|
-
!descriptor ||
|
|
614
|
-
!literalSignalMatches(value, descriptor.harness)) {
|
|
615
|
-
return undefined;
|
|
616
|
-
}
|
|
617
|
-
const match = /(?:^|[@/\s])v?(\d+\.\d+(?:\.\d+)?(?:[-+][A-Za-z0-9.-]+)?)$/u.exec(value);
|
|
618
|
-
return match?.[1]?.slice(0, 256);
|
|
619
|
-
}
|
|
620
|
-
return undefined;
|
|
621
|
-
}
|
|
622
|
-
function provenanceResolverHasInput(resolver, descriptor, signals, env) {
|
|
623
|
-
if (resolver === "ai_agent_version") {
|
|
624
|
-
const value = nonBlank(env.AI_AGENT);
|
|
625
|
-
return value !== undefined &&
|
|
626
|
-
literalSignalMatches(value, descriptor.harness)
|
|
627
|
-
? "available"
|
|
628
|
-
: "unavailable";
|
|
629
|
-
}
|
|
630
|
-
if (resolver === "codex_session_file") {
|
|
631
|
-
return nonBlank(env.CODEX_THREAD_ID) !== undefined
|
|
632
|
-
? "available"
|
|
633
|
-
: "unavailable";
|
|
634
|
-
}
|
|
635
|
-
return resolveClaudeSessionFile(signals, env).status;
|
|
636
|
-
}
|
|
637
|
-
function effectiveHarnessDetectionSignals(signals) {
|
|
638
|
-
if (signals)
|
|
639
|
-
return signals;
|
|
640
|
-
return (harnessDetectionStorage.getStore() ?? {
|
|
641
|
-
env: process.env,
|
|
642
|
-
argv: process.argv,
|
|
643
|
-
});
|
|
644
|
-
}
|
|
645
|
-
function descriptorMatchesSignals(descriptor, env, labels, clientName) {
|
|
646
|
-
const environmentMatch = descriptor.environment_keys.some((key) => nonBlank(env[key]) !== undefined);
|
|
647
|
-
const argvMatch = descriptor.argv_markers.some((marker) => labels.some((label) => {
|
|
648
|
-
const normalizedPath = label.replaceAll("\\", "/");
|
|
649
|
-
return literalSignalMatches(normalizedPath.slice(normalizedPath.lastIndexOf("/") + 1), marker);
|
|
650
|
-
}));
|
|
651
|
-
const clientMatch = descriptor.client_names.some((name) => clientName === name || literalSignalMatches(clientName, name));
|
|
652
|
-
return environmentMatch || argvMatch || clientMatch;
|
|
653
|
-
}
|
|
654
|
-
function inferredProvenanceObservation(dimension, semanticAttribution) {
|
|
655
|
-
if (!semanticAttribution)
|
|
656
|
-
return undefined;
|
|
657
|
-
let value;
|
|
658
|
-
if (dimension === "topic")
|
|
659
|
-
value = semanticAttribution.topic;
|
|
660
|
-
if (dimension === "role")
|
|
661
|
-
value = semanticAttribution.role;
|
|
662
|
-
if (!value)
|
|
663
|
-
return undefined;
|
|
664
|
-
return {
|
|
665
|
-
value,
|
|
666
|
-
source: "inferred",
|
|
667
|
-
confidence: semanticAttribution.confidence,
|
|
668
|
-
rule_version: semanticAttribution.rule_version,
|
|
669
|
-
evidence: semanticAttribution.evidence,
|
|
670
|
-
};
|
|
671
|
-
}
|
|
672
|
-
function firstProvenanceObservation(candidates) {
|
|
673
|
-
const observed = candidates.find(([value]) => value !== undefined);
|
|
674
|
-
return observed?.[0]
|
|
675
|
-
? { value: observed[0], source: observed[1] }
|
|
676
|
-
: undefined;
|
|
677
|
-
}
|
|
678
|
-
function resolveAgentProvenanceObservation(dimension, signals, env, descriptor, sessionContext, semanticAttribution) {
|
|
679
|
-
const overrideKey = `PM_AGENT_${dimension.toUpperCase().replaceAll("-", "_")}`;
|
|
680
|
-
const hostResolvedDimensions = new Set([
|
|
681
|
-
...AGENT_PROVENANCE_DIMENSIONS,
|
|
682
|
-
...Object.keys(descriptor?.provenance_environment_keys ?? {}),
|
|
683
|
-
]);
|
|
684
|
-
let overrideValue;
|
|
685
|
-
let argvValue;
|
|
686
|
-
let argvFlagValue;
|
|
687
|
-
if (hostResolvedDimensions.has(dimension)) {
|
|
688
|
-
overrideValue = normalizeProvenanceValue(dimension, nonBlank(env[overrideKey])?.slice(0, 256));
|
|
689
|
-
argvFlagValue = normalizeProvenanceValue(dimension, provenanceFlagValue(signals.argv ?? [], dimension));
|
|
690
|
-
argvValue = normalizeProvenanceValue(dimension, provenanceFromArgv(signals.argv ?? [], dimension));
|
|
691
|
-
}
|
|
692
|
-
const environmentKeysByDimension = {
|
|
693
|
-
...descriptor?.provenance_environment_keys,
|
|
694
|
-
model: descriptor?.model_environment_keys,
|
|
695
|
-
};
|
|
696
|
-
const clientProvenance = {
|
|
697
|
-
...signals.client_info?.provenance,
|
|
698
|
-
model: signals.client_info?.model,
|
|
699
|
-
};
|
|
700
|
-
const sessionValue = boundedProvenanceValue(sessionContext?.provenance, dimension);
|
|
701
|
-
const environmentValue = normalizeProvenanceValue(dimension, firstEnvironmentValue(env, environmentKeysByDimension[dimension]));
|
|
702
|
-
const clientValue = normalizeProvenanceValue(dimension, boundedProvenanceValue(clientProvenance, dimension));
|
|
703
|
-
const hostValue = normalizeProvenanceValue(dimension, boundedProvenanceValue(signals.provenance, dimension));
|
|
704
|
-
const probeValue = resolveProvenanceProbe(dimension, signals, env, descriptor);
|
|
705
|
-
const observed = firstProvenanceObservation([
|
|
706
|
-
[overrideValue, "override"],
|
|
707
|
-
[sessionValue, "session"],
|
|
708
|
-
[argvFlagValue, "argv"],
|
|
709
|
-
[environmentValue, "environment"],
|
|
710
|
-
[clientValue, "mcp_client"],
|
|
711
|
-
[hostValue, "host"],
|
|
712
|
-
[probeValue, "probe"],
|
|
713
|
-
]);
|
|
714
|
-
return (observed ??
|
|
715
|
-
inferredProvenanceObservation(dimension, semanticAttribution) ??
|
|
716
|
-
(argvValue ? { value: argvValue, source: "argv" } : undefined));
|
|
717
|
-
}
|
|
718
|
-
function resolveAgentInstance(harness, session) {
|
|
719
|
-
if (!harness || !session)
|
|
720
|
-
return undefined;
|
|
721
|
-
return createHash("sha256")
|
|
722
|
-
.update(`pm-agent-instance:v1\0${harness}\0${session}`)
|
|
723
|
-
.digest("hex")
|
|
724
|
-
.slice(0, 24);
|
|
725
|
-
}
|
|
726
|
-
function resolveAgentProvenance(signals, env, descriptor, sessionContext, semanticAttribution) {
|
|
727
|
-
const descriptorDimensions = Object.keys(descriptor?.provenance_environment_keys ?? {});
|
|
728
|
-
const dimensions = new Set([
|
|
729
|
-
...AGENT_PROVENANCE_DIMENSIONS,
|
|
730
|
-
...descriptorDimensions,
|
|
731
|
-
...Object.keys(descriptor?.provenance_resolvers ?? {}),
|
|
732
|
-
...Object.keys(signals.provenance ?? {}),
|
|
733
|
-
...Object.keys(signals.client_info?.provenance ?? {}),
|
|
734
|
-
...Object.keys(sessionContext?.provenance ?? {}),
|
|
735
|
-
]);
|
|
736
|
-
const observations = {};
|
|
737
|
-
for (const dimension of dimensions) {
|
|
738
|
-
const observed = resolveAgentProvenanceObservation(dimension, signals, env, descriptor, sessionContext, semanticAttribution);
|
|
739
|
-
if (observed) {
|
|
740
|
-
observations[dimension] = observed;
|
|
741
|
-
}
|
|
742
|
-
else if (descriptor &&
|
|
743
|
-
(dimension !== "version" ||
|
|
744
|
-
descriptor.provenance_unavailable_dimensions.includes(dimension))) {
|
|
745
|
-
observations[dimension] = null;
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
return observations;
|
|
749
|
-
}
|
|
750
|
-
/**
|
|
751
|
-
* Register package-provided harness signals until the returned disposer runs.
|
|
752
|
-
*
|
|
753
|
-
* Built-in and conflicting package namespaces are rejected deterministically.
|
|
754
|
-
* Re-registering an identical package descriptor is reference counted so
|
|
755
|
-
* repeated extension activation remains idempotent.
|
|
756
|
-
*/
|
|
757
|
-
export function registerHarnessSignalDescriptors(descriptors) {
|
|
758
|
-
const normalized = descriptors.map(normalizeHarnessSignalDescriptor);
|
|
759
|
-
const builtins = new Map(NORMALIZED_BUILTIN_HARNESS_SIGNAL_DESCRIPTORS.map((descriptor) => [
|
|
760
|
-
descriptor.harness,
|
|
761
|
-
descriptor,
|
|
762
|
-
]));
|
|
763
|
-
const seen = new Set();
|
|
764
|
-
for (const descriptor of normalized) {
|
|
765
|
-
if (seen.has(descriptor.harness) || builtins.has(descriptor.harness)) {
|
|
766
|
-
throw new Error(`Harness signal descriptor collision for "${descriptor.harness}"`);
|
|
767
|
-
}
|
|
768
|
-
const registered = registeredHarnessSignalDescriptors.get(descriptor.harness);
|
|
769
|
-
if (registered && !descriptorEquals(registered.descriptor, descriptor)) {
|
|
770
|
-
throw new Error(`Harness signal descriptor collision for "${descriptor.harness}"`);
|
|
771
|
-
}
|
|
772
|
-
seen.add(descriptor.harness);
|
|
773
|
-
}
|
|
774
|
-
for (const descriptor of normalized) {
|
|
775
|
-
const registered = registeredHarnessSignalDescriptors.get(descriptor.harness);
|
|
776
|
-
registeredHarnessSignalDescriptors.set(descriptor.harness, {
|
|
777
|
-
descriptor,
|
|
778
|
-
registrations: (registered?.registrations ?? 0) + 1,
|
|
779
|
-
});
|
|
780
|
-
}
|
|
781
|
-
let active = true;
|
|
782
|
-
return () => {
|
|
783
|
-
if (!active)
|
|
784
|
-
return;
|
|
785
|
-
active = false;
|
|
786
|
-
for (const descriptor of normalized) {
|
|
787
|
-
const registered = registeredHarnessSignalDescriptors.get(descriptor.harness);
|
|
788
|
-
if (!registered || registered.registrations <= 1) {
|
|
789
|
-
registeredHarnessSignalDescriptors.delete(descriptor.harness);
|
|
790
|
-
}
|
|
791
|
-
else {
|
|
792
|
-
registered.registrations -= 1;
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
};
|
|
796
|
-
}
|
|
797
|
-
function normalizeAgentProvenanceAdapter(adapter) {
|
|
798
|
-
const descriptor = normalizeHarnessSignalDescriptor(adapter.descriptor);
|
|
799
|
-
const harness = adapter.harness.trim().toLowerCase();
|
|
800
|
-
if (adapter.contract_version !== 1) {
|
|
801
|
-
throw new Error(`Unsupported provenance adapter contract for "${harness}": ${adapter.contract_version}`);
|
|
802
|
-
}
|
|
803
|
-
if (descriptor.harness !== harness) {
|
|
804
|
-
throw new Error(`Provenance adapter harness "${harness}" does not match descriptor "${descriptor.harness}".`);
|
|
805
|
-
}
|
|
806
|
-
const adapterVersion = nonBlank(adapter.adapter_version)?.slice(0, 64);
|
|
807
|
-
if (!adapterVersion) {
|
|
808
|
-
throw new Error(`Provenance adapter "${harness}" requires a version.`);
|
|
809
|
-
}
|
|
810
|
-
if (!Number.isSafeInteger(adapter.priority)) {
|
|
811
|
-
throw new Error(`Provenance adapter "${harness}" requires an integer priority.`);
|
|
812
|
-
}
|
|
813
|
-
if (adapter.probe_policy.network_access !== false ||
|
|
814
|
-
adapter.probe_policy.subprocess_access !== false ||
|
|
815
|
-
adapter.probe_policy.max_bytes > MAX_CODEX_PROVENANCE_PROBE_BYTES ||
|
|
816
|
-
adapter.probe_policy.max_lines > 4_096) {
|
|
817
|
-
throw new Error(`Provenance adapter "${harness}" exceeds the bounded local probe policy.`);
|
|
818
|
-
}
|
|
819
|
-
return Object.freeze({
|
|
820
|
-
...adapter,
|
|
821
|
-
adapter_version: adapterVersion,
|
|
822
|
-
harness,
|
|
823
|
-
descriptor,
|
|
824
|
-
supported_dimensions: Object.freeze(boundedUniqueStrings(adapter.supported_dimensions)
|
|
825
|
-
.map((dimension) => dimension.toLowerCase())
|
|
826
|
-
.sort()),
|
|
827
|
-
native_sources: Object.freeze([...new Set(adapter.native_sources)]),
|
|
828
|
-
probe_policy: Object.freeze({ ...adapter.probe_policy }),
|
|
829
|
-
normalization: Object.freeze({ ...adapter.normalization }),
|
|
830
|
-
...(adapter.waivers
|
|
831
|
-
? {
|
|
832
|
-
waivers: Object.freeze(Object.fromEntries(Object.entries(adapter.waivers)
|
|
833
|
-
.slice(0, 32)
|
|
834
|
-
.map(([dimension, reason]) => [
|
|
835
|
-
dimension.slice(0, 64),
|
|
836
|
-
reason.slice(0, 256),
|
|
837
|
-
]))),
|
|
838
|
-
}
|
|
839
|
-
: {}),
|
|
840
|
-
});
|
|
841
|
-
}
|
|
842
|
-
/** Return the effective built-in or explicitly higher-priority package adapters. */
|
|
843
|
-
export function listAgentProvenanceAdapters() {
|
|
844
|
-
const effective = new Map(BUILTIN_AGENT_PROVENANCE_ADAPTERS.map((adapter) => [
|
|
845
|
-
adapter.harness,
|
|
846
|
-
adapter,
|
|
847
|
-
]));
|
|
848
|
-
for (const { adapter } of registeredAgentProvenanceAdapters.values()) {
|
|
849
|
-
effective.set(adapter.harness, adapter);
|
|
850
|
-
}
|
|
851
|
-
return Object.freeze([...effective.values()].sort((left, right) => left.harness.localeCompare(right.harness)));
|
|
852
|
-
}
|
|
853
|
-
/**
|
|
854
|
-
* Register package adapters until disposal. Replacing a built-in requires an
|
|
855
|
-
* explicitly greater priority; equal-priority ambiguity fails closed.
|
|
856
|
-
*/
|
|
857
|
-
export function registerAgentProvenanceAdapters(adapters) {
|
|
858
|
-
const normalized = adapters.map(normalizeAgentProvenanceAdapter);
|
|
859
|
-
const builtins = new Map(BUILTIN_AGENT_PROVENANCE_ADAPTERS.map((adapter) => [
|
|
860
|
-
adapter.harness,
|
|
861
|
-
adapter,
|
|
862
|
-
]));
|
|
863
|
-
const seen = new Set();
|
|
864
|
-
for (const adapter of normalized) {
|
|
865
|
-
if (seen.has(adapter.harness)) {
|
|
866
|
-
throw new Error(`Provenance adapter collision for "${adapter.harness}".`);
|
|
867
|
-
}
|
|
868
|
-
const builtin = builtins.get(adapter.harness);
|
|
869
|
-
if (builtin && adapter.priority <= builtin.priority) {
|
|
870
|
-
throw new Error(`Provenance adapter override for "${adapter.harness}" requires priority greater than ${builtin.priority}.`);
|
|
871
|
-
}
|
|
872
|
-
const registered = registeredAgentProvenanceAdapters.get(adapter.harness);
|
|
873
|
-
if (registered &&
|
|
874
|
-
JSON.stringify(registered.adapter) !== JSON.stringify(adapter)) {
|
|
875
|
-
throw new Error(`Provenance adapter collision for "${adapter.harness}".`);
|
|
876
|
-
}
|
|
877
|
-
seen.add(adapter.harness);
|
|
878
|
-
}
|
|
879
|
-
for (const adapter of normalized) {
|
|
880
|
-
const registered = registeredAgentProvenanceAdapters.get(adapter.harness);
|
|
881
|
-
registeredAgentProvenanceAdapters.set(adapter.harness, {
|
|
882
|
-
adapter,
|
|
883
|
-
registrations: (registered?.registrations ?? 0) + 1,
|
|
884
|
-
});
|
|
885
|
-
}
|
|
886
|
-
let active = true;
|
|
887
|
-
return () => {
|
|
888
|
-
if (!active)
|
|
889
|
-
return;
|
|
890
|
-
active = false;
|
|
891
|
-
for (const adapter of normalized) {
|
|
892
|
-
const registered = registeredAgentProvenanceAdapters.get(adapter.harness);
|
|
893
|
-
if (!registered || registered.registrations <= 1) {
|
|
894
|
-
registeredAgentProvenanceAdapters.delete(adapter.harness);
|
|
895
|
-
}
|
|
896
|
-
else {
|
|
897
|
-
registered.registrations -= 1;
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
};
|
|
901
|
-
}
|
|
902
|
-
/** Normalize model-family or effort vocabulary while retaining the raw value. */
|
|
903
|
-
export function normalizeAgentProvenanceAdapterValue(dimension, value) {
|
|
904
|
-
const raw = value.trim().slice(0, 256);
|
|
905
|
-
let normalized = raw.toLowerCase();
|
|
906
|
-
if (dimension === "model") {
|
|
907
|
-
const family = /^(gpt-\d+(?:\.\d+)?)/u.exec(normalized)?.[1];
|
|
908
|
-
if (family)
|
|
909
|
-
normalized = family;
|
|
910
|
-
}
|
|
911
|
-
else {
|
|
912
|
-
normalized = normalized.replaceAll(/[_\s-]+/gu, "");
|
|
913
|
-
const effortAliases = {
|
|
914
|
-
minimal: "low",
|
|
915
|
-
low: "low",
|
|
916
|
-
medium: "medium",
|
|
917
|
-
high: "high",
|
|
918
|
-
xhigh: "xhigh",
|
|
919
|
-
max: "max",
|
|
920
|
-
ultra: "ultra",
|
|
921
|
-
};
|
|
922
|
-
normalized = effortAliases[normalized] ?? normalized;
|
|
923
|
-
}
|
|
924
|
-
return { raw, normalized, vocabulary: "v1" };
|
|
925
|
-
}
|
|
926
|
-
/** Run one invocation with host-provided detection signals available downstream. */
|
|
927
|
-
export function runWithHarnessDetectionSignals(signals, callback) {
|
|
928
|
-
return harnessDetectionStorage.run(signals, callback);
|
|
929
|
-
}
|
|
930
|
-
/** Run one invocation with workspace-provided descriptors available downstream. */
|
|
931
|
-
export function runWithWorkspaceHarnessSignalDescriptors(descriptors, callback, options = {}) {
|
|
932
|
-
const normalized = descriptors.map(normalizeHarnessSignalDescriptor);
|
|
933
|
-
currentHarnessSignalDescriptors(normalized);
|
|
934
|
-
return workspaceHarnessSignalsStorage.run({
|
|
935
|
-
descriptors: normalized,
|
|
936
|
-
probesEnabled: options.probesEnabled !== false,
|
|
937
|
-
}, callback);
|
|
938
|
-
}
|
|
939
|
-
/**
|
|
940
|
-
* Detect structured agent provenance from bounded caller-supplied signals.
|
|
941
|
-
*
|
|
942
|
-
* The function is deterministic and side-effect free. Descriptor values are
|
|
943
|
-
* treated as literal strings; they never execute regexes, commands, filesystem
|
|
944
|
-
* traversal, or network requests.
|
|
945
|
-
*/
|
|
946
|
-
export function detectAgentIdentity(signals) {
|
|
947
|
-
const effectiveSignals = effectiveHarnessDetectionSignals(signals);
|
|
948
|
-
const env = effectiveSignals.env ?? {};
|
|
949
|
-
const descriptors = currentHarnessSignalDescriptors(effectiveSignals.descriptors);
|
|
950
|
-
const labels = [
|
|
951
|
-
...(effectiveSignals.argv ?? []).slice(0, 3),
|
|
952
|
-
...(effectiveSignals.process_labels ?? []),
|
|
953
|
-
]
|
|
954
|
-
.slice(0, 64)
|
|
955
|
-
.map((token) => token.slice(0, 512));
|
|
956
|
-
const clientName = effectiveSignals.client_info?.name.trim().toLowerCase() ?? "";
|
|
957
|
-
const descriptor = descriptors.find((candidate) => descriptorMatchesSignals(candidate, env, labels, clientName));
|
|
958
|
-
const sessionContext = resolveAgentSessionContextFromSignals(effectiveSignals, env);
|
|
959
|
-
const session = [
|
|
960
|
-
firstEnvironmentValue(env, descriptor?.session_environment_keys),
|
|
961
|
-
nonBlank(effectiveSignals.client_info?.session)?.slice(0, 256),
|
|
962
|
-
].find((candidate) => candidate !== undefined);
|
|
963
|
-
const instance = resolveAgentInstance(descriptor?.harness, session);
|
|
964
|
-
const semanticAttribution = readAgentSemanticAttributionSync({
|
|
965
|
-
cwd: effectiveSignals.cwd ?? process.cwd(),
|
|
966
|
-
env,
|
|
967
|
-
key: instance,
|
|
968
|
-
});
|
|
969
|
-
const provenance = resolveAgentProvenance(effectiveSignals, env, descriptor, sessionContext, semanticAttribution);
|
|
970
|
-
const modelCandidate = provenance.model;
|
|
971
|
-
const entries = [
|
|
972
|
-
["harness", descriptor?.harness],
|
|
973
|
-
["model", modelCandidate?.value],
|
|
974
|
-
["model_source", modelCandidate?.source],
|
|
975
|
-
["session", session],
|
|
976
|
-
["instance", instance],
|
|
977
|
-
["provenance", Object.keys(provenance).length > 0 ? provenance : undefined],
|
|
978
|
-
["episode", sessionContext.episode],
|
|
979
|
-
];
|
|
980
|
-
return Object.fromEntries(entries.filter((entry) => entry[1] !== undefined));
|
|
981
|
-
}
|
|
982
|
-
/** Classify one configured resolver's privacy-safe absence outcome. */
|
|
983
|
-
function provenanceResolverAbsence(resolverInput) {
|
|
984
|
-
if (resolverInput === "unavailable") {
|
|
985
|
-
return { status: "unavailable", reason: "harness_unavailable" };
|
|
986
|
-
}
|
|
987
|
-
if (resolverInput === "missing") {
|
|
988
|
-
return { status: "unavailable", reason: "resolver_input_missing" };
|
|
989
|
-
}
|
|
990
|
-
return { status: "failed", reason: "resolver_failed" };
|
|
991
|
-
}
|
|
992
|
-
function resolveProvenanceOutcome(dimension, identity, descriptor, signals, env, probesEnabled, invalidValue) {
|
|
993
|
-
const resolver = descriptor?.provenance_resolvers[dimension];
|
|
994
|
-
if (identity.provenance?.[dimension]) {
|
|
995
|
-
return {
|
|
996
|
-
status: "resolved",
|
|
997
|
-
...(resolver ? { resolver } : {}),
|
|
998
|
-
rule_version: "v1",
|
|
999
|
-
};
|
|
1000
|
-
}
|
|
1001
|
-
if (invalidValue) {
|
|
1002
|
-
return {
|
|
1003
|
-
status: "unavailable",
|
|
1004
|
-
reason: "invalid_value",
|
|
1005
|
-
rule_version: "v1",
|
|
1006
|
-
};
|
|
1007
|
-
}
|
|
1008
|
-
if (resolver) {
|
|
1009
|
-
if (!probesEnabled) {
|
|
1010
|
-
return {
|
|
1011
|
-
status: "unavailable",
|
|
1012
|
-
reason: "probes_disabled",
|
|
1013
|
-
resolver,
|
|
1014
|
-
rule_version: "v1",
|
|
1015
|
-
};
|
|
1016
|
-
}
|
|
1017
|
-
const resolverInput = provenanceResolverHasInput(resolver, descriptor, signals, env);
|
|
1018
|
-
return {
|
|
1019
|
-
...provenanceResolverAbsence(resolverInput),
|
|
1020
|
-
resolver,
|
|
1021
|
-
rule_version: "v1",
|
|
1022
|
-
};
|
|
1023
|
-
}
|
|
1024
|
-
return {
|
|
1025
|
-
status: descriptor?.provenance_unavailable_dimensions.includes(dimension)
|
|
1026
|
-
? "unavailable"
|
|
1027
|
-
: "not_configured",
|
|
1028
|
-
reason: descriptor?.provenance_unavailable_dimensions.includes(dimension)
|
|
1029
|
-
? "harness_unavailable"
|
|
1030
|
-
: "resolver_not_configured",
|
|
1031
|
-
rule_version: "v1",
|
|
1032
|
-
};
|
|
1033
|
-
}
|
|
1034
|
-
/**
|
|
1035
|
-
* Diagnose provenance without exposing environment values, paths, or probe data.
|
|
1036
|
-
*
|
|
1037
|
-
* This additive SDK contract keeps legacy `detectAgentIdentity` projections
|
|
1038
|
-
* stable while giving health checks and history writers explicit absence states.
|
|
1039
|
-
*/
|
|
1040
|
-
export function diagnoseAgentIdentity(signals) {
|
|
1041
|
-
const effectiveSignals = effectiveHarnessDetectionSignals(signals);
|
|
1042
|
-
const identity = detectAgentIdentity(effectiveSignals);
|
|
1043
|
-
const descriptor = currentHarnessSignalDescriptors(effectiveSignals.descriptors).find((candidate) => candidate.harness === identity.harness);
|
|
1044
|
-
const env = effectiveSignals.env ?? {};
|
|
1045
|
-
const probesEnabled = effectiveSignals.probes_enabled !== false &&
|
|
1046
|
-
workspaceHarnessSignalsStorage.getStore()?.probesEnabled !== false &&
|
|
1047
|
-
!["0", "false", "off"].includes(nonBlank(env.PM_AGENT_PROBES)?.toLowerCase() ?? "");
|
|
1048
|
-
const sessionContext = resolveAgentSessionContextFromSignals(effectiveSignals, env);
|
|
1049
|
-
const invalidRoleValue = [
|
|
1050
|
-
env.PM_AGENT_ROLE,
|
|
1051
|
-
sessionContext.provenance?.role,
|
|
1052
|
-
firstEnvironmentValue(env, descriptor?.provenance_environment_keys.role),
|
|
1053
|
-
effectiveSignals.client_info?.provenance?.role,
|
|
1054
|
-
effectiveSignals.provenance?.role,
|
|
1055
|
-
provenanceFlagValue(effectiveSignals.argv ?? [], "role"),
|
|
1056
|
-
].some((candidate) => {
|
|
1057
|
-
const value = nonBlank(candidate)?.slice(0, 256);
|
|
1058
|
-
return (value !== undefined &&
|
|
1059
|
-
normalizeProvenanceValue("role", value) === undefined);
|
|
1060
|
-
});
|
|
1061
|
-
const outcomes = Object.fromEntries(AGENT_PROVENANCE_DIMENSIONS.map((dimension) => [
|
|
1062
|
-
dimension,
|
|
1063
|
-
resolveProvenanceOutcome(dimension, identity, descriptor, effectiveSignals, env, probesEnabled, dimension === "role" && invalidRoleValue),
|
|
1064
|
-
]));
|
|
1065
|
-
return { ...identity, provenance_outcomes: outcomes };
|
|
1066
|
-
}
|
|
1067
|
-
/** Reads the invocation-wide author override through the canonical environment seam. */
|
|
1068
|
-
export function readAuthorEnvironment() {
|
|
1069
|
-
return process.env.PM_AUTHOR;
|
|
1070
|
-
}
|
|
1071
|
-
/** Updates or clears the invocation-wide author override through the canonical environment seam. */
|
|
1072
|
-
export function writeAuthorEnvironment(author) {
|
|
1073
|
-
if (author === undefined)
|
|
1074
|
-
delete process.env.PM_AUTHOR;
|
|
1075
|
-
else
|
|
1076
|
-
process.env.PM_AUTHOR = author;
|
|
1077
|
-
}
|
|
1078
|
-
/**
|
|
1079
|
-
* Detect a known agent harness from bounded, caller-supplied runtime signals.
|
|
1080
|
-
*
|
|
1081
|
-
* The function is pure: it performs no process traversal, subprocess launch,
|
|
1082
|
-
* network access, or telemetry emission. Hosts can therefore use it in
|
|
1083
|
-
* latency-sensitive mutation paths and test every detection branch directly.
|
|
1084
|
-
*/
|
|
1085
|
-
export function detectHarnessIdentity(signals) {
|
|
1086
|
-
return detectAgentIdentity(signals).harness;
|
|
1087
|
-
}
|
|
1088
|
-
/**
|
|
1089
|
-
* Resolve one mutation identity using the stable precedence contract:
|
|
1090
|
-
* explicit argument, `PM_AUTHOR`, configured default, detected harness, then
|
|
1091
|
-
* anonymous fallback.
|
|
1092
|
-
*/
|
|
1093
|
-
export function resolveAuthorIdentity(candidate, fallback, signals) {
|
|
1094
|
-
const effectiveSignals = effectiveHarnessDetectionSignals(signals);
|
|
1095
|
-
const detected = detectAgentIdentity(effectiveSignals);
|
|
1096
|
-
if (candidate !== undefined) {
|
|
1097
|
-
const explicit = nonBlank(candidate);
|
|
1098
|
-
return explicit
|
|
1099
|
-
? { author: explicit, source: "asserted", ...detected }
|
|
1100
|
-
: { author: "unknown", source: "unknown", ...detected };
|
|
1101
|
-
}
|
|
1102
|
-
if (effectiveSignals.env?.PM_AUTHOR !== undefined) {
|
|
1103
|
-
const environment = nonBlank(effectiveSignals.env.PM_AUTHOR);
|
|
1104
|
-
return environment
|
|
1105
|
-
? { author: environment, source: "asserted", ...detected }
|
|
1106
|
-
: { author: "unknown", source: "unknown", ...detected };
|
|
1107
|
-
}
|
|
1108
|
-
const configured = nonBlank(fallback);
|
|
1109
|
-
if (configured) {
|
|
1110
|
-
return { author: configured, source: "configured", ...detected };
|
|
1111
|
-
}
|
|
1112
|
-
if (detected.harness) {
|
|
1113
|
-
return {
|
|
1114
|
-
author: `harness:${detected.harness}`,
|
|
1115
|
-
source: "detected",
|
|
1116
|
-
...detected,
|
|
1117
|
-
};
|
|
1118
|
-
}
|
|
1119
|
-
return { author: "unknown", source: "unknown", ...detected };
|
|
1120
|
-
}
|
|
1121
|
-
/** Return the provenance associated with the current resolved author. */
|
|
1122
|
-
export function resolveHistoryAuthorSource(author) {
|
|
1123
|
-
const active = authorIdentityStorage.getStore();
|
|
1124
|
-
if (active?.author === author) {
|
|
1125
|
-
return active.source;
|
|
1126
|
-
}
|
|
1127
|
-
if (author.startsWith("harness:")) {
|
|
1128
|
-
return "detected";
|
|
1129
|
-
}
|
|
1130
|
-
return author === "unknown" ? "unknown" : "asserted";
|
|
1131
|
-
}
|
|
1132
|
-
/** Return structured agent provenance associated with the current author. */
|
|
1133
|
-
export function resolveHistoryAgentIdentity(author) {
|
|
1134
|
-
const active = authorIdentityStorage.getStore();
|
|
1135
|
-
if (active?.author !== author) {
|
|
1136
|
-
return author.startsWith("harness:")
|
|
1137
|
-
? { harness: author.slice("harness:".length) }
|
|
1138
|
-
: {};
|
|
1139
|
-
}
|
|
1140
|
-
return {
|
|
1141
|
-
...(active.harness ? { harness: active.harness } : {}),
|
|
1142
|
-
...(active.model ? { model: active.model } : {}),
|
|
1143
|
-
...(active.model_source ? { model_source: active.model_source } : {}),
|
|
1144
|
-
...(active.session ? { session: active.session } : {}),
|
|
1145
|
-
...(active.instance ? { instance: active.instance } : {}),
|
|
1146
|
-
...(active.provenance ? { provenance: active.provenance } : {}),
|
|
1147
|
-
...(active.episode ? { episode: active.episode } : {}),
|
|
1148
|
-
};
|
|
1149
|
-
}
|
|
1150
|
-
/**
|
|
1151
|
-
* Resolve the ownership principal for an automatically detected agent.
|
|
1152
|
-
*
|
|
1153
|
-
* Human-facing authors remain stable (`harness:codex`, for example), while a
|
|
1154
|
-
* privacy-safe invocation fingerprint prevents two concurrent sessions of the
|
|
1155
|
-
* same harness from silently sharing one claim. Explicit and configured
|
|
1156
|
-
* authors intentionally retain their asserted principal.
|
|
1157
|
-
*/
|
|
1158
|
-
export function resolveClaimPrincipal(author) {
|
|
1159
|
-
const active = authorIdentityStorage.getStore();
|
|
1160
|
-
return active?.author === author &&
|
|
1161
|
-
active.source === "detected" &&
|
|
1162
|
-
active.instance
|
|
1163
|
-
? `${author}#${active.instance}`
|
|
1164
|
-
: author;
|
|
1165
|
-
}
|
|
1166
|
-
/** Resolves the effective mutation author from explicit input, environment defaults, and fallback settings. */
|
|
1167
|
-
export function resolveAuthor(candidate, fallback) {
|
|
1168
|
-
const identity = resolveAuthorIdentity(candidate, fallback);
|
|
1169
|
-
authorIdentityStorage.enterWith(identity);
|
|
1170
|
-
return identity.author;
|
|
1171
|
-
}
|
|
1
|
+
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="c39d3d14-b0b5-5309-b89a-9da08e1a939a")}catch(e2){}})();import{AsyncLocalStorage}from"node:async_hooks";import{createHash}from"node:crypto";import fs from"node:fs";import os from"node:os";import path from"node:path";import{resolveAgentSessionContextFromSignals}from"./agent-session-context.js";import{readAgentSemanticAttributionSync}from"../session/session-state.js";import{isFileAbsentError}from"../fs/fs-utils.js";const AGENT_PROVENANCE_DIMENSIONS=["model","effort","role","topic","version"];const authorIdentityStorage=new AsyncLocalStorage;const harnessDetectionStorage=new AsyncLocalStorage;const workspaceHarnessSignalsStorage=new AsyncLocalStorage;const BUILTIN_HARNESS_SIGNAL_DESCRIPTORS=[{harness:"claude-code",environment_keys:["CLAUDE_CODE","CLAUDECODE"],model_environment_keys:["ANTHROPIC_MODEL","CLAUDE_MODEL"],session_environment_keys:["CLAUDE_CODE_SESSION_ID"],provenance_environment_keys:{effort:["CLAUDE_EFFORT"]},provenance_resolvers:{model:"claude_session_file",version:"claude_session_file"},provenance_unavailable_dimensions:["role","topic"],argv_markers:["claude","claude-code"],client_names:["claude","claude-code","claude code"]},{harness:"codex",environment_keys:["CODEX_HOME","CODEX_CI","CODEX_THREAD_ID"],model_environment_keys:["CODEX_MODEL"],session_environment_keys:["CODEX_THREAD_ID"],provenance_environment_keys:{effort:["CODEX_REASONING_EFFORT","CODEX_EFFORT"],role:["CODEX_SESSION_ROLE"]},provenance_resolvers:{model:"codex_session_file",effort:"codex_session_file",version:"ai_agent_version"},provenance_unavailable_dimensions:["topic"],argv_markers:["codex"],client_names:["codex"]},{harness:"pi",environment_keys:["PI_AGENT","PI_CODING_AGENT"],model_environment_keys:["PI_MODEL"],session_environment_keys:["PI_SESSION_ID"],provenance_unavailable_dimensions:["effort","role","topic"],argv_markers:["pi"],client_names:["pi"]},{harness:"opencode",environment_keys:["OPENCODE","OPENCODE_SESSION_ID"],model_environment_keys:["OPENCODE_MODEL"],session_environment_keys:["OPENCODE_SESSION_ID"],provenance_unavailable_dimensions:["effort","role","topic"],argv_markers:["opencode"],client_names:["opencode"]},{harness:"cursor",environment_keys:["CURSOR_AGENT","CURSOR_TRACE_ID"],model_environment_keys:["CURSOR_MODEL"],session_environment_keys:["CURSOR_TRACE_ID"],provenance_unavailable_dimensions:["effort","role","topic"],argv_markers:["cursor"],client_names:["cursor"]},{harness:"aider",environment_keys:["AIDER","AIDER_MODEL"],model_environment_keys:["AIDER_MODEL"],session_environment_keys:["AIDER_SESSION_ID"],provenance_unavailable_dimensions:["effort","role","topic"],argv_markers:["aider"],client_names:["aider"]},{harness:"gemini-cli",environment_keys:["GEMINI_CLI","GEMINI_CLI_HOME"],model_environment_keys:["GEMINI_MODEL"],session_environment_keys:["GEMINI_CLI_SESSION_ID"],provenance_unavailable_dimensions:["effort","role","topic"],argv_markers:["gemini","gemini-cli"],client_names:["gemini","gemini-cli","gemini cli"]},{harness:"ci",environment_keys:["CI","GITHUB_ACTIONS","BUILDKITE","GITLAB_CI"],provenance_unavailable_dimensions:["model","effort","role","topic"],argv_markers:[],client_names:[]}];const PROVENANCE_PROBE_POLICY=Object.freeze({max_bytes:1048576,max_lines:4096,network_access:false,subprocess_access:false});const CODEX_PROVENANCE_PROBE_POLICY=Object.freeze({...PROVENANCE_PROBE_POLICY,max_bytes:4194304});const HARNESS_NAMESPACE_PATTERN=/^[a-z0-9]+(?:-[a-z0-9]+)*$/u;function buildBuiltinProvenanceAdapter(descriptor){const unavailableDimensions=normalizeHarnessSignalDescriptor(descriptor).provenance_unavailable_dimensions;const dimensions=new Set(["model","version",...Object.keys(descriptor.provenance_environment_keys??{}),...Object.keys(descriptor.provenance_resolvers??{})]);return Object.freeze({contract_version:1,adapter_version:"v1",priority:0,harness:descriptor.harness,descriptor,supported_dimensions:Object.freeze([...dimensions].sort()),native_sources:Object.freeze(["environment","argv","mcp_client",...Object.values(descriptor.provenance_resolvers??{}).some(resolver=>resolver?.endsWith("session_file"))?["session_file"]:[]]),probe_policy:descriptor.harness==="codex"?CODEX_PROVENANCE_PROBE_POLICY:PROVENANCE_PROBE_POLICY,normalization:Object.freeze({model_family:"v1",effort:"v1",preserve_raw:true}),confidence:"high",waivers:Object.freeze(Object.fromEntries(unavailableDimensions.map(dimension=>[dimension,"Harness does not expose this dimension."])))})}const BUILTIN_AGENT_PROVENANCE_ADAPTERS=Object.freeze(BUILTIN_HARNESS_SIGNAL_DESCRIPTORS.filter(descriptor=>descriptor.harness!=="ci").map(buildBuiltinProvenanceAdapter).sort((left,right)=>left.harness.localeCompare(right.harness)));const registeredAgentProvenanceAdapters=new Map;const registeredHarnessSignalDescriptors=new Map;function nonBlank(value){const trimmed=typeof value==="string"?value.trim():void 0;return trimmed&&trimmed.length>0?trimmed:void 0}function boundedUniqueStrings(values){return[...new Set((values??[]).slice(0,64).map(value=>value.trim()).filter(value=>value.length>0).map(value=>value.slice(0,128)))]}function normalizeHarnessSignalDescriptor(descriptor){const harness=descriptor.harness.trim().toLowerCase();if(!HARNESS_NAMESPACE_PATTERN.test(harness)){throw new Error(`Invalid harness signal descriptor namespace: ${descriptor.harness}`)}return{harness,environment_keys:boundedUniqueStrings(descriptor.environment_keys),model_environment_keys:boundedUniqueStrings(descriptor.model_environment_keys),session_environment_keys:boundedUniqueStrings(descriptor.session_environment_keys),provenance_environment_keys:Object.fromEntries(Object.entries(descriptor.provenance_environment_keys??{}).slice(0,32).map(([dimension,keys])=>[dimension.trim().toLowerCase().slice(0,64),boundedUniqueStrings(keys)]).filter(([dimension])=>HARNESS_NAMESPACE_PATTERN.test(dimension))),provenance_resolvers:Object.fromEntries(Object.entries(descriptor.provenance_resolvers??{}).slice(0,32).map(([dimension,resolver])=>[dimension.trim().toLowerCase().slice(0,64),resolver]).filter(entry=>typeof entry[0]==="string"&&HARNESS_NAMESPACE_PATTERN.test(entry[0])&&(entry[1]==="ai_agent_version"||entry[1]==="claude_session_file"||entry[1]==="codex_session_file"))),provenance_unavailable_dimensions:boundedUniqueStrings(descriptor.provenance_unavailable_dimensions).map(value=>value.toLowerCase()),argv_markers:boundedUniqueStrings(descriptor.argv_markers).map(value=>value.toLowerCase()),client_names:boundedUniqueStrings(descriptor.client_names).map(value=>value.toLowerCase())}}const NORMALIZED_BUILTIN_HARNESS_SIGNAL_DESCRIPTORS=BUILTIN_HARNESS_SIGNAL_DESCRIPTORS.map(normalizeHarnessSignalDescriptor);function descriptorEquals(left,right){return JSON.stringify(left)===JSON.stringify(right)}function literalSignalMatches(value,marker){const segments=value.toLowerCase().slice(0,512).split(/[/\\\s:=]+/u).filter(segment=>segment.length>0);return segments.includes(marker)||value.trim().toLowerCase()===marker}function currentHarnessSignalDescriptors(localDescriptors=[]){const adapterDescriptors=new Map(BUILTIN_HARNESS_SIGNAL_DESCRIPTORS.filter(descriptor=>descriptor.harness!=="ci").map(descriptor=>[descriptor.harness,normalizeHarnessSignalDescriptor(descriptor)]));for(const{adapter}of registeredAgentProvenanceAdapters.values()){adapterDescriptors.set(adapter.harness,normalizeHarnessSignalDescriptor(adapter.descriptor))}const descriptors=[...adapterDescriptors.values(),...NORMALIZED_BUILTIN_HARNESS_SIGNAL_DESCRIPTORS.filter(descriptor=>descriptor.harness==="ci"),...[...registeredHarnessSignalDescriptors.values()].map(entry=>entry.descriptor),...workspaceHarnessSignalsStorage.getStore()?.descriptors??[],...localDescriptors.map(normalizeHarnessSignalDescriptor)];const seen=new Set;for(const descriptor of descriptors){if(seen.has(descriptor.harness)){throw new Error(`Harness signal descriptor collision for "${descriptor.harness}"`)}seen.add(descriptor.harness)}return descriptors}function firstEnvironmentValue(env,keys){for(const key of keys??[]){const value=nonBlank(env[key]);if(value)return value.slice(0,256)}return void 0}function provenanceFromArgv(argv,dimension){if(dimension==="role"){const command=argv.slice(0,8).map(token=>token.trim().toLowerCase()).find(token=>["claim","create","update","close","release","review"].includes(token));if(command==="review")return"reviewer";if(command)return"implementer"}return void 0}function provenanceFlagValue(argv,dimension){const acceptedFlags=dimension==="model"?["--model","--agent-model"]:[`--agent-${dimension}`];const tokens=argv.slice(0,8);for(let index=0;index<tokens.length;index+=1){const token=tokens[index].slice(0,512);if(acceptedFlags.includes(token)){return nonBlank(tokens[index+1])?.slice(0,256)}const prefix=acceptedFlags.find(flag=>token.startsWith(`${flag}=`));if(prefix){return nonBlank(token.slice(prefix.length+1))?.slice(0,256)}}return void 0}const AGENT_ROLE_VALUES=new Set(["implementation","implementer","investigator","orchestrator","planner","release-operator","reviewer"]);function normalizeProvenanceValue(dimension,value){if(dimension!=="role"||value===void 0)return value;const normalized=value.trim().toLowerCase().replaceAll(/[_\s]+/gu,"-");return AGENT_ROLE_VALUES.has(normalized)?normalized:void 0}function boundedProvenanceValue(provenance,dimension){return nonBlank(provenance?.[dimension])?.slice(0,256)}const MAX_PROVENANCE_PROBE_BYTES=1048576;const MAX_CODEX_PROVENANCE_PROBE_BYTES=4194304;const codexProvenanceSnapshotCache=new Map;const EMPTY_CODEX_PROVENANCE_SNAPSHOT=Object.freeze({});const claudeProvenanceSnapshotCache=new Map;const EMPTY_CLAUDE_PROVENANCE_SNAPSHOT=Object.freeze({});function asProvenanceRecord(value){return typeof value==="object"&&value!==null&&!Array.isArray(value)?value:void 0}function parseClaudeProvenanceLine(line){let parsed;try{parsed=JSON.parse(line)}catch{return EMPTY_CLAUDE_PROVENANCE_SNAPSHOT}const record=asProvenanceRecord(parsed);if(!record)return EMPTY_CLAUDE_PROVENANCE_SNAPSHOT;const queue=[{value:record,depth:0}];let visited=0;let model;let version;while(queue.length>0&&visited<64){const current=queue.shift();visited+=1;model??=nonBlank(current.value.model)?.slice(0,256);version??=nonBlank(current.value.version)?.slice(0,256);if(model&&version)break;if(current.depth>=4)continue;for(const value of Object.values(current.value)){const nested=asProvenanceRecord(value);if(nested){queue.push({value:nested,depth:current.depth+1})}}}return Object.freeze({model,version})}function claudeTranscriptCandidateStatus(candidate){try{return fs.lstatSync(candidate).isFile()?"available":"missing"}catch(error){return isFileAbsentError(error)?"missing":"failed"}}function discoverClaudeSessionFile(projectsRoot,session){let discovered;try{discovered=fs.readdirSync(projectsRoot,{withFileTypes:true}).filter(entry=>entry.isDirectory()).sort((left,right)=>left.name.localeCompare(right.name)).slice(0,512).map(entry=>{const candidate=path.join(projectsRoot,entry.name,`${session}.jsonl`);return{candidate,status:claudeTranscriptCandidateStatus(candidate)}})}catch(error){return{status:isFileAbsentError(error)?"missing":"failed"}}const matches=discovered.filter(({status})=>status==="available").map(({candidate})=>candidate);if(matches.length===0){return{status:discovered.some(({status})=>status==="failed")?"failed":"missing"}}if(matches.length>1)return{status:"ambiguous"};return{status:"available",path:matches[0]}}function resolveClaudeSessionFile(signals,env){const session=nonBlank(env.CLAUDE_CODE_SESSION_ID);if(!session||!/^[A-Za-z0-9_-]{1,128}$/u.test(session)){return{status:"unavailable"}}const workspace=path.resolve(signals.cwd??process.cwd());const encodedWorkspace=workspace.replaceAll(/[^A-Za-z0-9-]/gu,"-");const projectsRoot=path.join(signals.home_dir??os.homedir(),".claude","projects");const directPath=path.join(projectsRoot,encodedWorkspace,`${session}.jsonl`);const explicitPath=nonBlank(signals.session_file);const suppliedPath=explicitPath&&path.basename(explicitPath)===`${session}.jsonl`?explicitPath:void 0;for(const candidate of[suppliedPath,directPath]){if(!candidate)continue;const status=claudeTranscriptCandidateStatus(candidate);if(status==="available")return{status,path:candidate};if(status==="failed")return{status}}return discoverClaudeSessionFile(projectsRoot,session)}function readClaudeSessionProvenance(dimension,signals,env){const resolution=resolveClaudeSessionFile(signals,env);if(resolution.status!=="available")return void 0;try{const file=fs.openSync(resolution.path,fs.constants.O_RDONLY|fs.constants.O_NOFOLLOW);try{const stats=fs.fstatSync(file);const cacheKey=`${resolution.path}\0${stats.size}\0${stats.mtimeMs}`;const cached=claudeProvenanceSnapshotCache.get(cacheKey);if(cached)return cached[dimension];const probeLength=Math.min(stats.size,MAX_PROVENANCE_PROBE_BYTES);const headLength=Math.min(probeLength,Math.ceil(probeLength/2));const tailLength=Math.min(probeLength-headLength,stats.size-headLength);const head=Buffer.alloc(headLength);fs.readSync(file,head,0,headLength,0);const tail=Buffer.alloc(tailLength);if(tailLength>0){fs.readSync(file,tail,0,tailLength,stats.size-tailLength)}const snapshot={};const lines=stats.size<=probeLength?Buffer.concat([head,tail]).toString("utf8").split("\n"):[...head.toString("utf8").split("\n").slice(0,4096),...tail.toString("utf8").split("\n").slice(-4096)];for(const line of lines){if(line.length===0||line.length>262144)continue;const parsed=parseClaudeProvenanceLine(line);snapshot.model??=parsed.model;snapshot.version??=parsed.version;if(snapshot.model&&snapshot.version)break}const frozen=Object.freeze(snapshot);claudeProvenanceSnapshotCache.clear();claudeProvenanceSnapshotCache.set(cacheKey,frozen);return frozen[dimension]}finally{fs.closeSync(file)}}catch{return void 0}}function findCodexSessionFile(root,session){let visited=0;const visit=(directory,depth)=>{if(depth>4||visited>=512)return void 0;let entries;try{entries=fs.readdirSync(directory,{withFileTypes:true}).sort((left,right)=>right.name.localeCompare(left.name))}catch{return void 0}for(const entry of entries){visited+=1;if(visited>512)return void 0;const entryPath=path.join(directory,entry.name);if(entry.isFile()&&entry.name.endsWith(`-${session}.jsonl`)){return entryPath}if(entry.isDirectory()){const found=visit(entryPath,depth+1);if(found)return found}}return void 0};return visit(root,0)}function codexProvenanceWindows(size){if(size<=MAX_CODEX_PROVENANCE_PROBE_BYTES){return[{offset:0,length:size}]}const halfBudget=Math.floor(MAX_CODEX_PROVENANCE_PROBE_BYTES/2);return[{offset:size-halfBudget,length:halfBudget},{offset:0,length:halfBudget}]}function mergeCodexTurnContext(snapshot,line){if(line.length===0||line.length>262144)return;let parsed;try{parsed=JSON.parse(line)}catch{return}if(typeof parsed!=="object"||parsed===null||Array.isArray(parsed)){return}const record=parsed;if(record.type!=="turn_context")return;const payload=typeof record.payload==="object"&&record.payload!==null?record.payload:void 0;snapshot.model??=nonBlank(payload?.model)?.slice(0,256);snapshot.effort??=nonBlank(payload?.effort)?.slice(0,256)}function readCodexProvenanceSnapshot(file,size){const snapshot={};let linesRemaining=4096;for(const window2 of codexProvenanceWindows(size)){const buffer=Buffer.alloc(window2.length);fs.readSync(file,buffer,0,window2.length,window2.offset);const lines=buffer.toString("utf8").split("\n").reverse().slice(0,linesRemaining);linesRemaining-=lines.length;for(const line of lines){mergeCodexTurnContext(snapshot,line);if(snapshot.model&&snapshot.effort)break}if(snapshot.model&&snapshot.effort||linesRemaining<=0)break}return snapshot}function readCodexSessionProvenance(dimension,signals,env){const session=nonBlank(env.CODEX_THREAD_ID);if(!session||!/^[A-Za-z0-9_-]{1,128}$/u.test(session))return void 0;const sessionsRoot=path.join(signals.home_dir??os.homedir(),".codex","sessions");const cacheKey=`${sessionsRoot}\0${session}`;const cached=codexProvenanceSnapshotCache.get(cacheKey);if(cached)return cached[dimension];const sessionPath=findCodexSessionFile(sessionsRoot,session);if(!sessionPath){codexProvenanceSnapshotCache.set(cacheKey,EMPTY_CODEX_PROVENANCE_SNAPSHOT);return void 0}try{const file=fs.openSync(sessionPath,"r");try{const size=fs.fstatSync(file).size;const snapshot=readCodexProvenanceSnapshot(file,size);codexProvenanceSnapshotCache.set(cacheKey,snapshot);return snapshot[dimension]}finally{fs.closeSync(file)}}catch{codexProvenanceSnapshotCache.set(cacheKey,EMPTY_CODEX_PROVENANCE_SNAPSHOT);return void 0}}function resolveProvenanceProbe(dimension,signals,env,descriptor){const workspaceSignals=workspaceHarnessSignalsStorage.getStore();const enabled=signals.probes_enabled!==false&&workspaceSignals?.probesEnabled!==false&&!["0","false","off"].includes(nonBlank(env.PM_AGENT_PROBES)?.toLowerCase()??"");if(!enabled)return void 0;const resolver=descriptor?.provenance_resolvers[dimension];if(resolver==="claude_session_file"){return readClaudeSessionProvenance(dimension,signals,env)}if(resolver==="codex_session_file"){return readCodexSessionProvenance(dimension,signals,env)}if(resolver==="ai_agent_version"){const value=nonBlank(env.AI_AGENT);if(!value||!descriptor||!literalSignalMatches(value,descriptor.harness)){return void 0}const match=/(?:^|[@/\s])v?(\d+\.\d+(?:\.\d+)?(?:[-+][A-Za-z0-9.-]+)?)$/u.exec(value);return match?.[1]?.slice(0,256)}return void 0}function provenanceResolverHasInput(resolver,descriptor,signals,env){if(resolver==="ai_agent_version"){const value=nonBlank(env.AI_AGENT);return value!==void 0&&literalSignalMatches(value,descriptor.harness)?"available":"unavailable"}if(resolver==="codex_session_file"){return nonBlank(env.CODEX_THREAD_ID)!==void 0?"available":"unavailable"}return resolveClaudeSessionFile(signals,env).status}function effectiveHarnessDetectionSignals(signals){if(signals)return signals;return harnessDetectionStorage.getStore()??{env:process.env,argv:process.argv}}function descriptorMatchesSignals(descriptor,env,labels,clientName){const environmentMatch=descriptor.environment_keys.some(key=>nonBlank(env[key])!==void 0);const argvMatch=descriptor.argv_markers.some(marker=>labels.some(label=>{const normalizedPath=label.replaceAll("\\","/");return literalSignalMatches(normalizedPath.slice(normalizedPath.lastIndexOf("/")+1),marker)}));const clientMatch=descriptor.client_names.some(name=>clientName===name||literalSignalMatches(clientName,name));return environmentMatch||argvMatch||clientMatch}function inferredProvenanceObservation(dimension,semanticAttribution){if(!semanticAttribution)return void 0;let value;if(dimension==="topic")value=semanticAttribution.topic;if(dimension==="role")value=semanticAttribution.role;if(!value)return void 0;return{value,source:"inferred",confidence:semanticAttribution.confidence,rule_version:semanticAttribution.rule_version,evidence:semanticAttribution.evidence}}function firstProvenanceObservation(candidates){const observed=candidates.find(([value])=>value!==void 0);return observed?.[0]?{value:observed[0],source:observed[1]}:void 0}function resolveAgentProvenanceObservation(dimension,signals,env,descriptor,sessionContext,semanticAttribution){const overrideKey=`PM_AGENT_${dimension.toUpperCase().replaceAll("-","_")}`;const hostResolvedDimensions=new Set([...AGENT_PROVENANCE_DIMENSIONS,...Object.keys(descriptor?.provenance_environment_keys??{})]);let overrideValue;let argvValue;let argvFlagValue;if(hostResolvedDimensions.has(dimension)){overrideValue=normalizeProvenanceValue(dimension,nonBlank(env[overrideKey])?.slice(0,256));argvFlagValue=normalizeProvenanceValue(dimension,provenanceFlagValue(signals.argv??[],dimension));argvValue=normalizeProvenanceValue(dimension,provenanceFromArgv(signals.argv??[],dimension))}const environmentKeysByDimension={...descriptor?.provenance_environment_keys,model:descriptor?.model_environment_keys};const clientProvenance={...signals.client_info?.provenance,model:signals.client_info?.model};const sessionValue=boundedProvenanceValue(sessionContext?.provenance,dimension);const environmentValue=normalizeProvenanceValue(dimension,firstEnvironmentValue(env,environmentKeysByDimension[dimension]));const clientValue=normalizeProvenanceValue(dimension,boundedProvenanceValue(clientProvenance,dimension));const hostValue=normalizeProvenanceValue(dimension,boundedProvenanceValue(signals.provenance,dimension));const probeValue=resolveProvenanceProbe(dimension,signals,env,descriptor);const observed=firstProvenanceObservation([[overrideValue,"override"],[sessionValue,"session"],[argvFlagValue,"argv"],[environmentValue,"environment"],[clientValue,"mcp_client"],[hostValue,"host"],[probeValue,"probe"]]);return observed??inferredProvenanceObservation(dimension,semanticAttribution)??(argvValue?{value:argvValue,source:"argv"}:void 0)}function resolveAgentInstance(harness,session){if(!harness||!session)return void 0;return createHash("sha256").update(`pm-agent-instance:v1\0${harness}\0${session}`).digest("hex").slice(0,24)}function resolveAgentProvenance(signals,env,descriptor,sessionContext,semanticAttribution){const descriptorDimensions=Object.keys(descriptor?.provenance_environment_keys??{});const dimensions=new Set([...AGENT_PROVENANCE_DIMENSIONS,...descriptorDimensions,...Object.keys(descriptor?.provenance_resolvers??{}),...Object.keys(signals.provenance??{}),...Object.keys(signals.client_info?.provenance??{}),...Object.keys(sessionContext?.provenance??{})]);const observations={};for(const dimension of dimensions){const observed=resolveAgentProvenanceObservation(dimension,signals,env,descriptor,sessionContext,semanticAttribution);if(observed){observations[dimension]=observed}else if(descriptor&&(dimension!=="version"||descriptor.provenance_unavailable_dimensions.includes(dimension))){observations[dimension]=null}}return observations}function registerHarnessSignalDescriptors(descriptors){const normalized=descriptors.map(normalizeHarnessSignalDescriptor);const builtins=new Map(NORMALIZED_BUILTIN_HARNESS_SIGNAL_DESCRIPTORS.map(descriptor=>[descriptor.harness,descriptor]));const seen=new Set;for(const descriptor of normalized){if(seen.has(descriptor.harness)||builtins.has(descriptor.harness)){throw new Error(`Harness signal descriptor collision for "${descriptor.harness}"`)}const registered=registeredHarnessSignalDescriptors.get(descriptor.harness);if(registered&&!descriptorEquals(registered.descriptor,descriptor)){throw new Error(`Harness signal descriptor collision for "${descriptor.harness}"`)}seen.add(descriptor.harness)}for(const descriptor of normalized){const registered=registeredHarnessSignalDescriptors.get(descriptor.harness);registeredHarnessSignalDescriptors.set(descriptor.harness,{descriptor,registrations:(registered?.registrations??0)+1})}let active=true;return()=>{if(!active)return;active=false;for(const descriptor of normalized){const registered=registeredHarnessSignalDescriptors.get(descriptor.harness);if(!registered||registered.registrations<=1){registeredHarnessSignalDescriptors.delete(descriptor.harness)}else{registered.registrations-=1}}}}function normalizeAgentProvenanceAdapter(adapter){const descriptor=normalizeHarnessSignalDescriptor(adapter.descriptor);const harness=adapter.harness.trim().toLowerCase();if(adapter.contract_version!==1){throw new Error(`Unsupported provenance adapter contract for "${harness}": ${adapter.contract_version}`)}if(descriptor.harness!==harness){throw new Error(`Provenance adapter harness "${harness}" does not match descriptor "${descriptor.harness}".`)}const adapterVersion=nonBlank(adapter.adapter_version)?.slice(0,64);if(!adapterVersion){throw new Error(`Provenance adapter "${harness}" requires a version.`)}if(!Number.isSafeInteger(adapter.priority)){throw new Error(`Provenance adapter "${harness}" requires an integer priority.`)}if(adapter.probe_policy.network_access!==false||adapter.probe_policy.subprocess_access!==false||adapter.probe_policy.max_bytes>MAX_CODEX_PROVENANCE_PROBE_BYTES||adapter.probe_policy.max_lines>4096){throw new Error(`Provenance adapter "${harness}" exceeds the bounded local probe policy.`)}return Object.freeze({...adapter,adapter_version:adapterVersion,harness,descriptor,supported_dimensions:Object.freeze(boundedUniqueStrings(adapter.supported_dimensions).map(dimension=>dimension.toLowerCase()).sort()),native_sources:Object.freeze([...new Set(adapter.native_sources)]),probe_policy:Object.freeze({...adapter.probe_policy}),normalization:Object.freeze({...adapter.normalization}),...adapter.waivers?{waivers:Object.freeze(Object.fromEntries(Object.entries(adapter.waivers).slice(0,32).map(([dimension,reason])=>[dimension.slice(0,64),reason.slice(0,256)])))}:{}})}function listAgentProvenanceAdapters(){const effective=new Map(BUILTIN_AGENT_PROVENANCE_ADAPTERS.map(adapter=>[adapter.harness,adapter]));for(const{adapter}of registeredAgentProvenanceAdapters.values()){effective.set(adapter.harness,adapter)}return Object.freeze([...effective.values()].sort((left,right)=>left.harness.localeCompare(right.harness)))}function registerAgentProvenanceAdapters(adapters){const normalized=adapters.map(normalizeAgentProvenanceAdapter);const builtins=new Map(BUILTIN_AGENT_PROVENANCE_ADAPTERS.map(adapter=>[adapter.harness,adapter]));const seen=new Set;for(const adapter of normalized){if(seen.has(adapter.harness)){throw new Error(`Provenance adapter collision for "${adapter.harness}".`)}const builtin=builtins.get(adapter.harness);if(builtin&&adapter.priority<=builtin.priority){throw new Error(`Provenance adapter override for "${adapter.harness}" requires priority greater than ${builtin.priority}.`)}const registered=registeredAgentProvenanceAdapters.get(adapter.harness);if(registered&&JSON.stringify(registered.adapter)!==JSON.stringify(adapter)){throw new Error(`Provenance adapter collision for "${adapter.harness}".`)}seen.add(adapter.harness)}for(const adapter of normalized){const registered=registeredAgentProvenanceAdapters.get(adapter.harness);registeredAgentProvenanceAdapters.set(adapter.harness,{adapter,registrations:(registered?.registrations??0)+1})}let active=true;return()=>{if(!active)return;active=false;for(const adapter of normalized){const registered=registeredAgentProvenanceAdapters.get(adapter.harness);if(!registered||registered.registrations<=1){registeredAgentProvenanceAdapters.delete(adapter.harness)}else{registered.registrations-=1}}}}function normalizeAgentProvenanceAdapterValue(dimension,value){const raw=value.trim().slice(0,256);let normalized=raw.toLowerCase();if(dimension==="model"){const family=/^(gpt-\d+(?:\.\d+)?)/u.exec(normalized)?.[1];if(family)normalized=family}else{normalized=normalized.replaceAll(/[_\s-]+/gu,"");const effortAliases={minimal:"low",low:"low",medium:"medium",high:"high",xhigh:"xhigh",max:"max",ultra:"ultra"};normalized=effortAliases[normalized]??normalized}return{raw,normalized,vocabulary:"v1"}}function runWithHarnessDetectionSignals(signals,callback){return harnessDetectionStorage.run(signals,callback)}function runWithWorkspaceHarnessSignalDescriptors(descriptors,callback,options={}){const normalized=descriptors.map(normalizeHarnessSignalDescriptor);currentHarnessSignalDescriptors(normalized);return workspaceHarnessSignalsStorage.run({descriptors:normalized,probesEnabled:options.probesEnabled!==false},callback)}function detectAgentIdentity(signals){const effectiveSignals=effectiveHarnessDetectionSignals(signals);const env=effectiveSignals.env??{};const descriptors=currentHarnessSignalDescriptors(effectiveSignals.descriptors);const labels=[...(effectiveSignals.argv??[]).slice(0,3),...effectiveSignals.process_labels??[]].slice(0,64).map(token=>token.slice(0,512));const clientName=effectiveSignals.client_info?.name.trim().toLowerCase()??"";const descriptor=descriptors.find(candidate=>descriptorMatchesSignals(candidate,env,labels,clientName));const sessionContext=resolveAgentSessionContextFromSignals(effectiveSignals,env);const session=[firstEnvironmentValue(env,descriptor?.session_environment_keys),nonBlank(effectiveSignals.client_info?.session)?.slice(0,256)].find(candidate=>candidate!==void 0);const instance=resolveAgentInstance(descriptor?.harness,session);const semanticAttribution=readAgentSemanticAttributionSync({cwd:effectiveSignals.cwd??process.cwd(),env,key:instance});const provenance=resolveAgentProvenance(effectiveSignals,env,descriptor,sessionContext,semanticAttribution);const modelCandidate=provenance.model;const entries=[["harness",descriptor?.harness],["model",modelCandidate?.value],["model_source",modelCandidate?.source],["session",session],["instance",instance],["provenance",Object.keys(provenance).length>0?provenance:void 0],["episode",sessionContext.episode]];return Object.fromEntries(entries.filter(entry=>entry[1]!==void 0))}function provenanceResolverAbsence(resolverInput){if(resolverInput==="unavailable"){return{status:"unavailable",reason:"harness_unavailable"}}if(resolverInput==="missing"){return{status:"unavailable",reason:"resolver_input_missing"}}return{status:"failed",reason:"resolver_failed"}}function resolveProvenanceOutcome(dimension,identity,descriptor,signals,env,probesEnabled,invalidValue){const resolver=descriptor?.provenance_resolvers[dimension];if(identity.provenance?.[dimension]){return{status:"resolved",...resolver?{resolver}:{},rule_version:"v1"}}if(invalidValue){return{status:"unavailable",reason:"invalid_value",rule_version:"v1"}}if(resolver){if(!probesEnabled){return{status:"unavailable",reason:"probes_disabled",resolver,rule_version:"v1"}}const resolverInput=provenanceResolverHasInput(resolver,descriptor,signals,env);return{...provenanceResolverAbsence(resolverInput),resolver,rule_version:"v1"}}return{status:descriptor?.provenance_unavailable_dimensions.includes(dimension)?"unavailable":"not_configured",reason:descriptor?.provenance_unavailable_dimensions.includes(dimension)?"harness_unavailable":"resolver_not_configured",rule_version:"v1"}}function diagnoseAgentIdentity(signals){const effectiveSignals=effectiveHarnessDetectionSignals(signals);const identity=detectAgentIdentity(effectiveSignals);const descriptor=currentHarnessSignalDescriptors(effectiveSignals.descriptors).find(candidate=>candidate.harness===identity.harness);const env=effectiveSignals.env??{};const probesEnabled=effectiveSignals.probes_enabled!==false&&workspaceHarnessSignalsStorage.getStore()?.probesEnabled!==false&&!["0","false","off"].includes(nonBlank(env.PM_AGENT_PROBES)?.toLowerCase()??"");const sessionContext=resolveAgentSessionContextFromSignals(effectiveSignals,env);const invalidRoleValue=[env.PM_AGENT_ROLE,sessionContext.provenance?.role,firstEnvironmentValue(env,descriptor?.provenance_environment_keys.role),effectiveSignals.client_info?.provenance?.role,effectiveSignals.provenance?.role,provenanceFlagValue(effectiveSignals.argv??[],"role")].some(candidate=>{const value=nonBlank(candidate)?.slice(0,256);return value!==void 0&&normalizeProvenanceValue("role",value)===void 0});const outcomes=Object.fromEntries(AGENT_PROVENANCE_DIMENSIONS.map(dimension=>[dimension,resolveProvenanceOutcome(dimension,identity,descriptor,effectiveSignals,env,probesEnabled,dimension==="role"&&invalidRoleValue)]));return{...identity,provenance_outcomes:outcomes}}function readAuthorEnvironment(){return process.env.PM_AUTHOR}function writeAuthorEnvironment(author){if(author===void 0)delete process.env.PM_AUTHOR;else process.env.PM_AUTHOR=author}function detectHarnessIdentity(signals){return detectAgentIdentity(signals).harness}function resolveAuthorIdentity(candidate,fallback,signals){const effectiveSignals=effectiveHarnessDetectionSignals(signals);const detected=detectAgentIdentity(effectiveSignals);if(candidate!==void 0){const explicit=nonBlank(candidate);return explicit?{author:explicit,source:"asserted",...detected}:{author:"unknown",source:"unknown",...detected}}if(effectiveSignals.env?.PM_AUTHOR!==void 0){const environment=nonBlank(effectiveSignals.env.PM_AUTHOR);return environment?{author:environment,source:"asserted",...detected}:{author:"unknown",source:"unknown",...detected}}const configured=nonBlank(fallback);if(configured){return{author:configured,source:"configured",...detected}}if(detected.harness){return{author:`harness:${detected.harness}`,source:"detected",...detected}}return{author:"unknown",source:"unknown",...detected}}function resolveHistoryAuthorSource(author){const active=authorIdentityStorage.getStore();if(active?.author===author){return active.source}if(author.startsWith("harness:")){return"detected"}return author==="unknown"?"unknown":"asserted"}function resolveHistoryAgentIdentity(author){const active=authorIdentityStorage.getStore();if(active?.author!==author){return author.startsWith("harness:")?{harness:author.slice("harness:".length)}:{}}return{...active.harness?{harness:active.harness}:{},...active.model?{model:active.model}:{},...active.model_source?{model_source:active.model_source}:{},...active.session?{session:active.session}:{},...active.instance?{instance:active.instance}:{},...active.provenance?{provenance:active.provenance}:{},...active.episode?{episode:active.episode}:{}}}function resolveClaimPrincipal(author){const active=authorIdentityStorage.getStore();return active?.author===author&&active.source==="detected"&&active.instance?`${author}#${active.instance}`:author}function resolveAuthor(candidate,fallback){const identity=resolveAuthorIdentity(candidate,fallback);authorIdentityStorage.enterWith(identity);return identity.author}export{AGENT_PROVENANCE_DIMENSIONS,BUILTIN_AGENT_PROVENANCE_ADAPTERS,BUILTIN_HARNESS_SIGNAL_DESCRIPTORS,detectAgentIdentity,detectHarnessIdentity,diagnoseAgentIdentity,listAgentProvenanceAdapters,normalizeAgentProvenanceAdapterValue,readAuthorEnvironment,registerAgentProvenanceAdapters,registerHarnessSignalDescriptors,resolveAuthor,resolveAuthorIdentity,resolveClaimPrincipal,resolveHistoryAgentIdentity,resolveHistoryAuthorSource,runWithHarnessDetectionSignals,runWithWorkspaceHarnessSignalDescriptors,writeAuthorEnvironment};
|
|
1172
2
|
//# sourceMappingURL=author.js.map
|
|
1173
|
-
//# debugId=dfbf4eb8-1f02-5880-a70a-0e7ed9b9784a
|