@unbrained/pm-cli 2026.9.2 → 2026.9.4
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/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +44 -0
- package/dist/cli/after-command-context-usage.js +16 -3
- package/dist/cli-bundle/bundle-manifest.json +151 -151
- package/dist/cli-bundle/chunks/chunk-6XSKPNCF.js +230 -0
- package/dist/cli-bundle/chunks/chunk-A24WAVE6.js +8 -0
- package/dist/cli-bundle/chunks/{chunk-TAG4VC22.js → chunk-HI6BHPCU.js} +27 -27
- package/dist/cli-bundle/chunks/{chunk-Y7VOMSZT.js → chunk-I2AS367G.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-X4RCGLTX.js → chunk-OGBVU67G.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-DTGWEL23.js → chunk-RI4XNOYS.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-TXW6VL33.js +38 -0
- package/dist/cli-bundle/chunks/{chunk-FZ4Z2J4F.js → chunk-V72UV7QS.js} +76 -79
- package/dist/cli-bundle/chunks/chunk-VGLHECAP.js +9 -0
- package/dist/cli-bundle/chunks/{chunk-T6H5BZCP.js → chunk-X6CMGV6L.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-3WICXLVT.js → chunk-YW4QK2G7.js} +2 -2
- package/dist/cli-bundle/chunks/{register-list-query-XYNX4ASQ.js → register-list-query-Z5YYSJJG.js} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-WFQ7MJTX.js → register-mutation-ELSP6I4I.js} +2 -2
- package/dist/cli-bundle/chunks/{register-operations-JVTI7JPP.js → register-operations-OH7R3ZT4.js} +2 -2
- package/dist/cli-bundle/chunks/{register-setup-KVNC5KPL.js → register-setup-E2AE72QG.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-MEASX544.js → chunk-25UJBH4M.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-SVXJYD6G.js → chunk-3646BZ4W.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-4YRAVI43.js +12 -0
- package/dist/cli-bundle/focused-chunks/chunk-53IHPICX.js +3 -0
- package/dist/cli-bundle/focused-chunks/chunk-5P4HVOWG.js +176 -0
- package/dist/cli-bundle/focused-chunks/chunk-636VVQ7F.js +54 -0
- package/dist/cli-bundle/focused-chunks/{chunk-4O4CJAR6.js → chunk-6PWPQKDN.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-7N2TV7WZ.js +8 -0
- package/dist/cli-bundle/focused-chunks/chunk-AJR3OP2E.js +3 -0
- package/dist/cli-bundle/focused-chunks/chunk-B3A6MJYE.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-BFDDJ2T2.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-BHUIRZWQ.js +9 -0
- package/dist/cli-bundle/focused-chunks/chunk-JADHHPY6.js +6 -0
- package/dist/cli-bundle/focused-chunks/{chunk-KB5OFSFD.js → chunk-MHKUIPJW.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-NBMJD6MK.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-NSKBLHVI.js +20 -0
- package/dist/cli-bundle/focused-chunks/{chunk-BEVHCEWG.js → chunk-P2GOAOQN.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-YARWJM2B.js +2 -0
- package/dist/cli-bundle/main.js +15 -15
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +1 -1
- package/dist/cli-bundle/sdk-core.js +28 -31
- 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 +43 -36
- 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 +10 -10
- package/dist/core/diagnostics/remediation.js +4 -4
- package/dist/core/history/event-classification.d.ts +21 -0
- package/dist/core/history/event-classification.js +109 -0
- package/dist/core/history/event-index.d.ts +14 -3
- package/dist/core/history/event-index.js +543 -88
- package/dist/core/history/history.d.ts +37 -1
- package/dist/core/history/history.js +320 -71
- package/dist/core/history/replay.js +68 -34
- package/dist/core/history/workspace-history.js +7 -6
- package/dist/core/lock/lock.d.ts +32 -2
- package/dist/core/lock/lock.js +161 -20
- package/dist/core/output/output.js +31 -7
- package/dist/core/shared/author.d.ts +3 -1
- package/dist/core/shared/author.js +111 -23
- package/dist/core/shared/time.d.ts +2 -0
- package/dist/core/shared/time.js +8 -2
- package/dist/core/store/item-metadata-query-index.js +5 -5
- package/dist/sdk/context/recency.d.ts +9 -0
- package/dist/sdk/context/recency.js +34 -0
- package/dist/sdk/context/usage-egress.d.ts +9 -0
- package/dist/sdk/context/usage-egress.js +30 -0
- package/dist/sdk/context-intent-contracts.js +7 -3
- package/dist/sdk/context-relevance.d.ts +23 -0
- package/dist/sdk/context-relevance.js +94 -23
- package/dist/sdk/context-signal-store.d.ts +7 -3
- package/dist/sdk/context-signal-store.js +155 -42
- package/dist/sdk/context-usage.d.ts +54 -0
- package/dist/sdk/context-usage.js +245 -16
- package/dist/sdk/environment/agent-environment.d.ts +296 -0
- package/dist/sdk/environment/agent-environment.js +467 -0
- package/dist/sdk/environment/project-runtime-compatibility.d.ts +19 -1
- package/dist/sdk/environment/project-runtime-compatibility.js +118 -21
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +14 -2
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +14 -2
- package/dist/sdk/governance/health.js +13 -44
- package/dist/sdk/governance/merge-receipt-history.d.ts +62 -0
- package/dist/sdk/governance/merge-receipt-history.js +207 -0
- package/dist/sdk/governance/provenance-health.js +9 -3
- package/dist/sdk/history-compact.js +14 -5
- package/dist/sdk/history-redact.js +58 -23
- package/dist/sdk/history-repair.js +16 -6
- package/dist/sdk/index.d.ts +4 -0
- package/dist/sdk/index.js +6 -2
- package/dist/sdk/init.d.ts +2 -0
- package/dist/sdk/init.js +18 -9
- package/dist/sdk/merge/driver.d.ts +3 -1
- package/dist/sdk/merge/driver.js +9 -9
- package/dist/sdk/merge/index.d.ts +1 -1
- package/dist/sdk/merge/index.js +3 -3
- package/dist/sdk/merge/receipts.d.ts +17 -6
- package/dist/sdk/merge/receipts.js +246 -75
- package/dist/sdk/merge/reconcile.d.ts +9 -7
- package/dist/sdk/merge/reconcile.js +175 -12
- package/dist/sdk/merge/three-way.d.ts +22 -2
- package/dist/sdk/merge/three-way.js +92 -25
- package/dist/sdk/query/context.d.ts +3 -1
- package/dist/sdk/query/context.js +21 -9
- package/dist/sdk/query/next.js +18 -9
- package/dist/sdk/runtime-input.d.ts +2 -0
- package/dist/sdk/runtime-input.js +25 -2
- package/dist/sdk/runtime-primitives.d.ts +2 -2
- package/dist/sdk/runtime-primitives.js +4 -4
- package/dist/sdk/runtime.d.ts +1 -0
- package/dist/sdk/runtime.js +17 -26
- package/dist/types.d.ts +27 -0
- package/dist/types.js +2 -2
- package/docs/AGENT_ENVIRONMENTS.md +47 -0
- package/docs/AGENT_PROVENANCE_ADR.md +17 -2
- package/docs/CONTEXT_INTEGRITY_CONTRACTS.md +38 -1
- package/docs/CONTEXT_RELEVANCE.md +44 -1
- package/docs/MERGE_SAFETY.md +119 -23
- package/docs/PERFORMANCE.md +6 -3
- package/docs/README.md +1 -0
- package/docs/READ_OUTPUT_CONTRACTS.md +9 -1
- package/docs/SDK.md +11 -8
- package/docs/SDK_CONTEXT.md +7 -0
- package/docs/SDK_CONTEXT_EVIDENCE_CONTRACTS.md +24 -2
- package/docs/SDK_RUNTIME_BOUNDARIES.md +17 -1
- package/docs/examples/sdk-agent-environment/README.md +14 -0
- package/docs/examples/sdk-agent-environment/package.json +8 -0
- package/docs/examples/sdk-agent-environment/run-agent-environment.mjs +154 -0
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +5 -3
- package/marketplace.json +2 -2
- package/package.json +5 -5
- 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/sdk/public-surface.json +773 -46
- package/dist/cli-bundle/chunks/chunk-GOACULJW.js +0 -13
- package/dist/cli-bundle/chunks/chunk-NOPL37X4.js +0 -205
- package/dist/cli-bundle/chunks/chunk-UDW64J2W.js +0 -8
- package/dist/cli-bundle/chunks/chunk-ZLJIFSOE.js +0 -35
- package/dist/cli-bundle/focused-chunks/chunk-242AXYB2.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-2FEZ5SKM.js +0 -3
- package/dist/cli-bundle/focused-chunks/chunk-6GCRSLPG.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-7VATS5QY.js +0 -16
- package/dist/cli-bundle/focused-chunks/chunk-JEFKLWMM.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-MKHG3T76.js +0 -20
- package/dist/cli-bundle/focused-chunks/chunk-O67VDLOT.js +0 -51
- package/dist/cli-bundle/focused-chunks/chunk-PF3E6Q36.js +0 -8
- package/dist/cli-bundle/focused-chunks/chunk-QDFJIRKN.js +0 -4
- package/dist/cli-bundle/focused-chunks/chunk-RMRCQPWU.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-S4U5CN5Q.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-T2LXXSOD.js +0 -158
- package/dist/cli-bundle/focused-chunks/chunk-Z2USIBR2.js +0 -5
package/docs/MERGE_SAFETY.md
CHANGED
|
@@ -5,7 +5,19 @@ Tracked by [pm-wc1r](../.agents/pm/features/pm-wc1r.toon), with the integrity an
|
|
|
5
5
|
Lossless receipt health gating is tracked by
|
|
6
6
|
[pm-baksix](../.agents/pm/issues/pm-baksix.toon), and executable remediation
|
|
7
7
|
that performs settlement is tracked by
|
|
8
|
-
[pm-r0p3at](../.agents/pm/issues/pm-r0p3at.toon).
|
|
8
|
+
[pm-r0p3at](../.agents/pm/issues/pm-r0p3at.toon). Immutable record sealing and
|
|
9
|
+
retained re-anchor evidence are tracked by
|
|
10
|
+
[pm-javbsq](../.agents/pm/issues/pm-javbsq.toon) and
|
|
11
|
+
[pm-aka8m7](../.agents/pm/issues/pm-aka8m7.toon); preferred-era receipt-summary
|
|
12
|
+
compatibility is tracked by
|
|
13
|
+
[pm-wn3ee5](../.agents/pm/issues/pm-wn3ee5.toon).
|
|
14
|
+
Lossless concurrent acceptance-criteria composition is tracked by
|
|
15
|
+
[pm-inn5y5](../.agents/pm/issues/pm-inn5y5.toon).
|
|
16
|
+
Recency-aware scalar convergence, bounded fresh-clone decision evidence, and
|
|
17
|
+
audited pre-durable receipt dispositions are tracked by
|
|
18
|
+
[pm-7wzb6d](../.agents/pm/issues/pm-7wzb6d.toon),
|
|
19
|
+
[pm-mg13iz](../.agents/pm/issues/pm-mg13iz.toon), and
|
|
20
|
+
[pm-cf4t42](../.agents/pm/issues/pm-cf4t42.toon).
|
|
9
21
|
|
|
10
22
|
pm stores project context as reviewable repository files. Concurrent agents can therefore use ordinary branches and worktrees, but tracker artifacts need semantic merge behavior: raw line merging cannot preserve TOON collection counts, JSON object structure, or append-only history hash chains.
|
|
11
23
|
|
|
@@ -59,12 +71,12 @@ pm merge install --dry-run --json
|
|
|
59
71
|
|
|
60
72
|
## Artifact semantics
|
|
61
73
|
|
|
62
|
-
| Artifact | Driver | Merge behavior
|
|
63
|
-
| ---------------------------------------------------------------- | ----------------------------------- |
|
|
64
|
-
| Item `.toon` / `.md` | `pm-item-toon` / `pm-item-markdown` | Three-way field merge; append-like collections use set union, `updated_at` uses latest timestamp, scalar conflicts select
|
|
65
|
-
| `history/*.jsonl` | `pm-history` | Preserves the common prefix and both divergent suffixes, orders deterministically, then re-anchors the resulting hash chain.
|
|
66
|
-
| tracker `**/*.jsonl` except the later `history/*.jsonl` override | `pm-relationship` | Covers default and package-owned custom relationship event paths, unions divergent suffixes by `eventId` (timestamp-ordered, ours-first on ties), and renumbers `sequence` consecutively so the strict-sequence store loader accepts the merged stream.
|
|
67
|
-
| root `settings.json` and nested `**/*.json` | `pm-json` | Recursively merges objects per key. Arrays compose when both branches preserve the base and add distinct entries, so independent extension installs and evaluation additions merge without weakening edit/removal conflict detection.
|
|
74
|
+
| Artifact | Driver | Merge behavior |
|
|
75
|
+
| ---------------------------------------------------------------- | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
76
|
+
| Item `.toon` / `.md` | `pm-item-toon` / `pm-item-markdown` | Three-way field merge; append-like collections use set union, `updated_at` uses the latest timestamp, scalar conflicts select the value from the later document update with stable value order as an equal-timestamp tie-break, and canonical serialization recomputes TOON counts. |
|
|
77
|
+
| `history/*.jsonl` | `pm-history` | Preserves the common prefix and both divergent suffixes, orders deterministically, then re-anchors the resulting hash chain. |
|
|
78
|
+
| tracker `**/*.jsonl` except the later `history/*.jsonl` override | `pm-relationship` | Covers default and package-owned custom relationship event paths, unions divergent suffixes by `eventId` (timestamp-ordered, ours-first on ties), and renumbers `sequence` consecutively so the strict-sequence store loader accepts the merged stream. |
|
|
79
|
+
| root `settings.json` and nested `**/*.json` | `pm-json` | Recursively merges objects per key. Arrays compose when both branches preserve the base and add distinct entries, so independent extension installs and evaluation additions merge without weakening edit/removal conflict detection. |
|
|
68
80
|
|
|
69
81
|
The `tests` collection has an additional execution-safety rule. Its semantic
|
|
70
82
|
identity excludes provenance so the same command/context does not duplicate
|
|
@@ -80,17 +92,50 @@ boundary for append-like data that becomes executable after a merge; ordinary
|
|
|
80
92
|
notes, files, and other non-executable collections retain normal set-union
|
|
81
93
|
behavior.
|
|
82
94
|
|
|
83
|
-
|
|
95
|
+
Although `acceptance_criteria` is serialized as a semicolon-delimited scalar
|
|
96
|
+
for backward compatibility, the item driver treats its parsed criteria as a
|
|
97
|
+
collection. Independent additions compose in branch order, removals made by
|
|
98
|
+
either side remain removed, the field is reported in `union_fields`, and a
|
|
99
|
+
lossless merge does not create a scalar conflict decision. This gives repeated
|
|
100
|
+
`pm update --add-ac` mutations the same multi-branch preservation guarantee as
|
|
101
|
+
native append-like metadata without a storage migration.
|
|
102
|
+
|
|
103
|
+
When both sides change the same item scalar differently, the driver retains the
|
|
104
|
+
value from the document with the later `metadata.updated_at` timestamp. Equal
|
|
105
|
+
timestamps fall back to stable value ordering, so reversing Git's ours/theirs
|
|
106
|
+
labels still converges to the same result. Item results, driver results, and
|
|
107
|
+
receipts expose `conflict_resolution: latest_document_update` and
|
|
108
|
+
`requested_preference_applied: false`; each conflict decision adds
|
|
109
|
+
`retained_side` and `resolution_basis` so review automation can distinguish a
|
|
110
|
+
recency decision from the stable tie-break. The caller's
|
|
111
|
+
`requested_preference` remains observable but does not override item scalar
|
|
112
|
+
convergence. Readers continue to accept legacy `preferred_side` and
|
|
113
|
+
`stable_value_order` receipts and normalize the legacy `preferred` key. JSON
|
|
114
|
+
leaf conflicts retain their explicit preferred-side policy. Git keeps the item
|
|
115
|
+
path conflicted so a human or coordinating agent must review the discarded
|
|
116
|
+
value and explicitly `git add` the resolution.
|
|
117
|
+
|
|
118
|
+
The exact object `{ "pm_item_scalar_missing": true }` is reserved for
|
|
119
|
+
JSON-stable missing-value evidence. Item merge inputs reject that object as a
|
|
120
|
+
present metadata value, while the hashing primitive independently separates
|
|
121
|
+
present and missing domains. This prevents extension data from impersonating a
|
|
122
|
+
deletion without wrapping every ordinary scalar in receipt output.
|
|
84
123
|
|
|
85
124
|
The driver result's `guidance` always points unresolved conflicts to `pm merge report`. When a clone-local receipt exists, guidance includes its privacy-safe receipt and item ids for exact correlation; discarded values remain confined to the local receipt and never appear in generic logs or tracker history. Tracked by [pm-fbrz7p](../.agents/pm/issues/pm-fbrz7p.toon).
|
|
86
125
|
|
|
87
126
|
For item conflicts, the driver writes a clone-local receipt below the Git
|
|
88
127
|
directory and a durable privacy-safe sidecar below `merge-receipts/` in the
|
|
89
128
|
tracker. The local receipt contains retained and discarded values so recovery
|
|
90
|
-
does not depend on a reflog. The tracked sidecar
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
129
|
+
does not depend on a reflog. The tracked sidecar applies the versioned
|
|
130
|
+
`bounded_non_sensitive_scalars_v1` policy. Built-in lifecycle statuses,
|
|
131
|
+
priority integers from 0 through 4, bounded risk/confidence/severity ordinals,
|
|
132
|
+
and `null` are stored with both their value and matching hash. All other values
|
|
133
|
+
remain hash-only. `value_availability` distinguishes `bounded_inline`, `mixed`,
|
|
134
|
+
and `hash_only`, while the clone-local receipt remains `clone_local`. This lets
|
|
135
|
+
a fresh-clone reviewer recover ordinary control-plane decisions without
|
|
136
|
+
publishing titles, descriptions, custom statuses, or other potentially private
|
|
137
|
+
content. When both copies exist the SDK deduplicates them and prefers the
|
|
138
|
+
locally recoverable copy:
|
|
94
139
|
|
|
95
140
|
```bash
|
|
96
141
|
pm merge report
|
|
@@ -108,7 +153,9 @@ that distinction without returning malformed contents.
|
|
|
108
153
|
loss-aware contract through `complete`, `invalid_evidence_count`, bounded
|
|
109
154
|
`invalid_evidence[]`, `invalid_evidence_truncated`, and
|
|
110
155
|
`clone_local_evidence_resolved`. Each rejected candidate reports a stable
|
|
111
|
-
reason plus its `clone_local`, `durable`, or copy-consistency source.
|
|
156
|
+
reason plus its `clone_local`, `durable`, or copy-consistency source. Schema and
|
|
157
|
+
identity failures additionally expose a bounded `validation_error` such as
|
|
158
|
+
`required_fields`, `item_path`, `filename`, or `durable_decisions`. A safe
|
|
112
159
|
receipt filename is returned as `receipt_id`; unsafe candidate names are
|
|
113
160
|
represented only by `candidate_name_hash`, and malformed contents are never
|
|
114
161
|
returned. The detail list is capped at 100 rows while the count remains exact,
|
|
@@ -118,13 +165,26 @@ POSIX instead of treating platform-specific `ENOENT`/`ENOTDIR` spellings as
|
|
|
118
165
|
equivalent. Full health also cross-checks the privacy-safe receipt summaries in
|
|
119
166
|
append-only history against valid pending and reconciled evidence. Missing
|
|
120
167
|
evidence emits `merge_receipt_history_reference_missing:<n>` with bounded item,
|
|
121
|
-
history-line, and receipt-id-or-hash coordinates.
|
|
122
|
-
|
|
123
|
-
|
|
168
|
+
history-line, and receipt-id-or-hash coordinates. Recover an available receipt
|
|
169
|
+
from an authoritative clone or backup first. For an exact reference whose
|
|
170
|
+
history-event timestamp predates tracked durable receipts, `pm merge reconcile
|
|
171
|
+
--force` can append a `merge_reconcile` audit event containing the original
|
|
172
|
+
item, line, receipt id, timestamp, and the closed
|
|
173
|
+
`legacy_clone_local_only` reason. Health accepts only that exact coordinate and
|
|
174
|
+
reports it through `accepted_missing_merge_receipt_dispositions`; it never
|
|
175
|
+
rewrites or deletes the original history. The audit event must also occur after
|
|
176
|
+
the referenced history line; an earlier event cannot pre-authorize a later
|
|
177
|
+
missing receipt. Missing post-durable evidence remains blocking and cannot be
|
|
178
|
+
dispositioned through this compatibility path. The CLI
|
|
124
179
|
exits nonzero when evidence is incomplete, even when the valid-receipt count is
|
|
125
180
|
zero. Current SDK implementations always emit the new field, while its optional
|
|
126
181
|
type preserves structural compatibility for existing typed adapters and test
|
|
127
|
-
fixtures.
|
|
182
|
+
fixtures. A structurally valid preferred-era history summary that contains its
|
|
183
|
+
complete privacy-safe receipt evidence is accepted in place: health counts it
|
|
184
|
+
as `accepted_legacy_merge_receipt_references` and does not demand an external
|
|
185
|
+
receipt file that the older writer never created. Incomplete, contradictory, or
|
|
186
|
+
modern summaries still fail closed. `runMergeReceiptReport` remains the
|
|
187
|
+
compatible valid-only report.
|
|
128
188
|
|
|
129
189
|
## Cross-branch id collision safety
|
|
130
190
|
|
|
@@ -165,7 +225,8 @@ Serialized source claims are ignored. Receipt readers validate the complete
|
|
|
165
225
|
bounded schema, safe identifiers, filename and item-path identity, timestamps,
|
|
166
226
|
and bounded decision structure before a sidecar enters health or
|
|
167
227
|
reconciliation. Reads use size-preflighted, no-follow regular-file descriptors;
|
|
168
|
-
durable
|
|
228
|
+
durable decision values must conform to the declared bounded-inline policy or
|
|
229
|
+
remain hash-only. Qualifying durable-only receipts
|
|
169
230
|
are reloaded from the authoritative store and accepted only after exact canonical
|
|
170
231
|
item path, declared-field, and merged-value hash verification. Legacy receipts,
|
|
171
232
|
receipts whose declared fields disagree with their hashes, same-item tampering,
|
|
@@ -173,16 +234,19 @@ and drift on unrelated items fail closed to the normal `pm history-repair`
|
|
|
173
234
|
guidance. Health indexes authoritative evidence once by item and reconciliation
|
|
174
235
|
uses the same per-item groups with a fixed receipt-only worker pool, so committed
|
|
175
236
|
sidecars cannot amplify drift scans into unbounded parallel repair work.
|
|
176
|
-
The machine-executable remediation
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
237
|
+
The machine-executable remediation for a missing receipt reference names
|
|
238
|
+
`pm merge reconcile --dry-run`. It never publishes `--force` as an executable
|
|
239
|
+
hint: the human-readable summary explains that exact eligible pre-durable
|
|
240
|
+
coordinates may be dispositioned by a separately reviewed force pass. Ordinary
|
|
241
|
+
pending lossless receipts retain their unforced apply remediation.
|
|
181
242
|
Apply-mode reconciliation repeats the same proof against the exact
|
|
182
243
|
item snapshot used by the audited history rewrite. The audit event and
|
|
183
244
|
settlement include only the individually proven receipt id, so one valid receipt
|
|
184
245
|
cannot authorize an untrusted same-item sibling. Failed or unproven receipts
|
|
185
246
|
remain pending unless the coordinator explicitly reviews and supplies `--force`.
|
|
247
|
+
Snapshot verification accepts both the current presence-domain digest and the
|
|
248
|
+
legacy version-1 scalar digest, so already-written receipts remain repairable;
|
|
249
|
+
new receipts always use the collision-free presence-domain scheme.
|
|
186
250
|
Receipts with discarded scalar values retain the distinct
|
|
187
251
|
`merge_decisions_unreviewed:<n>` finding. Matching authoritative hash proof
|
|
188
252
|
allows those receipts to settle without `--force`; without qualifying proof,
|
|
@@ -192,6 +256,15 @@ an unforced apply command that clears `merge_decisions_unreviewed` when the
|
|
|
192
256
|
receipt proves the exact current merged values. This prevents routine repair
|
|
193
257
|
from hiding unfinished reconciliation while avoiding redundant force for an
|
|
194
258
|
already-proven canonical snapshot.
|
|
259
|
+
The same `--force` boundary also handles an unrecoverable pre-durable
|
|
260
|
+
clone-local-only history reference. Preview and apply results expose
|
|
261
|
+
`missing_history_references_before`, `legacy_disposition_eligible`,
|
|
262
|
+
`legacy_disposition_recorded`, and `missing_history_references_after`. When
|
|
263
|
+
coordinates exceed the bounded health response, explicit result guidance
|
|
264
|
+
requires repeated dry-run and reviewed force passes until health no longer
|
|
265
|
+
reports truncated coordinate details and the remaining count is zero. An apply
|
|
266
|
+
result cannot return `ok: true` while any missing reference or truncated
|
|
267
|
+
evidence remains.
|
|
195
268
|
It exits nonzero while either merge-critical validation check is non-green, so
|
|
196
269
|
CI and explicit post-merge hooks cannot approve unresolved receipts or drift.
|
|
197
270
|
The apply pass uses the audited history rewrite boundary to append a
|
|
@@ -233,6 +306,29 @@ keeps version incompatibility distinct from item corruption and is tracked by
|
|
|
233
306
|
[pm-2htk4p](../.agents/pm/issues/pm-2htk4p.toon) and
|
|
234
307
|
[pm-2qahia](../.agents/pm/issues/pm-2qahia.toon).
|
|
235
308
|
|
|
309
|
+
New history events also carry `record_hash_version` and `record_hash`. Unlike
|
|
310
|
+
the item anchors, the record hash covers the complete immutable event: author
|
|
311
|
+
and agent provenance, timestamp, operation, message, context, patch, item-hash
|
|
312
|
+
epoch, and before/after anchors. A record that carries only one envelope field,
|
|
313
|
+
uses an unsupported record epoch, or changes after sealing fails verification.
|
|
314
|
+
Entries created before this envelope remain readable as explicit
|
|
315
|
+
`item_state_only` coverage; they are not presented as record-authenticated.
|
|
316
|
+
|
|
317
|
+
Every maintenance rewrite verifies a present record hash before changing the
|
|
318
|
+
stream and reseals the output. When anchors or patch representation change, the
|
|
319
|
+
entry's append-only `reanchor_evidence` retains the prior anchors, item epoch,
|
|
320
|
+
patch digest, and prior record envelope. Lenient repair additionally retains
|
|
321
|
+
the complete replaced patch operations. `verifyHistoryRewriteEvidence()`
|
|
322
|
+
reconstructs every available prior envelope and rejects a record that was
|
|
323
|
+
modified and merely resealed after maintenance. Redaction never copies sensitive patch
|
|
324
|
+
values into new evidence: it keeps the digest and drops a retained patch if the
|
|
325
|
+
patch itself matched a redaction rule. Compaction baselines retain the pruned
|
|
326
|
+
entry count and ordered stream digest plus an explicit
|
|
327
|
+
`individual_pruned_entries_require_pre_compaction_stream` limitation. A holder
|
|
328
|
+
of the pre-compaction stream can therefore validate the checkpoint, while the
|
|
329
|
+
post-compaction stream does not falsely claim that it can reconstruct content
|
|
330
|
+
that was intentionally pruned.
|
|
331
|
+
|
|
236
332
|
## Delete versus modify policy
|
|
237
333
|
|
|
238
334
|
A delete on one branch and an edit on another is not safely resolvable by a generic file driver. The merged workspace must not silently resurrect the item. `storage_integrity` reports the live document plus delete-terminated history as a hard finding. The coordinator chooses one policy explicitly:
|
package/docs/PERFORMANCE.md
CHANGED
|
@@ -12,7 +12,7 @@ Every measured CLI and SDK operation targets:
|
|
|
12
12
|
- default output at or below 5,000 estimated tokens;
|
|
13
13
|
- no feature, flag, output, history, or validation loss.
|
|
14
14
|
|
|
15
|
-
The committed regression budgets in [`scripts/bench/scale-budgets.json`](../scripts/bench/scale-budgets.json) protect the current baseline while the product targets stay fixed. Short local checks use the best observed latency as a regression floor; statistically meaningful runs of 20 or more use p95. Both receive 25% baseline headroom plus a 25 ms scheduler/filesystem noise margin. Reports always retain min/p50/p95, and product-target status always uses p95. This lets a busy workstation detect deterministic code slowdowns without pretending that three samples produce a meaningful p95 or hiding the real tail-latency target.
|
|
15
|
+
The committed regression budgets in [`scripts/bench/scale-budgets.json`](../scripts/bench/scale-budgets.json) protect the current baseline while the product targets stay fixed. Baseline refreshes use the Node major pinned by release and primary CI workflows (currently Node 24); newer supported runtimes remain compatibility targets, but their startup and memory characteristics must not silently rewrite the release baseline. Short local checks use the best observed latency as a regression floor; statistically meaningful runs of 20 or more use p95. Both receive 25% baseline headroom plus a 25 ms scheduler/filesystem noise margin. Reports always retain min/p50/p95, and product-target status always uses p95. This lets a busy workstation detect deterministic code slowdowns without pretending that three samples produce a meaningful p95 or hiding the real tail-latency target.
|
|
16
16
|
|
|
17
17
|
## Reproducible fixtures
|
|
18
18
|
|
|
@@ -92,7 +92,10 @@ probe off and performs no query on the create path; advisory/strict modes reuse
|
|
|
92
92
|
one dependency-light SDK scorer with the package-owned dedupe audit. Mutation
|
|
93
93
|
history events use a separate rebuildable ordered SQLite projection so
|
|
94
94
|
`pm events --since <cursor>` catch-up cost follows new history rows instead of
|
|
95
|
-
workspace size.
|
|
95
|
+
workspace size. Its v5 schema also indexes the declared substantive-versus-
|
|
96
|
+
maintenance event class, allowing context recency to fetch only the latest
|
|
97
|
+
substantive row per requested stream instead of folding complete histories on
|
|
98
|
+
each read. See [SDK Context Coordination](SDK_CONTEXT_COORDINATION.md).
|
|
96
99
|
|
|
97
100
|
SDK hosts that commit authoritative item documents outside the stock mutation
|
|
98
101
|
commands use `acquireItemMetadataDerivedIndexLock` and
|
|
@@ -127,7 +130,7 @@ To refresh a baseline after an intentional, measured improvement:
|
|
|
127
130
|
pnpm benchmark:scale --items ci --iterations 5 --transport both --update --headroom 1.25
|
|
128
131
|
```
|
|
129
132
|
|
|
130
|
-
Review the report and budget diff together. Never update a budget merely to silence a regression.
|
|
133
|
+
Review the report and budget diff together. Before a refresh, compare the delivery head with its exact base commit using the same runtime, fixture shape, and transport set; retain that evidence on the owning PM item. Never update a budget merely to silence a regression.
|
|
131
134
|
|
|
132
135
|
## Startup and observability
|
|
133
136
|
|
package/docs/README.md
CHANGED
|
@@ -63,6 +63,7 @@ pm guide release --json
|
|
|
63
63
|
- [Mutation Integrity](MUTATION_INTEGRITY.md) - shared CLI/SDK/MCP author, secret, append-only disposition, and stale-work guardrails.
|
|
64
64
|
- [Agent Provenance ADR Amendment](AGENT_PROVENANCE_ADR.md) - extensible model, effort, role, and host provenance with privacy and compatibility boundaries.
|
|
65
65
|
- [SDK Agent Session and Episode Context](SDK_AGENT_SESSION_CONTEXT.md) - inherited role/topic context, cross-process episode identity, and deterministic history grouping.
|
|
66
|
+
- [SDK Agent Environments](AGENT_ENVIRONMENTS.md) - calibrated observations, total verdicts, isolated episodes, and an executable public-SDK environment.
|
|
66
67
|
- [Improvement Ledger and History Analytics](IMPROVEMENT_ANALYTICS.md) - audited quantitative observations, live provenance coverage, and bounded observational fleet outcomes.
|
|
67
68
|
- [Project Assurance Primitives](ASSURANCE.md) - SDK-owned measurements, assertions, lifecycle gates, cost receipts, and durable verdict history shared by CLI and MCP.
|
|
68
69
|
- [Defect Recurrence and Boundary Evidence](DEFECT_RECURRENCE.md) - captured external samples, structured defect-escape evidence, incremental change-risk indexing, and executable recovery-producer census.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Universal Read Output Contracts
|
|
2
2
|
|
|
3
|
-
Tracker references: [pm-hb7ug8](../.agents/pm/features/pm-hb7ug8.toon), [pm-cxr0jb](../.agents/pm/features/pm-cxr0jb.toon), [pm-hid9g1](../.agents/pm/features/pm-hid9g1.toon), [pm-h8tpeh](../.agents/pm/features/pm-h8tpeh.toon), [pm-5t33or](../.agents/pm/features/pm-5t33or.toon), [pm-srns](../.agents/pm/issues/pm-srns.toon), [pm-sb0tns](../.agents/pm/issues/pm-sb0tns.toon), [pm-gjjurs](../.agents/pm/issues/pm-gjjurs.toon), [pm-eugaqy](../.agents/pm/issues/pm-eugaqy.toon), [pm-jt8aa2](../.agents/pm/issues/pm-jt8aa2.toon), [pm-kyjdne](../.agents/pm/issues/pm-kyjdne.toon), [pm-8nev0o](../.agents/pm/issues/pm-8nev0o.toon), [pm-oahhyc](../.agents/pm/issues/pm-oahhyc.toon), [pm-q4isdq](../.agents/pm/issues/pm-q4isdq.toon), [pm-e5gl05](../.agents/pm/issues/pm-e5gl05.toon), [pm-cha95z](../.agents/pm/tasks/pm-cha95z.toon), [pm-2qvq7a](../.agents/pm/issues/pm-2qvq7a.toon), and [pm-xam9bt](../.agents/pm/issues/pm-xam9bt.toon).
|
|
3
|
+
Tracker references: [pm-hb7ug8](../.agents/pm/features/pm-hb7ug8.toon), [pm-cxr0jb](../.agents/pm/features/pm-cxr0jb.toon), [pm-hid9g1](../.agents/pm/features/pm-hid9g1.toon), [pm-h8tpeh](../.agents/pm/features/pm-h8tpeh.toon), [pm-5t33or](../.agents/pm/features/pm-5t33or.toon), [pm-wv47pf](../.agents/pm/issues/pm-wv47pf.toon), [pm-srns](../.agents/pm/issues/pm-srns.toon), [pm-sb0tns](../.agents/pm/issues/pm-sb0tns.toon), [pm-gjjurs](../.agents/pm/issues/pm-gjjurs.toon), [pm-eugaqy](../.agents/pm/issues/pm-eugaqy.toon), [pm-jt8aa2](../.agents/pm/issues/pm-jt8aa2.toon), [pm-kyjdne](../.agents/pm/issues/pm-kyjdne.toon), [pm-8nev0o](../.agents/pm/issues/pm-8nev0o.toon), [pm-oahhyc](../.agents/pm/issues/pm-oahhyc.toon), [pm-q4isdq](../.agents/pm/issues/pm-q4isdq.toon), [pm-e5gl05](../.agents/pm/issues/pm-e5gl05.toon), [pm-cha95z](../.agents/pm/tasks/pm-cha95z.toon), [pm-2qvq7a](../.agents/pm/issues/pm-2qvq7a.toon), and [pm-xam9bt](../.agents/pm/issues/pm-xam9bt.toon).
|
|
4
4
|
|
|
5
5
|
## Agent Quick Context
|
|
6
6
|
|
|
@@ -153,6 +153,14 @@ pm contracts --full --json
|
|
|
153
153
|
|
|
154
154
|
Every projected result carries a `read_output` receipt with the requested dimensions, precedence, observed option provenance, deterministic estimated token count, string/row compaction signals, and budget outcome. When canonical controls are present, `canonical_options_used` records spellings such as `--output-include`; the optional field is omitted when no canonical control was supplied so minimum-budget session receipts remain compact. `legacy_aliases_used` and `migration_hints` record only compatibility flags the caller actually supplied. A command-local flag synthesized internally to execute a canonical projection mode is therefore never misreported as deprecated syntax. When both spellings are supplied, both provenance arrays report that mixed invocation. Budget degradation discovers nested arrays as well as declared result rows, so validation diagnostics and other governance payloads compact their inner findings before the useful result is omitted. `compacted_row_paths` names every reduced collection without redefining those nested arrays as ordinary pagination rows.
|
|
155
155
|
|
|
156
|
+
For `context` and `next`, that final projection is also the usage-feedback
|
|
157
|
+
delivery boundary. The SDK carries a JSON-invisible serve receipt through
|
|
158
|
+
intent and universal output projection, then appends the final omitted decision
|
|
159
|
+
and exact emitted item ids. An infeasible output budget records zero delivered
|
|
160
|
+
rows; it can never leave the packer's earlier inclusions marked as served.
|
|
161
|
+
`PmClient` finalizes the receipt before resolving, while the CLI finalizes it
|
|
162
|
+
from the exact active result passed to telemetry and after-command hooks.
|
|
163
|
+
|
|
156
164
|
When rows are dropped to satisfy a ceiling, the result also carries `output_budget_truncation`, naming the binding budget and its source, any explicitly requested dimension the budget overrode, every compacted collection path, and executable CLI/SDK/MCP recovery options — a default ceiling can override an explicit `--output-limit unbounded`, and that override is reported rather than silent. If a producer supplied an opaque item-page cursor, compaction rebases it to the last row actually returned and reports `continuation_cursor_rebased: true`; following the cursor therefore cannot skip rows removed from the middle of a producer page. If no useful content can fit, `PmReadOutputBudgetExceeded` provides a discriminated omission result, a compact `{ outputBudget: "unbounded" }` recovery object, and `omitted_result_estimated_tokens`, the last useful-result estimate before omission; use `isReadOutputBudgetExceeded` before accessing result-specific fields. Universal controls are rejected on mutation commands and on the mutation mode of hybrid commands such as `comments`, `notes`, `files`, and `docs`.
|
|
157
165
|
|
|
158
166
|
Cursor recovery carries the opaque value once in `recovery.cursor` and declares
|
package/docs/SDK.md
CHANGED
|
@@ -1773,14 +1773,17 @@ For persistent derived signals, use `ContextSignalStore` with a caller-owned
|
|
|
1773
1773
|
`ContextSignalStoreAdapter`, or use `JsonFileContextSignalStoreAdapter` for a
|
|
1774
1774
|
same-directory atomic JSON snapshot. Each snapshot carries both a
|
|
1775
1775
|
`format_version` and `signal_set_version`, the authoritative history or index
|
|
1776
|
-
`source_cursor`,
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1776
|
+
`source_cursor`, a deterministic `recency_evidence_fingerprint`, the stable
|
|
1777
|
+
caller clock, and whether its items came from the `derived_index` or
|
|
1778
|
+
`scan_fallback` path. Item rows are deterministic and sorted; the snapshot never
|
|
1779
|
+
replaces item or history data.
|
|
1780
|
+
|
|
1781
|
+
`readOrRebuild(items, options)` reuses a snapshot only when its format and
|
|
1782
|
+
signal-set metadata are supported, its item source matches, and its cursor,
|
|
1783
|
+
complete item-id set, and substantive recency-evidence fingerprint match.
|
|
1784
|
+
Missing, stale, version-incompatible, or corrupt state is rebuilt from the
|
|
1785
|
+
authoritative items and atomically replaced. The result reports `cache_status`
|
|
1786
|
+
and non-fatal `context_signal_store_stale`,
|
|
1784
1787
|
`context_signal_store_invalid`, or `context_signal_store_write_failed`
|
|
1785
1788
|
warnings. A write failure still serves the in-memory rebuilt candidates because
|
|
1786
1789
|
the snapshot is derived, never authoritative. Optional maps for activity density,
|
package/docs/SDK_CONTEXT.md
CHANGED
|
@@ -31,6 +31,13 @@ stale, or unwritable snapshots return a stable warning, its meaning, an
|
|
|
31
31
|
executable recovery command, and the expected effect. Re-running `pm context`
|
|
32
32
|
confirms a successful rebuild as fresh.
|
|
33
33
|
|
|
34
|
+
Recency uses the public `classifyHistoryEvent()` contract and the most recent
|
|
35
|
+
substantive immutable event, with release-cohort and `created_at` fallbacks.
|
|
36
|
+
Explained ranking carries the selected coordinate, operation, and class.
|
|
37
|
+
`recordContextUsageServing()` plus `recordContextUsageDelivery()` expose the
|
|
38
|
+
same two-phase feedback boundary used by CLI and `PmClient`, so custom hosts can
|
|
39
|
+
correlate propensity rows with the exact result delivered after output budgets.
|
|
40
|
+
|
|
34
41
|
See [Context relevance and packing](CONTEXT_RELEVANCE.md) for signal and token
|
|
35
42
|
budgets, and [context coordination](SDK_CONTEXT_COORDINATION.md) for cursored
|
|
36
43
|
events and duplicate governance.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# SDK Context and Evidence Contracts
|
|
2
2
|
|
|
3
|
-
Tracked by [pm-gok2km](../.agents/pm/issues/pm-gok2km.toon), [pm-zryb9d](../.agents/pm/issues/pm-zryb9d.toon), [pm-qckpnq](../.agents/pm/issues/pm-qckpnq.toon), [pm-hfqju5](../.agents/pm/issues/pm-hfqju5.toon), [pm-2htk4p](../.agents/pm/issues/pm-2htk4p.toon),
|
|
3
|
+
Tracked by [pm-gok2km](../.agents/pm/issues/pm-gok2km.toon), [pm-zryb9d](../.agents/pm/issues/pm-zryb9d.toon), [pm-qckpnq](../.agents/pm/issues/pm-qckpnq.toon), [pm-hfqju5](../.agents/pm/issues/pm-hfqju5.toon), [pm-2htk4p](../.agents/pm/issues/pm-2htk4p.toon), [pm-v0a0un](../.agents/pm/issues/pm-v0a0un.toon), [pm-7wzb6d](../.agents/pm/issues/pm-7wzb6d.toon), [pm-mg13iz](../.agents/pm/issues/pm-mg13iz.toon), and [pm-cf4t42](../.agents/pm/issues/pm-cf4t42.toon).
|
|
4
4
|
|
|
5
5
|
These contracts keep SDK context truthful, bounded, and reusable across the CLI, MCP, packages, and automation. They are designed around the project principle that project management is context management: a compact response must reveal material omissions, merge evidence must describe what actually survived, and compatibility failures must not masquerade as corruption.
|
|
6
6
|
|
|
@@ -22,7 +22,29 @@ This keeps health diagnostics and lazy runtime behavior on one ownership contrac
|
|
|
22
22
|
|
|
23
23
|
## Merge provenance
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
Item scalar merges distinguish a caller request from the convergent outcome.
|
|
26
|
+
The `latest_document_update` policy selects the branch document with the later
|
|
27
|
+
`metadata.updated_at`; equal timestamps use stable value order. Low-level item
|
|
28
|
+
results, driver results, receipts, and privacy-safe summaries expose
|
|
29
|
+
`requested_preference` plus `requested_preference_applied: false`. Each new
|
|
30
|
+
decision records `retained_side` and `resolution_basis`. New receipts do not
|
|
31
|
+
emit the ambiguous `preferred` key; readers still ingest legacy schema-v1
|
|
32
|
+
receipts and normalize `preferred_side` and `stable_value_order` evidence.
|
|
33
|
+
|
|
34
|
+
Tracked receipt evidence uses `bounded_non_sensitive_scalars_v1`: built-in
|
|
35
|
+
status, priority 0 through 4, risk/confidence/severity ordinals, and `null` may
|
|
36
|
+
be included beside their verifiable hashes. Every other value remains
|
|
37
|
+
hash-only. Fresh-clone consumers must branch on `value_availability` rather than
|
|
38
|
+
assuming raw values exist. Invalid evidence separates `schema_invalid` from
|
|
39
|
+
`identity_invalid` and adds a bounded `validation_error`, while retaining the
|
|
40
|
+
legacy combined reason in the public union for source compatibility.
|
|
41
|
+
|
|
42
|
+
`runMergeReconcile` also reports missing history receipt counts before and
|
|
43
|
+
after the operation. With explicit `force`, it can append a narrowly matched
|
|
44
|
+
audit disposition for a missing reference whose original event predates the
|
|
45
|
+
durable-receipt epoch. The item id, original line, receipt id, and timestamp
|
|
46
|
+
must all match, and the audit event must occur later in that history stream;
|
|
47
|
+
current-era missing evidence remains blocking.
|
|
26
48
|
|
|
27
49
|
## Claim race classification
|
|
28
50
|
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Tracker: [pm-1eted6](../.agents/pm/issues/pm-1eted6.toon),
|
|
4
4
|
[pm-3lhth4](../.agents/pm/issues/pm-3lhth4.toon), and
|
|
5
|
-
[pm-0xmajx](../.agents/pm/issues/pm-0xmajx.toon)
|
|
5
|
+
[pm-0xmajx](../.agents/pm/issues/pm-0xmajx.toon), with forward history-epoch
|
|
6
|
+
protection tracked by
|
|
7
|
+
[pm-aka8m7](../.agents/pm/issues/pm-aka8m7.toon). Refusal reachability and
|
|
6
8
|
recovery completeness are tracked by
|
|
7
9
|
[pm-elmpav](../.agents/pm/features/pm-elmpav.toon),
|
|
8
10
|
[pm-185870](../.agents/pm/issues/pm-185870.toon), and
|
|
@@ -29,6 +31,20 @@ package-manager-neutral recovery action. SDK callers receive the same warning
|
|
|
29
31
|
inside `ProjectRuntimeCompatibilityResult`. `PM_ALLOW_STALE_CLI=1` is the
|
|
30
32
|
explicit, auditable emergency override.
|
|
31
33
|
|
|
34
|
+
The boundary is bidirectional for history storage. A current runtime also
|
|
35
|
+
refuses a mutation when any package declaration or lockfile pin cannot select a
|
|
36
|
+
runtime that reads the writer epoch. Every manifest section is evaluated, so a
|
|
37
|
+
newer permissive declaration cannot hide an older exact pin. Upper-bounded
|
|
38
|
+
ranges that exclude the first compatible reader also fail closed, including
|
|
39
|
+
inclusive hyphen ranges. Disjunctive ranges evaluate each alternative, so one
|
|
40
|
+
branch that can select a compatible reader keeps the declaration writable. The
|
|
41
|
+
original incompatible declaration is preserved in the diagnostic rather than
|
|
42
|
+
being reduced to its representative lower bound. The typed
|
|
43
|
+
`project_runtime_history_epoch_incompatible` error reports the writer epoch,
|
|
44
|
+
the incompatible declaration, its redaction-safe source, and the minimum
|
|
45
|
+
upgrade. Reads remain available, and the same emergency override is reserved
|
|
46
|
+
for an intentionally coordinated fleet migration.
|
|
47
|
+
|
|
32
48
|
The public `isProjectMutatingInvocation` classifier applies the same decision
|
|
33
49
|
to package hosts and the bundled CLI. It resolves mixed command families by
|
|
34
50
|
their effective action: configuration, merge, schema, profile, package,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Public SDK Agent Environment
|
|
2
|
+
|
|
3
|
+
Tracker: [pm-t8a0x1](../../../.agents/pm/features/pm-t8a0x1.toon)
|
|
4
|
+
|
|
5
|
+
This executable example imports only Node.js built-ins and `@unbrained/pm-cli/sdk`. It creates an isolated temporary tracker, uses ordinary `PmClient` actions, serves a budgeted observation, evaluates recorded state, and closes the episode. It has no machine-learning dependencies.
|
|
6
|
+
|
|
7
|
+
From an installed package checkout:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @unbrained/pm-cli
|
|
11
|
+
npm start
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The JSON result is intentionally small and stable enough for a CI assertion. The temporary workspace is removed after the run.
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { mkdtemp, rm } from "node:fs/promises";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import {
|
|
5
|
+
PM_EPISODE_SCHEMA,
|
|
6
|
+
PM_OBSERVATION_SCHEMA,
|
|
7
|
+
PM_VERDICT_SCHEMA,
|
|
8
|
+
PM_WORKSPACE_RECIPE_SCHEMA,
|
|
9
|
+
PmClient,
|
|
10
|
+
defineEpisodeSpecification,
|
|
11
|
+
openPmEpisode,
|
|
12
|
+
runWithWorkspaceRecipe,
|
|
13
|
+
} from "@unbrained/pm-cli/sdk";
|
|
14
|
+
|
|
15
|
+
class PublicSdkAdapter {
|
|
16
|
+
constructor(workspace) {
|
|
17
|
+
this.client = new PmClient({ cwd: workspace, noExtensions: true });
|
|
18
|
+
this.itemId = "";
|
|
19
|
+
this.revision = 0;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async reset(recipe) {
|
|
23
|
+
const created = await runWithWorkspaceRecipe(recipe, async () => {
|
|
24
|
+
await this.client.init("environment");
|
|
25
|
+
return this.client.create({
|
|
26
|
+
id: "pm-created-by-adapter",
|
|
27
|
+
title: "Complete the SDK environment task",
|
|
28
|
+
type: "Task",
|
|
29
|
+
status: "open",
|
|
30
|
+
description: "Created inside a deterministic public-SDK episode.",
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
this.itemId = created.item.id;
|
|
34
|
+
this.revision = 0;
|
|
35
|
+
return { workspace_id: "temporary-pm-workspace", state_id: "revision:0" };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async execute(_action) {
|
|
39
|
+
const result = await this.client.close(
|
|
40
|
+
this.itemId,
|
|
41
|
+
"Public SDK episode completed",
|
|
42
|
+
{
|
|
43
|
+
resolution: "The ordinary PmClient close action recorded completion.",
|
|
44
|
+
expected: "The task is closed through the public SDK.",
|
|
45
|
+
actual: "The task is closed through the public SDK.",
|
|
46
|
+
validateClose: "warn",
|
|
47
|
+
},
|
|
48
|
+
);
|
|
49
|
+
this.revision += 1;
|
|
50
|
+
return { state_id: `revision:${this.revision}`, output: result };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async readRecordedState() {
|
|
54
|
+
const result = await this.client.get(this.itemId);
|
|
55
|
+
return {
|
|
56
|
+
snapshot_id: `revision:${this.revision}`,
|
|
57
|
+
state: {
|
|
58
|
+
item: {
|
|
59
|
+
id: result.item.id,
|
|
60
|
+
title: result.item.title,
|
|
61
|
+
status: result.item.status,
|
|
62
|
+
resolution: result.item.resolution,
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const observation = {
|
|
70
|
+
schema: PM_OBSERVATION_SCHEMA,
|
|
71
|
+
id: "sdk-task-state",
|
|
72
|
+
version: 1,
|
|
73
|
+
reads: [{ command: "get", budget_tokens: 256 }],
|
|
74
|
+
calibration: {
|
|
75
|
+
basis: "emitted_bytes",
|
|
76
|
+
samples: [96, 128, 160],
|
|
77
|
+
expected_emitted_bytes: 128,
|
|
78
|
+
tolerance_bytes: 32,
|
|
79
|
+
},
|
|
80
|
+
corpus_dependence: { kind: "independent" },
|
|
81
|
+
tiers: [
|
|
82
|
+
{
|
|
83
|
+
id: "standard",
|
|
84
|
+
max_tokens: 256,
|
|
85
|
+
fields: ["item.id", "item.title", "item.status", "item.resolution"],
|
|
86
|
+
},
|
|
87
|
+
{ id: "identity", max_tokens: 48, fields: ["item.id", "item.status"] },
|
|
88
|
+
],
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const verdict = {
|
|
92
|
+
schema: PM_VERDICT_SCHEMA,
|
|
93
|
+
id: "sdk-task-closed",
|
|
94
|
+
version: 1,
|
|
95
|
+
predicates: [
|
|
96
|
+
{
|
|
97
|
+
id: "closed",
|
|
98
|
+
kind: "field_equals",
|
|
99
|
+
path: "item.status",
|
|
100
|
+
expected: "closed",
|
|
101
|
+
},
|
|
102
|
+
{ id: "explained", kind: "field_present", path: "item.resolution" },
|
|
103
|
+
],
|
|
104
|
+
composition: { operator: "all", predicate_ids: ["closed", "explained"] },
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const workspace = await mkdtemp(join(tmpdir(), "pm-sdk-environment-"));
|
|
108
|
+
try {
|
|
109
|
+
const session = await openPmEpisode(
|
|
110
|
+
defineEpisodeSpecification({
|
|
111
|
+
schema: PM_EPISODE_SCHEMA,
|
|
112
|
+
id: "public-sdk-environment",
|
|
113
|
+
version: 1,
|
|
114
|
+
mode: "evaluation",
|
|
115
|
+
recipe: {
|
|
116
|
+
schema: PM_WORKSPACE_RECIPE_SCHEMA,
|
|
117
|
+
seed: "public-sdk-environment",
|
|
118
|
+
clock: "2026-09-03T00:00:00.000Z",
|
|
119
|
+
tickMs: 1,
|
|
120
|
+
operations: [],
|
|
121
|
+
},
|
|
122
|
+
task_item_ids: ["pm-created-by-adapter"],
|
|
123
|
+
observable_fields: [
|
|
124
|
+
"item.id",
|
|
125
|
+
"item.title",
|
|
126
|
+
"item.status",
|
|
127
|
+
"item.resolution",
|
|
128
|
+
],
|
|
129
|
+
withheld_fields: ["grading.expected_status"],
|
|
130
|
+
observation,
|
|
131
|
+
verdict,
|
|
132
|
+
limits: {
|
|
133
|
+
max_actions: 1,
|
|
134
|
+
max_observations: 2,
|
|
135
|
+
max_tokens_per_observation: 256,
|
|
136
|
+
},
|
|
137
|
+
}),
|
|
138
|
+
new PublicSdkAdapter(workspace),
|
|
139
|
+
);
|
|
140
|
+
const initial = await session.observe();
|
|
141
|
+
await session.step({ kind: "close" });
|
|
142
|
+
const completed = await session.close();
|
|
143
|
+
process.stdout.write(
|
|
144
|
+
`${JSON.stringify({
|
|
145
|
+
initial_status: initial.status,
|
|
146
|
+
initial_tier: initial.receipt.served_tier,
|
|
147
|
+
verdict: completed.verdict.outcome,
|
|
148
|
+
policy: completed.verdict.policy,
|
|
149
|
+
trajectory: completed.trajectory.map((entry) => entry.kind),
|
|
150
|
+
})}\n`,
|
|
151
|
+
);
|
|
152
|
+
} finally {
|
|
153
|
+
await rm(workspace, { recursive: true, force: true });
|
|
154
|
+
}
|
|
@@ -4,12 +4,12 @@ Tracker: `pm-f05lsg`.
|
|
|
4
4
|
|
|
5
5
|
Every catalog code is listed. An `uncovered` row is an explicit closure obligation, never an omission or implied approval.
|
|
6
6
|
|
|
7
|
-
- Catalog error codes:
|
|
7
|
+
- Catalog error codes: 357
|
|
8
8
|
- Executable error codes: 19
|
|
9
9
|
- Executable-code ratchet floor: 18
|
|
10
10
|
- Required executable canonical codes: `bulk_ids_input_empty`, `bulk_ids_input_missing_path`, `bulk_ids_input_unreadable`, `invalid_argument_value`, `manifest_unknown_key`, `missing_lifecycle_target`, `missing_required_argument`, `no_version_bounds_declared`, `projection_options_mutually_exclusive`, `tracker_not_initialized`, `tracker_root_missing`, `tracker_root_not_directory`, `tracker_root_unreadable`, `unknown_context_intent`, `unknown_field_projection`, `unknown_option`, `unknown_subcommand`
|
|
11
|
-
- Uncovered error codes:
|
|
12
|
-
- Coverage fraction: 0.
|
|
11
|
+
- Uncovered error codes: 338
|
|
12
|
+
- Coverage fraction: 0.053221
|
|
13
13
|
- Closed-domain probes: 19
|
|
14
14
|
- Grammar probes: 94
|
|
15
15
|
|
|
@@ -120,6 +120,7 @@ Every catalog code is listed. An `uncovered` row is an explicit closure obligati
|
|
|
120
120
|
| `history_merge_conflict_markers_detected` | `merge_conflict_markers_detected` | uncovered | none | 0 |
|
|
121
121
|
| `history_stream_over_compact_threshold` | `history_stream_over_compact_threshold` | uncovered | none | 0 |
|
|
122
122
|
| `history_target_out_of_range` | `history_target_out_of_range` | uncovered | none | 0 |
|
|
123
|
+
| `history_timestamp_invalid` | `history_timestamp_invalid` | uncovered | none | 0 |
|
|
123
124
|
| `history_unknown_author_events` | `history_unknown_author_events` | uncovered | none | 0 |
|
|
124
125
|
| `host_environment_capacity_fault` | `host_environment_capacity_fault` | uncovered | none | 0 |
|
|
125
126
|
| `host_environment_operation_invalid` | `host_environment_operation_invalid` | uncovered | none | 0 |
|
|
@@ -232,6 +233,7 @@ Every catalog code is listed. An `uncovered` row is an explicit closure obligati
|
|
|
232
233
|
| `profile_name_not_normalized` | `profile_name_not_normalized` | uncovered | none | 0 |
|
|
233
234
|
| `profile_summary_empty` | `profile_summary_empty` | uncovered | none | 0 |
|
|
234
235
|
| `profile_title_empty` | `profile_title_empty` | uncovered | none | 0 |
|
|
236
|
+
| `project_runtime_history_epoch_incompatible` | `project_runtime_history_epoch_incompatible` | uncovered | none | 0 |
|
|
235
237
|
| `project_runtime_stale_mutation` | `project_runtime_stale_mutation` | uncovered | none | 0 |
|
|
236
238
|
| `project_runtime_stale_read` | `project_runtime_stale_read` | uncovered | none | 0 |
|
|
237
239
|
| `projection_options_mutually_exclusive` | `projection_options_mutually_exclusive` | executable | closed_domain | 3 |
|