@unbrained/pm-cli 2026.8.11 → 2026.8.13
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 +74 -21
- package/dist/cli/commander-usage.js +37 -11
- package/dist/cli/error-guidance.d.ts +2 -0
- package/dist/cli/error-guidance.js +82 -19
- package/dist/cli/main.js +35 -19
- package/dist/cli/register-annotations.js +56 -3
- package/dist/cli/register-assurance.js +28 -17
- package/dist/cli/register-list-query.js +10 -7
- package/dist/cli/register-operations.js +16 -6
- package/dist/cli-bundle/bundle-manifest.json +163 -163
- package/dist/cli-bundle/chunks/chunk-3ZMOWAFM.js +2 -0
- package/dist/cli-bundle/chunks/chunk-DEDU3DG7.js +196 -0
- package/dist/cli-bundle/chunks/chunk-DL5M5J3V.js +13 -0
- package/dist/cli-bundle/chunks/chunk-F7FJYGK3.js +8 -0
- package/dist/cli-bundle/chunks/chunk-HIUZVCMN.js +5 -0
- package/dist/cli-bundle/chunks/chunk-IMGIN7R6.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-A2SJGHSI.js → chunk-Q47C67TQ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-WMEZHCFI.js → chunk-QGTUPEU5.js} +62 -54
- package/dist/cli-bundle/chunks/chunk-TF3TPKPR.js +34 -0
- package/dist/cli-bundle/chunks/{chunk-ZU34C3LH.js → chunk-YLBAPY22.js} +50 -50
- package/dist/cli-bundle/chunks/register-list-query-4HIZ7EA3.js +10 -0
- package/dist/cli-bundle/chunks/register-mutation-W64FZ5HN.js +20 -0
- package/dist/cli-bundle/chunks/register-operations-C44ET7R5.js +2 -0
- package/dist/cli-bundle/chunks/{register-setup-NOCOOWQY.js → register-setup-634MFRXU.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-27N23W6M.js +31 -0
- package/dist/cli-bundle/focused-chunks/{chunk-4H5IA6AV.js → chunk-2JP7W7GO.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-2RI2FESN.js +4 -0
- package/dist/cli-bundle/focused-chunks/chunk-3BNVU6LC.js +8 -0
- package/dist/cli-bundle/focused-chunks/{chunk-2DL3MRTD.js → chunk-3DJSGWVB.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-6MLIRBLV.js +5 -0
- package/dist/cli-bundle/focused-chunks/chunk-6XYLENDV.js +155 -0
- package/dist/cli-bundle/focused-chunks/chunk-CP4K4WFS.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-TL5M2PAY.js → chunk-E3AVJ655.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-EBTNSFYE.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-J5EKAIVD.js → chunk-HC2OL2H2.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-BKPIY34S.js → chunk-I75MANL7.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-IIS2FRKL.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-NFHFZH2Z.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-OGC4XSBC.js +17 -0
- package/dist/cli-bundle/focused-chunks/{chunk-UDAZWT25.js → chunk-OOYYKQWX.js} +4 -4
- package/dist/cli-bundle/focused-chunks/{chunk-23FTGO3W.js → chunk-PKPOZXLL.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-QDZUABWL.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-QQX5TDFT.js +16 -0
- package/dist/cli-bundle/focused-chunks/{chunk-55BIB6DV.js → chunk-TEZIXMTH.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-WEH6NSL6.js +18 -0
- package/dist/cli-bundle/main.js +13 -13
- 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 +42 -41
- 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 +1 -1
- 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 +2 -2
- package/dist/core/checkpoint/checkpoint-gc.js +7 -12
- package/dist/core/extensions/activation-summary-markdown.js +5 -4
- package/dist/core/extensions/activation-summary.d.ts +2 -0
- package/dist/core/extensions/activation-summary.js +6 -2
- package/dist/core/extensions/capability-usage.d.ts +1 -1
- package/dist/core/extensions/capability-usage.js +4 -3
- package/dist/core/extensions/contribution-inventory.d.ts +1 -0
- package/dist/core/extensions/contribution-inventory.js +6 -2
- package/dist/core/extensions/extension-registries.js +3 -2
- package/dist/core/extensions/extension-types.d.ts +83 -1
- package/dist/core/extensions/extension-types.js +3 -2
- package/dist/core/extensions/loader.d.ts +2 -8
- package/dist/core/extensions/loader.js +53 -144
- package/dist/core/extensions/registration-values.d.ts +43 -0
- package/dist/core/extensions/registration-values.js +210 -0
- package/dist/core/extensions/reserved-host-flags.js +3 -2
- package/dist/core/extensions/runtime-registrations.d.ts +3 -1
- package/dist/core/extensions/runtime-registrations.js +12 -2
- package/dist/core/fs/fs-utils.d.ts +2 -0
- package/dist/core/fs/fs-utils.js +7 -3
- package/dist/core/history/drift-cache.js +4 -3
- package/dist/core/history/drift-scan.js +16 -17
- package/dist/core/history/history.d.ts +8 -0
- package/dist/core/history/history.js +57 -7
- package/dist/core/history/replay.d.ts +9 -1
- package/dist/core/history/replay.js +48 -13
- package/dist/core/lock/lock-gc.js +8 -13
- package/dist/core/lock/lock.js +5 -4
- package/dist/core/output/output.d.ts +2 -0
- package/dist/core/output/output.js +46 -14
- package/dist/core/search/vector-stores.js +6 -11
- package/dist/core/shared/command-types.d.ts +2 -0
- package/dist/core/shared/command-types.js +2 -2
- package/dist/core/shared/errors.d.ts +5 -0
- package/dist/core/shared/errors.js +2 -2
- package/dist/core/store/item-metadata-cache.d.ts +1 -1
- package/dist/core/store/item-metadata-cache.js +16 -9
- package/dist/core/telemetry/runtime.d.ts +6 -0
- package/dist/core/telemetry/runtime.js +101 -30
- package/dist/sdk/agent/command-recovery.d.ts +2 -0
- package/dist/sdk/agent/command-recovery.js +10 -2
- package/dist/sdk/annotations.js +4 -4
- package/dist/sdk/cli-bootstrap.d.ts +2 -0
- package/dist/sdk/cli-bootstrap.js +6 -2
- package/dist/sdk/cli-contracts/completeness.js +10 -3
- package/dist/sdk/cli-contracts/enum-contracts.d.ts +1 -1
- package/dist/sdk/cli-contracts/flag-contracts.js +9 -3
- package/dist/sdk/cli-contracts/registration-helpers.d.ts +20 -3
- package/dist/sdk/cli-contracts/registration-helpers.js +18 -12
- package/dist/sdk/cli-contracts/schemas/assurance-definition.d.ts +40 -6
- package/dist/sdk/cli-contracts/schemas/assurance-definition.js +27 -3
- package/dist/sdk/cli-contracts/tool-option-contracts.js +3 -2
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +55 -5
- package/dist/sdk/cli-contracts/tool-schema.d.ts +2 -2
- package/dist/sdk/cli-contracts/tool-schema.js +22 -4
- package/dist/sdk/cli-program.js +3 -2
- package/dist/sdk/comments.js +4 -3
- package/dist/sdk/compile-cache.js +4 -3
- package/dist/sdk/completion.js +16 -7
- package/dist/sdk/compose.d.ts +3 -1
- package/dist/sdk/compose.js +16 -2
- package/dist/sdk/context-intent-contracts.js +45 -4
- package/dist/sdk/context-signal-store.js +4 -3
- package/dist/sdk/core.d.ts +1 -0
- package/dist/sdk/core.js +3 -2
- package/dist/sdk/extension/install-runtime.js +4 -4
- package/dist/sdk/extension/managed-state.js +4 -3
- package/dist/sdk/extension-contracts.d.ts +1 -1
- package/dist/sdk/flag-invocation-contracts.js +5 -6
- package/dist/sdk/generated/generated-error-code-catalog-part-1.d.ts +8 -0
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1597 -0
- package/dist/sdk/generated/generated-error-code-catalog-part-2.d.ts +8 -0
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1608 -0
- package/dist/sdk/generated-error-code-catalog.js +6 -3140
- package/dist/sdk/governance/assurance-action.d.ts +27 -3
- package/dist/sdk/governance/assurance-action.js +117 -31
- package/dist/sdk/governance/assurance-mutation-error.d.ts +14 -0
- package/dist/sdk/governance/assurance-mutation-error.js +58 -0
- package/dist/sdk/governance/assurance-presets.d.ts +54 -0
- package/dist/sdk/governance/assurance-presets.js +136 -0
- package/dist/sdk/governance/assurance-runtime.d.ts +4 -0
- package/dist/sdk/governance/assurance-runtime.js +118 -14
- package/dist/sdk/governance/assurance.d.ts +51 -6
- package/dist/sdk/governance/assurance.js +321 -67
- package/dist/sdk/governance/gc.js +5 -11
- package/dist/sdk/governance/health.d.ts +3 -1
- package/dist/sdk/governance/health.js +24 -7
- package/dist/sdk/governance/validate-item-reader.js +3 -3
- package/dist/sdk/governance/validate.d.ts +2 -0
- package/dist/sdk/governance/validate.js +15 -5
- package/dist/sdk/graph/durable-cache.d.ts +1 -1
- package/dist/sdk/graph/durable-cache.js +156 -29
- package/dist/sdk/graph/governance-contracts.d.ts +12 -0
- package/dist/sdk/graph/governance-contracts.js +27 -0
- package/dist/sdk/graph/governance.d.ts +44 -2
- package/dist/sdk/graph/governance.js +156 -12
- package/dist/sdk/guide.js +4 -4
- package/dist/sdk/index.d.ts +3 -2
- package/dist/sdk/index.js +5 -4
- package/dist/sdk/lifecycle/claim.js +10 -3
- package/dist/sdk/linked-artifacts.d.ts +2 -0
- package/dist/sdk/linked-artifacts.js +29 -4
- package/dist/sdk/merge/driver.d.ts +2 -2
- package/dist/sdk/merge/driver.js +3 -3
- package/dist/sdk/merge/install.js +5 -4
- package/dist/sdk/merge/receipts.d.ts +6 -4
- package/dist/sdk/merge/receipts.js +7 -5
- package/dist/sdk/merge/three-way.d.ts +2 -2
- package/dist/sdk/merge/three-way.js +3 -3
- package/dist/sdk/output-projection.d.ts +9 -1
- package/dist/sdk/output-projection.js +45 -9
- package/dist/sdk/query/activity.d.ts +49 -2
- package/dist/sdk/query/activity.js +185 -38
- package/dist/sdk/query/get.js +19 -2
- package/dist/sdk/read-output-contracts.d.ts +5 -1
- package/dist/sdk/read-output-contracts.js +17 -2
- package/dist/sdk/read-output-session.d.ts +2 -0
- package/dist/sdk/read-output-session.js +12 -5
- package/dist/sdk/relationship-history.js +5 -5
- package/dist/sdk/runtime-primitives.d.ts +3 -3
- package/dist/sdk/runtime-primitives.js +5 -5
- package/dist/sdk/runtime-stats-options.js +3 -2
- package/dist/sdk/runtime.js +5 -9
- package/dist/sdk/schema-migration.js +4 -4
- package/dist/sdk/stats.d.ts +36 -3
- package/dist/sdk/stats.js +55 -15
- package/dist/sdk/test/execution.d.ts +4 -0
- package/dist/sdk/test/execution.js +88 -23
- package/dist/sdk/workspace-memory.js +4 -4
- package/dist/sdk/workspace-snapshot.js +8 -14
- package/dist/sdk/workspace-transaction-gc.js +4 -9
- package/dist/sdk/workspace-transaction.js +4 -4
- package/dist/sdk/workspace.js +4 -3
- package/dist/types.d.ts +2 -0
- package/dist/types.js +2 -2
- package/docs/ASSURANCE.md +170 -14
- package/docs/COMMANDS.md +29 -8
- package/docs/CONFIGURATION.md +9 -0
- package/docs/DEPENDENCY_KIND_CONTRACT.md +10 -8
- package/docs/EXTENSIONS.md +11 -12
- package/docs/MERGE_SAFETY.md +3 -1
- package/docs/OUTPUT_PROJECTION_CONTRACTS.md +26 -13
- package/docs/README.md +2 -0
- package/docs/READ_OUTPUT_CONTRACTS.md +17 -2
- package/docs/RELATIONSHIP_GRAPH.md +15 -0
- package/docs/SDK.md +17 -3
- package/docs/SDK_AGENT_SESSION_CONTEXT.md +12 -1
- package/docs/SDK_CONTEXT_EVIDENCE_CONTRACTS.md +53 -0
- package/docs/SDK_CONTEXT_INTEGRITY.md +28 -1
- package/docs/TESTING.md +24 -15
- package/docs/TRUSTWORTHY_CONTEXT_EVIDENCE.md +106 -0
- package/docs/performance/sdk-entrypoint-import-costs.md +6 -2
- package/marketplace.json +2 -2
- package/package.json +6 -6
- 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 +384 -83
- package/dist/cli-bundle/chunks/chunk-2OOU2AFH.js +0 -8
- package/dist/cli-bundle/chunks/chunk-2RA2YTHJ.js +0 -33
- package/dist/cli-bundle/chunks/chunk-DSKYD4LG.js +0 -13
- package/dist/cli-bundle/chunks/chunk-HC3GM6YY.js +0 -194
- package/dist/cli-bundle/chunks/chunk-IUNRVDAI.js +0 -2
- package/dist/cli-bundle/chunks/chunk-W7CPZGSB.js +0 -2
- package/dist/cli-bundle/chunks/chunk-ZXOC6HG5.js +0 -5
- package/dist/cli-bundle/chunks/register-list-query-HAUXVUPY.js +0 -10
- package/dist/cli-bundle/chunks/register-mutation-7Y5U7ABT.js +0 -20
- package/dist/cli-bundle/chunks/register-operations-EQX3DLAZ.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-3AYKXMYX.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-4AHEC74N.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-4SV3ZKG3.js +0 -16
- package/dist/cli-bundle/focused-chunks/chunk-6JW6Z2P5.js +0 -8
- package/dist/cli-bundle/focused-chunks/chunk-D4PIWE6D.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-DPO7TEFX.js +0 -31
- package/dist/cli-bundle/focused-chunks/chunk-E3KCL7AY.js +0 -5
- package/dist/cli-bundle/focused-chunks/chunk-ERAAFLPS.js +0 -153
- package/dist/cli-bundle/focused-chunks/chunk-F6E4JZKG.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-FPSYO5ZG.js +0 -18
- package/dist/cli-bundle/focused-chunks/chunk-KDH5OX3D.js +0 -4
- package/dist/cli-bundle/focused-chunks/chunk-OJ3LVVIS.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-VABB4L5Y.js +0 -17
package/docs/ASSURANCE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Project Assurance Primitives
|
|
2
2
|
|
|
3
|
-
Tracker: [pm-2lex4r](../.agents/pm/features/pm-2lex4r.toon), [pm-lyfu7b](../.agents/pm/features/pm-lyfu7b.toon), [pm-wn6wot](../.agents/pm/features/pm-wn6wot.toon), [pm-91xeam](../.agents/pm/features/pm-91xeam.toon)
|
|
3
|
+
Tracker: [pm-2lex4r](../.agents/pm/features/pm-2lex4r.toon), [pm-lyfu7b](../.agents/pm/features/pm-lyfu7b.toon), [pm-wn6wot](../.agents/pm/features/pm-wn6wot.toon), [pm-91xeam](../.agents/pm/features/pm-91xeam.toon), [pm-uhv1m5](../.agents/pm/features/pm-uhv1m5.toon), [pm-m7bb7r](../.agents/pm/features/pm-m7bb7r.toon), [pm-py7qv2](../.agents/pm/issues/pm-py7qv2.toon), [pm-33mjrw](../.agents/pm/issues/pm-33mjrw.toon), [pm-q6n8sj](../.agents/pm/issues/pm-q6n8sj.toon)
|
|
4
4
|
|
|
5
5
|
## Agent Quick Context
|
|
6
6
|
|
|
@@ -22,20 +22,27 @@ The assurance SDK keeps those semantics independent from presentation. Commander
|
|
|
22
22
|
|
|
23
23
|
Measurements support these built-in sources:
|
|
24
24
|
|
|
25
|
-
| Source
|
|
26
|
-
|
|
|
27
|
-
| `items`
|
|
28
|
-
| `dependency_kind` | Count typed relationship edges such as `blocked_by` or `verifies
|
|
29
|
-
| `graph`
|
|
30
|
-
| `validate`
|
|
31
|
-
| `health`
|
|
32
|
-
| `history`
|
|
33
|
-
| `links`
|
|
34
|
-
| `derived`
|
|
35
|
-
| `provider`
|
|
25
|
+
| Source | Purpose |
|
|
26
|
+
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
|
27
|
+
| `items` | Count authoritative full item records matching status, type, tags, an exact metadata field, or a field `state` of `present`/`missing`. |
|
|
28
|
+
| `dependency_kind` | Count typed relationship edges such as `blocked_by` or `verifies`; accepted aliases and canonical spellings measure the same population. |
|
|
29
|
+
| `graph` | Select a numeric or labelled-set field from a public graph SDK result. |
|
|
30
|
+
| `validate` | Select a validator check status or numeric detail. |
|
|
31
|
+
| `health` | Select a health check status, numeric detail, or labelled set. |
|
|
32
|
+
| `history` | Count immutable events by operation, author, harness, or model. |
|
|
33
|
+
| `links` | Count items with present or missing file, test, or documentation evidence. |
|
|
34
|
+
| `derived` | Combine numeric measurements with deterministic arithmetic and cycle detection. |
|
|
35
|
+
| `provider` | Delegate a measurement to an explicitly supplied host/package resolver. |
|
|
36
36
|
|
|
37
37
|
Each measurement may declare `max_cost`. Evaluation fails closed when the total abstract compute units exceed that ceiling. Every result reports units, scanned items, scanned history rows, provider calls, duration, population size, and contributors.
|
|
38
38
|
|
|
39
|
+
One workspace context memoizes identical graph operations and the shared
|
|
40
|
+
validate and health reports for its lifetime. A gate may therefore project many
|
|
41
|
+
fields from one authoritative audit snapshot without multiplying full-workspace
|
|
42
|
+
I/O or allowing concurrent assertions to observe different tracker states.
|
|
43
|
+
|
|
44
|
+
An `items` source with `field` must declare exactly one predicate: `equals` (including an explicit `null`) or `state`. `state: missing` treats an absent property, `null`, an empty string, or an empty array as missing; `state: present` selects the complement. Workspace evaluation loads full item metadata, so `files`, `tests`, and `docs` selectors measure stored evidence rather than a light projection that omitted those collections.
|
|
45
|
+
|
|
39
46
|
Assertions require exactly one polarity:
|
|
40
47
|
|
|
41
48
|
- `ceiling`, `floor`, `equals`, or `zero`
|
|
@@ -84,6 +91,152 @@ pm assurance remove gate release-readiness
|
|
|
84
91
|
|
|
85
92
|
Referenced measurements and assertions cannot be removed. Remove the consuming gate or assertion first.
|
|
86
93
|
|
|
94
|
+
### Presets, derivation, and promotion
|
|
95
|
+
|
|
96
|
+
List the four built-in project shapes, preview one as ordinary declarations, or apply it atomically:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
pm assurance presets
|
|
100
|
+
pm assurance presets software-delivery --owner pm-example
|
|
101
|
+
pm assurance apply software-delivery --owner pm-example \
|
|
102
|
+
--message "Adopt the initial delivery evidence contract"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The preset creates measurements, assertions, and a gate in one audited transaction. Reapplying the same bundle is idempotent; an existing divergent id is refused rather than overwritten. The available shapes are `software-delivery`, `research`, `agent-evaluation`, and `operations`.
|
|
106
|
+
|
|
107
|
+
Self-derivation observes active items without writing anything. Each proposal reports its active scope, population size, and observed missing-evidence ceiling. Persistence requires the explicit `--apply` flag:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
pm assurance derive --owner pm-example
|
|
111
|
+
pm assurance derive --owner pm-example --apply \
|
|
112
|
+
--message "Accept the observed evidence baseline"
|
|
113
|
+
pm assurance promote derived-active-missing-tests-ceiling --enforcement warn
|
|
114
|
+
pm assurance promote derived-active-missing-tests-ceiling --enforcement block
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Derived assertions start at `observe`. Promotion is exactly one step (`observe` to `warn`, then `warn` to `block`) and each transition is an ordinary audited declaration mutation. There is no automatic promotion and no privileged preset execution path.
|
|
118
|
+
|
|
119
|
+
## Extension Measurement Providers
|
|
120
|
+
|
|
121
|
+
An extension opens the measurement vocabulary through `api.registerAssuranceMeasurementProvider`. The registration declares stable keys, parameter types, a coarse `low`/`medium`/`high` cost class, network use, a host timeout, and a resolver. It requires the `services` capability; a network provider must also declare `permissions.network: true` in `manifest.json`.
|
|
122
|
+
|
|
123
|
+
This code-quality provider measures a local report without changing assertion or gate semantics:
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import { readFile } from "node:fs/promises";
|
|
127
|
+
import { defineExtension } from "@unbrained/pm-cli/sdk";
|
|
128
|
+
|
|
129
|
+
export default defineExtension({
|
|
130
|
+
activate(api) {
|
|
131
|
+
api.registerAssuranceMeasurementProvider({
|
|
132
|
+
id: "coverage",
|
|
133
|
+
keys: {
|
|
134
|
+
lines: {
|
|
135
|
+
value_type: "number",
|
|
136
|
+
parameters: { report: { type: "string", required: true } },
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
cost_class: "low",
|
|
140
|
+
network: false,
|
|
141
|
+
timeout_ms: 2_000,
|
|
142
|
+
async resolve({ parameters }) {
|
|
143
|
+
const report = JSON.parse(
|
|
144
|
+
await readFile(String(parameters.report), "utf8"),
|
|
145
|
+
) as {
|
|
146
|
+
total: { lines: { pct: number } };
|
|
147
|
+
};
|
|
148
|
+
return { value: report.total.lines.pct, population_size: 1, cost: 1 };
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
An evaluation package can expose episode reward on the same surface:
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
api.registerAssuranceMeasurementProvider({
|
|
159
|
+
id: "agent-eval",
|
|
160
|
+
keys: {
|
|
161
|
+
"mean-reward": {
|
|
162
|
+
value_type: "number",
|
|
163
|
+
parameters: { suite: { type: "string", required: true } },
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
cost_class: "high",
|
|
167
|
+
network: false,
|
|
168
|
+
timeout_ms: 120_000,
|
|
169
|
+
async resolve({ parameters }) {
|
|
170
|
+
const result = await runFrozenEvaluation(String(parameters.suite));
|
|
171
|
+
return {
|
|
172
|
+
value: result.meanReward,
|
|
173
|
+
population_size: result.episodes,
|
|
174
|
+
cost: result.steps,
|
|
175
|
+
contributors: result.regressedScenarioIds,
|
|
176
|
+
};
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
An external registry provider declares its network dependency explicitly:
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
api.registerAssuranceMeasurementProvider({
|
|
185
|
+
id: "npm-registry",
|
|
186
|
+
keys: {
|
|
187
|
+
"dist-tag-count": {
|
|
188
|
+
value_type: "number",
|
|
189
|
+
parameters: { package: { type: "string", required: true } },
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
cost_class: "medium",
|
|
193
|
+
network: true,
|
|
194
|
+
timeout_ms: 5_000,
|
|
195
|
+
async resolve({ parameters }) {
|
|
196
|
+
const name = encodeURIComponent(String(parameters.package));
|
|
197
|
+
const response = await fetch(
|
|
198
|
+
`https://registry.npmjs.org/-/package/${name}/dist-tags`,
|
|
199
|
+
);
|
|
200
|
+
if (!response.ok) throw new Error(`registry returned ${response.status}`);
|
|
201
|
+
const tags = (await response.json()) as Record<string, string>;
|
|
202
|
+
return { value: Object.keys(tags).length, population_size: 1, cost: 10 };
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
The corresponding measurement is ordinary registry data:
|
|
208
|
+
|
|
209
|
+
```json
|
|
210
|
+
{
|
|
211
|
+
"id": "published-tag-count",
|
|
212
|
+
"source": {
|
|
213
|
+
"kind": "provider",
|
|
214
|
+
"provider": "npm-registry",
|
|
215
|
+
"key": "dist-tag-count",
|
|
216
|
+
"parameters": { "package": "@example/tool" }
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
A provider-backed gate must opt into every provider and each trigger's execution envelope. Omission refuses provider execution:
|
|
222
|
+
|
|
223
|
+
```json
|
|
224
|
+
{
|
|
225
|
+
"id": "release-readiness",
|
|
226
|
+
"assertion_ids": ["published-tag-count-ceiling"],
|
|
227
|
+
"triggers": ["ci", "scheduled"],
|
|
228
|
+
"provider_policy": {
|
|
229
|
+
"allowed_providers": ["npm-registry"],
|
|
230
|
+
"triggers": {
|
|
231
|
+
"ci": { "max_cost_class": "low", "allow_network": false },
|
|
232
|
+
"scheduled": { "max_cost_class": "medium", "allow_network": true }
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Before invocation the host verifies the provider allow-list, declared cost class, and network capability for the active trigger. It then validates key parameters and result shape, enforces the registered timeout, and charges the returned cost through the existing measurement ceiling. Extension tests must bind `PM_PATH` and `PM_GLOBAL_PATH` to temporary roots; never point provider fixtures at the repository tracker or a live service.
|
|
239
|
+
|
|
87
240
|
## SDK and MCP
|
|
88
241
|
|
|
89
242
|
The reusable client exposes the same action grammar:
|
|
@@ -101,9 +254,9 @@ await pm.assurance({
|
|
|
101
254
|
});
|
|
102
255
|
```
|
|
103
256
|
|
|
104
|
-
For direct host composition, use `evaluateMeasurement`, `evaluateAssuranceGate`, `createAssuranceWorkspaceContext`, and the audited declaration/verdict helpers exported from `@unbrained/pm-cli/sdk`.
|
|
257
|
+
For direct host composition, use `evaluateMeasurement`, `evaluateAssuranceGate`, `createAssuranceWorkspaceContext`, the preset/derivation helpers, and the audited declaration/verdict helpers exported from `@unbrained/pm-cli/sdk`. Active extension registrations are discovered automatically. Embedding hosts may additionally pass stable resolver ids and matching `provider_capabilities` to `createAssuranceWorkspaceContext`; an absent resolver or capability fails loudly. The core evaluator bounds concurrent assertions and expression operands, and workspace history loading uses bounded concurrency; item-only callers can explicitly skip history and Git identity resolution.
|
|
105
258
|
|
|
106
|
-
Generic SDK and MCP dispatch use `action: "assurance"` with `subcommand` set to `list`, `show`, `put`, `remove`, `run`, or `
|
|
259
|
+
Generic SDK and MCP dispatch use `action: "assurance"` with `subcommand` set to `list`, `show`, `put`, `remove`, `run`, `verdicts`, `presets`, `apply`, `derive`, or `promote`. Discover the current machine contract instead of copying parameter lists:
|
|
107
260
|
|
|
108
261
|
```bash
|
|
109
262
|
pm contracts --action assurance --schema-only --json
|
|
@@ -117,10 +270,13 @@ A gate emits one object containing:
|
|
|
117
270
|
- gate id, evaluated tree, trigger, timestamp, and dry-run status;
|
|
118
271
|
- overall `pass`, `warn`, or `block` plus stable exit code;
|
|
119
272
|
- every assertion's measurement, scope, population, observed value, structured bound, signed distance, enforcement, negative-control proof, cost, and contributors;
|
|
273
|
+
- every assertion's `measurement_definition_fingerprint`, a SHA-256 identity for the exact declaration that produced the observation;
|
|
120
274
|
- an aggregate compute receipt.
|
|
121
275
|
|
|
122
276
|
Dry runs never write history. Non-dry verdicts are immutable workspace audit events and remain queryable after ordinary registry changes. Verdict reads return newest entries first and default to a bounded result; use `--limit` to select up to 1,000 matching records. A blocking verdict exits non-zero; warnings and observations remain successful while preserving their failed assertion rows.
|
|
123
277
|
|
|
278
|
+
Verdicts persisted before definition fingerprints were introduced remain readable and are identifiable by the absence of `measurement_definition_fingerprint`. Registry mutations and verdict writes use the same explicit-author, configured-author, and detected-harness precedence as other SDK mutations; they do not manufacture an `unknown` author when a harness identity is available.
|
|
279
|
+
|
|
124
280
|
## Safety and Evolution
|
|
125
281
|
|
|
126
282
|
- Use stable lowercase ids; prose belongs in descriptions and mutation messages.
|
package/docs/COMMANDS.md
CHANGED
|
@@ -19,7 +19,9 @@ pm contracts --command <command> --flags-only --json
|
|
|
19
19
|
- Use `pm contracts --summary --json` for the cheapest command map, then narrow with command-scoped contracts.
|
|
20
20
|
- Every mutation writes history.
|
|
21
21
|
|
|
22
|
-
Tracked documentation work: [pm-u9d0](../.agents/pm/epics/pm-u9d0.toon)
|
|
22
|
+
Tracked documentation work: [pm-u9d0](../.agents/pm/epics/pm-u9d0.toon),
|
|
23
|
+
[pm-7nqo6b](../.agents/pm/issues/pm-7nqo6b.toon), and
|
|
24
|
+
[pm-j1r8gl](../.agents/pm/issues/pm-j1r8gl.toon).
|
|
23
25
|
|
|
24
26
|
## Command Families
|
|
25
27
|
|
|
@@ -941,17 +943,25 @@ pm history-repair <id> --dry-run
|
|
|
941
943
|
pm history-repair <id> --message "re-anchor legacy drift"
|
|
942
944
|
pm history-repair --all --dry-run
|
|
943
945
|
pm history-repair --all --message "bulk re-anchor drifted streams"
|
|
944
|
-
pm activity
|
|
946
|
+
pm activity # item digest for the last 24 hours
|
|
947
|
+
pm activity --raw --id <id> --limit 50
|
|
945
948
|
pm activity --full --id <id> --limit 50
|
|
946
949
|
pm activity --full --unbounded
|
|
947
950
|
pm restore <id> <timestamp-or-version>
|
|
948
951
|
```
|
|
949
952
|
|
|
950
953
|
History is append-only. Restore appends a new restore event instead of rewriting old history.
|
|
951
|
-
Bare `pm activity` is
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
954
|
+
Bare `pm activity` is an item-centric digest for the last 24 hours, bounded to
|
|
955
|
+
15 most-recently-touched items. Each row joins current `id`, `type`, `status`,
|
|
956
|
+
and title with the matching event count, first/last timestamps, and a bounded
|
|
957
|
+
operation histogram. `activity_summary` states the effective window plus event,
|
|
958
|
+
item, author, and operation counts, so an empty digest is distinguishable from
|
|
959
|
+
a bounded one. Use `--raw` for the legacy compact per-event stream, `--compact`
|
|
960
|
+
as its compatibility spelling, `--full` for events with patch payloads, or
|
|
961
|
+
`--provenance` for patch-free provenance rows. Every mode reports total and
|
|
962
|
+
omitted row counts plus the applied bound. Use `--limit` for a deliberate cap,
|
|
963
|
+
or `--unbounded` for an explicitly unlimited read; the two flags are mutually
|
|
964
|
+
exclusive.
|
|
955
965
|
Workspace-scoped mutations to settings, schema, profiles, init state, and
|
|
956
966
|
extension/package activation are recorded in
|
|
957
967
|
`.agents/pm/history/_workspace.jsonl` using the same patch/hash format.
|
|
@@ -962,10 +972,21 @@ workspace auditing and is created on the first audited singleton mutation.
|
|
|
962
972
|
|
|
963
973
|
`--diff` replays the history chain and emits, per entry, a `changes` array of `{ field, before, after }` field-level value transitions (alongside the `changed_fields` name list) — so you can see exactly what each field changed from and to without comparing snapshots. It is independent of the compact/full projection. `--field <name>` narrows the diff to a single field's transitions (implying `--diff`), answering "when did `<field>` change?" — e.g. `pm history <id> --diff --field status`.
|
|
964
974
|
|
|
965
|
-
`pm stats` reports item and history totals plus
|
|
975
|
+
`pm stats` reports item and history totals plus a screen-sized lifecycle table.
|
|
976
|
+
Every non-empty item type is one row with `total`, `open`, `in_progress`,
|
|
977
|
+
`blocked`, `draft`, `closed`, `canceled`, and `other` counts. Empty registered
|
|
978
|
+
types and statuses are suppressed and their combined count is retained in the
|
|
979
|
+
`omitted_zero_buckets` scalar. The default TOON projection is gated at no more
|
|
980
|
+
than 22 lines on the representative release fixture. Add `--include-empty` to
|
|
981
|
+
restore every zero-filled type and status for schema-governance dashboards.
|
|
982
|
+
Add `--storage` for aggregate history-stream metrics — `total_streams`,
|
|
983
|
+
`total_lines`, `total_bytes`, the top streams by size (`largest_by_bytes`) and
|
|
984
|
+
by depth (`deepest_by_lines`), and the global `oldest_entry`/`newest_entry` — to
|
|
985
|
+
decide when to compact or redact streams and to plan storage:
|
|
966
986
|
|
|
967
987
|
```bash
|
|
968
988
|
pm stats
|
|
989
|
+
pm stats --include-empty
|
|
969
990
|
pm stats --storage --json
|
|
970
991
|
pm stats --metadata-coverage --json
|
|
971
992
|
pm stats --field-utilization --json
|
|
@@ -973,7 +994,7 @@ pm stats --by-assignee --by-priority
|
|
|
973
994
|
pm stats --by-tag --tag-prefix domain: --json
|
|
974
995
|
```
|
|
975
996
|
|
|
976
|
-
For governance dashboards, `--metadata-coverage` adds a `metadata_coverage` block reporting per-field `present`/`applicable`/`percent` for `acceptance_criteria`, `estimated_minutes`, `resolution`, `tags`, and `parent` — overall and `by_type` (resolution coverage is scoped to terminal items, its only applicable population). `--field-utilization` adds a `field_utilization` block reporting `present`/`total`/`percent` for each content field (`notes`, `learnings`, `files`, `docs`, `tests`, `comments`, `deps`, `body`, `linked_command`) across all items, so under-documented content dimensions are visible at a glance and pair naturally with the `--has-*`/`--no-*` list filters for drill-down. `--by-assignee`, `--by-tag`, and `--by-priority` add a `breakdowns` block with lifecycle-bucketed rows (`open`/`in_progress`/`blocked`/`draft`/`closed`/`canceled`/`other` + `total`) per group; blank keys render an explicit `(unassigned)`/`(untagged)` label. `--by-tag` accepts `--tag-prefix` to restrict counting to a tag namespace (for example `domain:`). All of these sections are gated behind their flags so the default `pm stats`
|
|
997
|
+
For governance dashboards, `--metadata-coverage` adds a `metadata_coverage` block reporting per-field `present`/`applicable`/`percent` for `acceptance_criteria`, `estimated_minutes`, `resolution`, `tags`, and `parent` — overall and `by_type` (resolution coverage is scoped to terminal items, its only applicable population). `--field-utilization` adds a `field_utilization` block reporting `present`/`total`/`percent` for each content field (`notes`, `learnings`, `files`, `docs`, `tests`, `comments`, `deps`, `body`, `linked_command`) across all items, so under-documented content dimensions are visible at a glance and pair naturally with the `--has-*`/`--no-*` list filters for drill-down. `--by-assignee`, `--by-tag`, and `--by-priority` add a `breakdowns` block with lifecycle-bucketed rows (`open`/`in_progress`/`blocked`/`draft`/`closed`/`canceled`/`other` + `total`) per group; blank keys render an explicit `(unassigned)`/`(untagged)` label. `--by-tag` accepts `--tag-prefix` to restrict counting to a tag namespace (for example `domain:`). All of these sections are gated behind their flags so the default `pm stats` remains readable at first glance.
|
|
977
998
|
`history-redact` rewrites matching history payloads deterministically, recomputes hash chains, and appends an auditable `history_redact` marker entry when changes are applied. Its result reports only `literal_count`, `regex_count`, `total_count`, and whether the default replacement was selected; literal values, regex source text, and replacement text are never echoed in CLI, SDK, MCP, recovery, profile, or telemetry output. Treat regex text as sensitive input because it can contain the exact material being removed.
|
|
978
999
|
`history-compact` rewrites long streams into a synthetic checkpoint baseline plus a retained tail (`--before` accepts a 1-based version or ISO timestamp), re-anchors hashes, verifies integrity, and appends an auditable `history_compact` marker when applied.
|
|
979
1000
|
`history-compact` bulk mode (mutually exclusive with a positional `<id>`) compacts many streams in one audited pass. Select with `--ids <a,b,c>` (an explicit list — used on its own, not combined with the scan selectors below), or a scan: `--all-over <N>` (every stream with more than N entries) and/or a lifecycle filter `--closed` (terminal items only) or `--all-streams` (every stream). `--closed` and `--all-streams` are mutually exclusive. `--min-entries <N>` (default 3) skips already-compact streams; when `history.compact_policy` is enabled and `--all-over` is omitted, the policy's `max_entries` becomes the default threshold. `--before` is single-id only and is rejected in bulk mode. Each selected stream runs the same single-item compaction; one failing stream never aborts the rest — the result reports `totals` (`streams_considered`/`selected`/`items_compacted`/`items_skipped`/`items_errored`) plus one row per stream (`compacted`/`skipped` with a `skip_reason`/`errored`), and the command exits non-zero only if any stream errored.
|
package/docs/CONFIGURATION.md
CHANGED
|
@@ -156,6 +156,7 @@ Telemetry is opt-in via `pm config set telemetry-tracking on` (see [Common Setti
|
|
|
156
156
|
| `PM_TELEMETRY_OTEL_DISABLED` | boolean | Disable only OTLP trace-span export; the event queue still flushes. |
|
|
157
157
|
| `PM_TELEMETRY_INLINE_FLUSH` | boolean | Flush the queue and OTLP spans inline instead of dispatching the detached worker. Mainly for tests; normal use relies on the background worker. |
|
|
158
158
|
| `PM_TELEMETRY_SOURCE_CONTEXT` | `user` \| `automation` \| `test` \| `dogfood` | Override the inferred source context recorded on each event. Any other value is ignored and the context is inferred. |
|
|
159
|
+
| `PM_TELEMETRY_HTTP_TIMEOUT_MS` | integer milliseconds | Bound each background event or OTLP request (default `20000`, clamped to `1000`–`25000` to stay below the worker lock TTL). |
|
|
159
160
|
| `PM_TELEMETRY_INGEST_KEY` | string | Sent as the `x-pm-telemetry-key` header on queue flushes; never logged. |
|
|
160
161
|
| `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | URL | OTLP/HTTP traces endpoint for command spans. Takes precedence over the base endpoint. |
|
|
161
162
|
| `OTEL_EXPORTER_OTLP_ENDPOINT` | URL | Base OTLP endpoint; the traces endpoint is derived by appending `/v1/traces`. |
|
|
@@ -164,6 +165,7 @@ Telemetry is opt-in via `pm config set telemetry-tracking on` (see [Common Setti
|
|
|
164
165
|
Interaction rules:
|
|
165
166
|
|
|
166
167
|
- `PM_TELEMETRY_DISABLED` / `PM_NO_TELEMETRY` short-circuit everything, including OTLP export, regardless of the other knobs.
|
|
168
|
+
- `PM_TELEMETRY_HTTP_TIMEOUT_MS` applies only to the detached flush worker in normal use. It covers DNS, each IPv4/IPv6 connection attempt, TLS, and response completion. The upper bound preserves the 60-second worker-lock safety margin across the sequential event and OTLP phases; it does not make foreground commands wait for the network.
|
|
167
169
|
- OTLP span export only happens when telemetry is enabled, `PM_TELEMETRY_OTEL_DISABLED` is off, and a traces endpoint is configured. By default spans are persisted to a bounded queue and exported by the detached, unref'd flush worker so commands exit promptly even when the traces endpoint is unreachable. `PM_TELEMETRY_INLINE_FLUSH=1` is the explicit test-oriented exception that performs the flush inline.
|
|
168
170
|
- `pm health --check-telemetry --json` surfaces flush and OTLP export diagnostics (`pending_otel_spans`, `last_otel_attempt_at`, `last_otel_success_at`, `last_otel_failure_at`, `last_otel_failure_error`) and the active `env_overrides` (including `telemetry_inline_flush` and `telemetry_source_context`) so agents can self-diagnose a stalled endpoint.
|
|
169
171
|
- An explicit `PM_AUTHOR` override adds a privacy-preserving agent-identity dimension to `command_start`/`command_finish` events so overridden invocations can be segmented in dashboards without leaking the raw author string. At `redacted`/`max` capture the events carry `author_context_hash` — the same installation-id-keyed one-way SHA-256 used for `pm_root_hash`/`cwd_hash`, so the same author hashes consistently within an installation but differently across installations. At `minimal` capture only a boolean `has_author_context` is emitted. The raw `PM_AUTHOR` value is never exported.
|
|
@@ -183,6 +185,13 @@ Crash and error diagnostics are reported to Sentry only when telemetry is enable
|
|
|
183
185
|
|
|
184
186
|
> Sentry is hard-disabled under Vitest (`VITEST` / `VITEST_WORKER_ID`), so these knobs are no-ops inside the test suite.
|
|
185
187
|
|
|
188
|
+
Linked commands launched by `pm test --run` default
|
|
189
|
+
`SENTRY_ENVIRONMENT=test`, even when the parent process is classified as
|
|
190
|
+
production. This keeps sandbox failures out of production diagnostics. An
|
|
191
|
+
explicit run-level or per-test `env_set=SENTRY_ENVIRONMENT=<name>` directive
|
|
192
|
+
still overrides the default when a test intentionally targets another
|
|
193
|
+
environment.
|
|
194
|
+
|
|
186
195
|
## Item Storage Format
|
|
187
196
|
|
|
188
197
|
TOON is the default:
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# Dependency-kind contract
|
|
2
2
|
|
|
3
|
-
Tracker: [pm-4020c5](../.agents/pm/issues/pm-4020c5.toon), [pm-jkbqt8](../.agents/pm/issues/pm-jkbqt8.toon)
|
|
3
|
+
Tracker: [pm-4020c5](../.agents/pm/issues/pm-4020c5.toon), [pm-jkbqt8](../.agents/pm/issues/pm-jkbqt8.toon), [pm-q6n8sj](../.agents/pm/issues/pm-q6n8sj.toon)
|
|
4
4
|
|
|
5
5
|
Dependency rows have one canonical stored spelling per relationship meaning. Command inputs remain compatibility-friendly: hyphens normalize to underscores and the aliases below are accepted, but `pm create` and `pm update` persist the canonical kind. Existing historical rows are never rewritten implicitly.
|
|
6
6
|
|
|
7
|
-
| Canonical kind | Accepted legacy aliases
|
|
8
|
-
|
|
|
9
|
-
| `blocked_by`
|
|
10
|
-
| `related`
|
|
11
|
-
| `parent`
|
|
12
|
-
| `child`
|
|
7
|
+
| Canonical kind | Accepted legacy aliases |
|
|
8
|
+
| -------------- | -------------------------------------- |
|
|
9
|
+
| `blocked_by` | `depends_on`, `depends-on` |
|
|
10
|
+
| `related` | `related_to`, `related-to` |
|
|
11
|
+
| `parent` | `child_of`, `child-of`, `epic` |
|
|
12
|
+
| `child` | `parent_child`, `parent-child`, `task` |
|
|
13
13
|
|
|
14
14
|
`epic` and `task` are compatibility aliases, not item types embedded in the relationship ontology. New integrations should use `parent` or `child` and express the work classification through the item `type` field.
|
|
15
15
|
|
|
@@ -26,4 +26,6 @@ Readiness, `pm next`, context blocker summaries, `pm list-blocked`, downstream `
|
|
|
26
26
|
|
|
27
27
|
## Legacy observability
|
|
28
28
|
|
|
29
|
-
`pm deps` returns `legacy_alias_counts` for the workspace. `pm graph audit` returns the same field beside
|
|
29
|
+
`pm deps` returns `legacy_alias_counts` for the workspace. `pm graph audit` returns the same field beside canonical `profile.edges_by_kind` counts, `profile.edge_share_by_kind` composition ratios, and the `semantic_edges`/`semantic_edge_share` context-preservation census. The semantic census counts `discovered_from`, `incident_from`, `supersedes`, and `verifies` over all deduplicated directed edges. Empty objects and zero shares are explicit, not omitted. These diagnostics are read-only; terminal history remains untouched until an explicitly governed migration is requested.
|
|
30
|
+
|
|
31
|
+
Assurance `dependency_kind` measurements canonicalize both the declaration and stored row before comparing. A declaration using `related` and one using the accepted `related_to` alias therefore measure the same edge population; alias debt remains separately observable through `legacy_alias_counts`.
|
package/docs/EXTENSIONS.md
CHANGED
|
@@ -29,6 +29,7 @@ pm install npm:package@1.2.3 --project
|
|
|
29
29
|
pm install https://github.com/org/repo --project
|
|
30
30
|
pm install --github org/repo/path --ref main --project
|
|
31
31
|
```
|
|
32
|
+
|
|
32
33
|
Bundled first-party packages live under `packages/pm-*`:
|
|
33
34
|
|
|
34
35
|
```bash
|
|
@@ -38,6 +39,7 @@ pm install calendar --project
|
|
|
38
39
|
pm install search-advanced --project
|
|
39
40
|
pm install kanban --project
|
|
40
41
|
```
|
|
42
|
+
|
|
41
43
|
`pm install '*'`, `pm install all`, and shell-expanded `pm install *` are normalized to the same bundled install-all request. First-party package aliases come from each package manifest, with a fallback derived from the `packages/pm-*` directory name. A bare bundled alias that also names an installed npm package reports both explicit choices in `source_resolution`; see [Extension Lifecycle Contracts](EXTENSION_LIFECYCLE.md).
|
|
42
44
|
|
|
43
45
|
External registry packages are installed by exact package name. If `npm:<name>` returns a registry 404, JSON error output includes `fallback_candidates` and `next_best_command`; unpublished first-party packages fall back to `pm install --project github.com/unbraind/<name>`. Install results include package-owned `command_paths`, `action_paths`, `contributions`, `command_discovery`, and a light `verification` block covering the target tracker, activation status, registered commands/actions/item types, and health verdict. Agents should consume those fields instead of guessing from the package name or immediately spending another invocation on doctor. A successful activation persists the versioned contribution inventory in `.managed-extensions.json`; subsequent discovery can enumerate command handlers, hooks, parser/renderer targets, schema names, and the other registered surfaces without importing the package module. A failed runtime activation returns `ok: false`, `activated: false`, a non-zero CLI exit, and actionable diagnostics; missing SDK resolution adds an explicit dependency recovery step. Local installs are containment-safe when the extension destination is nested inside the source checkout: pm stages the package outside the source and prunes the destination, `.agents`, `node_modules`, and install-backup directories before copying, so reinstalling cannot recursively copy tracker history, host dependencies, or prior backups.
|
|
@@ -52,6 +54,7 @@ pm install npm:pm-github --project
|
|
|
52
54
|
pm package doctor --project --detail deep --trace
|
|
53
55
|
pm github validate --repo owner/repo
|
|
54
56
|
```
|
|
57
|
+
|
|
55
58
|
For `pm-github`, run `pm github validate --repo owner/repo` before mutating commands; write paths require `GITHUB_TOKEN`/`GH_TOKEN` or `gh auth login`.
|
|
56
59
|
|
|
57
60
|
For ecosystem maintenance, use the reusable external package smoke harness after building `dist/`:
|
|
@@ -132,7 +135,11 @@ Extensions are authored **and loaded** as TypeScript (ADR [pm-2c28](../.agents/p
|
|
|
132
135
|
"process_spawn": false
|
|
133
136
|
},
|
|
134
137
|
"capabilities": ["commands"],
|
|
135
|
-
"contributions": {
|
|
138
|
+
"contributions": {
|
|
139
|
+
"schema_version": 1,
|
|
140
|
+
"commands": ["hello"],
|
|
141
|
+
"command_handlers": ["hello"]
|
|
142
|
+
},
|
|
136
143
|
"activation": { "commands": ["hello"] }
|
|
137
144
|
}
|
|
138
145
|
```
|
|
@@ -286,11 +293,9 @@ Doctor JSON also includes `triage.collision_plan` with grouped surfaces, ranked
|
|
|
286
293
|
## Runtime APIs
|
|
287
294
|
|
|
288
295
|
Use the public SDK barrel. Do not deep-import from `src/core` or `dist/core`.
|
|
289
|
-
|
|
290
296
|
```ts
|
|
291
297
|
import { defineExtension } from "@unbrained/pm-cli/sdk";
|
|
292
298
|
```
|
|
293
|
-
|
|
294
299
|
Common APIs:
|
|
295
300
|
|
|
296
301
|
- `api.extension` is a read-only identity (`name`, `layer`, `version`, `capabilities`, `pm_min_version?`, `pm_max_version?`, `source_package?`) for self-identifying logs and version gating without re-reading the manifest.
|
|
@@ -302,6 +307,7 @@ Common APIs:
|
|
|
302
307
|
- `api.registerRelationshipKinds(definitions)` adds validated graph semantics. Definitions declare direction, inverse spelling, ordering/precedence, hierarchy, cardinality, lifecycle, aliases, payload schema, compatibility version, and self-edge policy. Active definitions are merged into native CLI, MCP, and SDK workspace graph assembly. Requires the `schema` capability and is governed by the `schema.relationshipkinds` policy surface.
|
|
303
308
|
- `api.registerMigration(definition)` adds schema migrations.
|
|
304
309
|
- `api.registerProfile(profile)` contributes a project profile — a declarative archetype bundling item types, statuses, fields, per-type workflows, config, templates, and package recommendations. Once active it resolves by name through `pm profile list/show/apply` alongside the core `agile`/`ops`/`research` archetypes (built-in names are reserved; a colliding registration is ignored with a warning). Requires the `schema` capability.
|
|
310
|
+
- `api.registerAssuranceMeasurementProvider(provider)` contributes typed measurements to assurance. It requires `services`; network providers also require manifest `permissions.network: true`. Gates allow providers and cost/network limits per trigger. See [Project Assurance Primitives](ASSURANCE.md#extension-measurement-providers) for examples.
|
|
305
311
|
- `api.registerService("output_format", handler)` customizes output formatting through the service override API. Use `handleServiceOverride(result)` to claim a payload and return the scaffold-compatible literal `{ handled: false }` (or `declineServiceOverride()`) for commands the extension does not own. Legacy `null`/`undefined` declines remain supported; returning the original payload is now an unambiguous handled result.
|
|
306
312
|
- `api.registerRenderer("toon" | "json", renderer, ownership?)` adds format-specific renderers. Scope ownership with `commands` and/or a `resultDiscriminator`; the host checks both before invoking the renderer and falls back to native rendering for unrelated output. The legacy unscoped callback remains supported, but doctor warns because package ownership cannot be proven statically.
|
|
307
313
|
- `suppressHostOutput(result?)` from `@unbrained/pm-cli/sdk` marks commands that already wrote output, preventing a second CLI payload while retaining the optional result for hooks, telemetry, and embedded hosts.
|
|
@@ -312,15 +318,8 @@ Common APIs:
|
|
|
312
318
|
- Registered command, importer, and exporter handlers receive `context.sdk`, a host-bound service bundle containing a native-action `PmClient`, `getItemAt`, and `openRelationshipEventStore`, alongside portable workspace coordinates. The client reuses the already-active extension schema context without recursively loading extensions, so package commands and data adapters can compose core lifecycle operations safely in CLI and SDK hosts.
|
|
313
319
|
- An optional module-level `deactivate()` export (VS Code-style) is invoked by the host on shutdown/reload — including by the long-running MCP server between native-action requests — to close connections, clear timers, and release resources opened during `activate`. Teardown is best-effort and timeout-bounded by default so it does not block other extensions, except when a host explicitly disables waiting limits with `deactivate_timeout_ms: 0` or `Infinity`, which can wait indefinitely for a hanging `deactivate()` hook.
|
|
314
320
|
|
|
315
|
-
The bundled `pm-lifecycle-hooks` package is the hook exemplar: it declares only
|
|
316
|
-
`
|
|
317
|
-
safe lifecycle pattern without changing command output.
|
|
318
|
-
|
|
319
|
-
If a package calls a `register*` API without declaring the required manifest
|
|
320
|
-
capability, `pm package doctor --project --detail deep --trace` reports
|
|
321
|
-
`extension_capability_missing:<name>:<capability>` and shows the exact capability
|
|
322
|
-
to add before publishing.
|
|
323
|
-
|
|
321
|
+
The bundled `pm-lifecycle-hooks` package is the hook exemplar: it declares only `hooks` and registers a default-inert `afterCommand` hook so authors can copy a safe lifecycle pattern without changing command output.
|
|
322
|
+
If a package calls a `register*` API without declaring the required manifest capability, `pm package doctor --project --detail deep --trace` reports `extension_capability_missing:<name>:<capability>` and shows the exact capability to add before publishing.
|
|
324
323
|
Inline command flags require both `commands` and `schema` capabilities. Runtime schema changes should be verified with:
|
|
325
324
|
|
|
326
325
|
```bash
|
package/docs/MERGE_SAFETY.md
CHANGED
|
@@ -61,7 +61,7 @@ pm merge install --dry-run --json
|
|
|
61
61
|
| 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. |
|
|
62
62
|
| 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. |
|
|
63
63
|
|
|
64
|
-
When both sides change the same item scalar differently, the driver writes the same stable value regardless of which branch Git labels ours or theirs, but exits nonzero. JSON leaf conflicts retain the explicit preferred-side policy. Git keeps either path conflicted so a human or coordinating agent must review the discarded value and explicitly `git add` the resolution.
|
|
64
|
+
When both sides change the same item scalar differently, the driver writes the same stable value regardless of which branch Git labels ours or theirs, but exits nonzero. Item results and receipts expose the caller's `requested_preference`; the per-decision `retained` and `discarded` values or hashes are authoritative because stable value order can retain either side. Readers normalize the legacy receipt key `preferred`, while new receipts no longer emit it. JSON leaf conflicts retain the explicit preferred-side policy. Git keeps either path conflicted so a human or coordinating agent must review the discarded value and explicitly `git add` the resolution. This correction is tracked by [pm-qckpnq](../.agents/pm/issues/pm-qckpnq.toon).
|
|
65
65
|
|
|
66
66
|
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).
|
|
67
67
|
|
|
@@ -133,6 +133,8 @@ pm merge reconcile --dry-run --json
|
|
|
133
133
|
|
|
134
134
|
`history-repair` records the reconciliation patch and classifies its changed fields against the final item. Append-only collection unions and deterministic reordering are reported as preserved context without a data-loss warning. Fields whose replayed values are actually removed or replaced remain loud with discarded event authors/operations and recovery guidance. Re-apply any intended losing mutation as a normal `pm update` so it remains explicit and auditable.
|
|
135
135
|
|
|
136
|
+
History events now declare an item-hash epoch. The current epoch preserves linked-test insertion order; unversioned streams are verified against both the legacy sorted-test canonicalization and the order-preserving canonicalization. An unknown explicit epoch is reported as `unsupported_item_hash_version` and repair refuses to guess. This keeps version incompatibility distinct from item corruption and is tracked by [pm-2htk4p](../.agents/pm/issues/pm-2htk4p.toon).
|
|
137
|
+
|
|
136
138
|
## Delete versus modify policy
|
|
137
139
|
|
|
138
140
|
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:
|
|
@@ -12,7 +12,10 @@ cursor-chain amortization are tracked by
|
|
|
12
12
|
[pm-yekkvt](../.agents/pm/issues/pm-yekkvt.toon), and
|
|
13
13
|
[pm-sf31yl](../.agents/pm/issues/pm-sf31yl.toon). Trustworthy collection
|
|
14
14
|
selectors are tracked by
|
|
15
|
-
[pm-x710qm](../.agents/pm/issues/pm-x710qm.toon).
|
|
15
|
+
[pm-x710qm](../.agents/pm/issues/pm-x710qm.toon). Default contract suppression
|
|
16
|
+
and canonical TOON tables are tracked by
|
|
17
|
+
[pm-gjjurs](../.agents/pm/issues/pm-gjjurs.toon) and
|
|
18
|
+
[pm-5y05kq](../.agents/pm/issues/pm-5y05kq.toon).
|
|
16
19
|
|
|
17
20
|
## Agent Quick Context
|
|
18
21
|
|
|
@@ -38,12 +41,13 @@ explicit receipt with `has_omissions: false`,
|
|
|
38
41
|
|
|
39
42
|
Mutually exclusive output modes emit only their active row collection:
|
|
40
43
|
|
|
41
|
-
| Command mode | Active row key
|
|
42
|
-
| --------------------------- |
|
|
43
|
-
| `activity
|
|
44
|
-
| `activity --
|
|
45
|
-
| `
|
|
46
|
-
| `history
|
|
44
|
+
| Command mode | Active row key | Withheld group | Restore |
|
|
45
|
+
| --------------------------- | --------------------- | -------------- | ---------------- |
|
|
46
|
+
| `activity` (digest default) | `activity_digest` | `event_rows` | `--raw` |
|
|
47
|
+
| `activity --raw/--compact` | `compact_activity` | `provenance` | `--full` |
|
|
48
|
+
| `activity --full` | `activity` | none | already complete |
|
|
49
|
+
| `history` (compact default) | `compact_history` | `raw_history` | `--full` |
|
|
50
|
+
| `history --full` | `history` | none | already complete |
|
|
47
51
|
|
|
48
52
|
Inactive row keys are omitted, not zero-filled. This makes a wrong parser loud:
|
|
49
53
|
reading `.activity` from compact activity now yields a missing key instead of a
|
|
@@ -57,8 +61,11 @@ integrations and built-in output cannot drift independently.
|
|
|
57
61
|
|
|
58
62
|
## Universal Read Rows
|
|
59
63
|
|
|
60
|
-
Core read results expose
|
|
61
|
-
|
|
64
|
+
Core read results expose `row_contract` only when callers request
|
|
65
|
+
`--output-row-contract` / `outputRowContract: true`. Keeping discovery metadata
|
|
66
|
+
off by default makes ordinary reads pay for project data rather than repeating
|
|
67
|
+
the same selector declaration. The explicit contract remains available whether
|
|
68
|
+
or not the current page has rows:
|
|
62
69
|
|
|
63
70
|
```json
|
|
64
71
|
{
|
|
@@ -67,7 +74,8 @@ rows:
|
|
|
67
74
|
"row_kind": "collection",
|
|
68
75
|
"row_keys": ["items"],
|
|
69
76
|
"fields": "supported",
|
|
70
|
-
"jq_selector": ".row_contract.row_keys[] as $key | getpath($key | split(\".\")) | if type == \"array\" then .[] else if type == \"object\" then to_entries[] else empty end end"
|
|
77
|
+
"jq_selector": ".row_contract.row_keys[] as $key | getpath($key | split(\".\")) | if type == \"array\" then .[] else if type == \"object\" then to_entries[] else empty end end",
|
|
78
|
+
"toon_encoding": "tabular_when_uniform"
|
|
71
79
|
}
|
|
72
80
|
}
|
|
73
81
|
```
|
|
@@ -80,7 +88,12 @@ collections declare every active dot-delimited path. This keeps
|
|
|
80
88
|
nested dependency graph and relationship-context rows addressable as
|
|
81
89
|
`graph.nodes`, `graph.edges`, `context.nodes`, and `context.edges` without
|
|
82
90
|
duplicating them at the envelope root. Array collections produce their
|
|
83
|
-
elements; object maps
|
|
91
|
+
elements; object maps produce jq `to_entries` rows.
|
|
92
|
+
`toon_encoding: "tabular_when_uniform"` declares that an array of flat objects
|
|
93
|
+
with one shared key set renders as a length-marked TOON table; mixed, nested,
|
|
94
|
+
or heterogeneous arrays retain the expanded representation. Quoted,
|
|
95
|
+
separator-bearing, and multiline values use the canonical TOON encoder and
|
|
96
|
+
round-trip through the strict decoder.
|
|
84
97
|
Commands without a row collection, including a dependency tree or leaf `get`,
|
|
85
98
|
declare `row_kind: "none"`, an empty `row_keys` array, and omit `jq_selector`.
|
|
86
99
|
The absence is therefore distinguishable from a legitimate empty collection.
|
|
@@ -94,8 +107,8 @@ publish a row contract.
|
|
|
94
107
|
SDK and package authors can import `PM_READ_ROW_CONTRACTS`,
|
|
95
108
|
`PM_READ_ROW_JQ_SELECTOR`, and `resolveReadRowContract` from
|
|
96
109
|
`@unbrained/pm-cli/sdk`. Existing package declarations are preserved only
|
|
97
|
-
when `command`, `row_kind`, `row_keys`, `fields`,
|
|
98
|
-
`jq_selector` form a structurally valid row contract; malformed declarations
|
|
110
|
+
when `command`, `row_kind`, `row_keys`, `fields`, the conditional
|
|
111
|
+
`jq_selector`, and any supplied `toon_encoding` form a structurally valid row contract; malformed declarations
|
|
99
112
|
are replaced by the canonical built-in contract when one applies.
|
|
100
113
|
|
|
101
114
|
## Self-Describing SDK Projections
|
package/docs/README.md
CHANGED
|
@@ -54,7 +54,9 @@ pm guide release --json
|
|
|
54
54
|
- [SDK Agent Session and Episode Context](SDK_AGENT_SESSION_CONTEXT.md) - inherited role/topic context, cross-process episode identity, and deterministic history grouping.
|
|
55
55
|
- [Improvement Ledger and History Analytics](IMPROVEMENT_ANALYTICS.md) - audited quantitative observations, live provenance coverage, and bounded observational fleet outcomes.
|
|
56
56
|
- [Project Assurance Primitives](ASSURANCE.md) - SDK-owned measurements, assertions, lifecycle gates, cost receipts, and durable verdict history shared by CLI and MCP.
|
|
57
|
+
- [Trustworthy Context and Evidence Contracts](TRUSTWORTHY_CONTEXT_EVIDENCE.md) - full-record assurance, graph composition, boolean health rows, lossless linked-test removal, and role-labelled recovery.
|
|
57
58
|
- [SDK Evidence Traceability and Integrity](SDK_EVIDENCE_TRACEABILITY.md) - reverse source-to-item lookup, atomic evidence replacement, no-op history, linked-test collision classification, and telemetry drain receipts.
|
|
59
|
+
- [SDK Context and Evidence Contracts](SDK_CONTEXT_EVIDENCE_CONTRACTS.md) - material omission receipts, scoped preflight activation, truthful merge preference, claim-race classification, and versioned history hashes.
|
|
58
60
|
- [Reproducible Workspaces and Snapshots](REPRODUCIBLE_WORKSPACES.md) - deterministic SDK recipes and content-addressed authoritative tracker restore points.
|
|
59
61
|
- [Portable Corpus Shapes](CORPUS_SHAPES.md) - versioned SDK populations for realistic benchmarks, evaluations, and package tests.
|
|
60
62
|
- [Agent UX Contracts](AGENT_UX_CONTRACTS.md) - ordering-cycle advisories, graph count units, collision safety, compact context, ownership wording, and recovery behavior.
|
|
@@ -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),
|
|
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-sb0tns](../.agents/pm/issues/pm-sb0tns.toon), and [pm-gjjurs](../.agents/pm/issues/pm-gjjurs.toon).
|
|
4
4
|
|
|
5
5
|
## Agent Quick Context
|
|
6
6
|
|
|
@@ -19,6 +19,10 @@ Row shaping follows each envelope's `row_contract.row_keys`, including
|
|
|
19
19
|
dot-delimited nested arrays and object maps such as `graph.nodes`. Include,
|
|
20
20
|
amount, repeat suppression, and cost compaction therefore operate on the same
|
|
21
21
|
machine-declared rows; they do not rely on command-specific top-level keys.
|
|
22
|
+
The runtime uses that declaration internally on every read but omits the
|
|
23
|
+
repeated metadata from results by default. Request
|
|
24
|
+
`--output-row-contract` / `outputRowContract: true` when a consumer needs the
|
|
25
|
+
row paths, jq selector, and active TOON encoding contract.
|
|
22
26
|
|
|
23
27
|
## Cross-Call Context Sessions
|
|
24
28
|
|
|
@@ -46,6 +50,15 @@ tokens separately when the remaining group allowance is smaller than the
|
|
|
46
50
|
minimum control envelope, plus the accumulated spend, remaining capacity,
|
|
47
51
|
newly served items, and suppressed repeats.
|
|
48
52
|
|
|
53
|
+
The carried served-item set accepts at most 10,000 identities. A receipt always
|
|
54
|
+
preserves identities already present in the supplied state and retains newly
|
|
55
|
+
served identities in deterministic order until that capacity is full. When a
|
|
56
|
+
single read crosses the boundary, `seen_item_overflow_count` reports how many
|
|
57
|
+
new identities were not carried forward; those facts remain in the current
|
|
58
|
+
envelope and may be served in full again on a later read. The emitted
|
|
59
|
+
`next_state` therefore always remains valid input to the next call without
|
|
60
|
+
silently widening the safety bound.
|
|
61
|
+
|
|
49
62
|
Session state is deliberately caller-carried: CLI processes, SDK clients, MCP
|
|
50
63
|
hosts, and packages share the same deterministic primitive without a hidden
|
|
51
64
|
daemon or mutable cache. Validation rejects unknown fields, invalid identifiers,
|
|
@@ -69,12 +82,13 @@ tracker content.
|
|
|
69
82
|
|
|
70
83
|
## Precedence and Compatibility
|
|
71
84
|
|
|
72
|
-
Resolution is deterministic: canonical controls win over command-local compatibility options, which win over intent defaults, which win over command defaults. Existing options such as `--fields`, `--limit`, `--token-budget`, `--format`, `--brief`, and `--full` remain accepted. Contract output marks them as hidden compatibility aliases and supplies a migration hint; traversal, cursor, side-effect, and streaming controls instead receive an explicit behavior-preservation hint because a static output control cannot replace their semantics. Callers that omit the
|
|
85
|
+
Resolution is deterministic: canonical controls win over command-local compatibility options, which win over intent defaults, which win over command defaults. Existing options such as `--fields`, `--limit`, `--token-budget`, `--format`, `--brief`, and `--full` remain accepted. Contract output marks them as hidden compatibility aliases and supplies a migration hint; traversal, cursor, side-effect, and streaming controls instead receive an explicit behavior-preservation hint because a static output control cannot replace their semantics. Callers that omit the four shaping dimensions retain the established data projection; the one intentional envelope correction is that repeated `row_contract` metadata is now opt-in.
|
|
73
86
|
|
|
74
87
|
```bash
|
|
75
88
|
pm list-open --output-include id,title,status --output-limit 10
|
|
76
89
|
pm context --for orient --output-budget 900 --output-format toon
|
|
77
90
|
pm search "runtime contracts" --output-limit 5 --output-format json
|
|
91
|
+
pm stats --output-row-contract
|
|
78
92
|
pm contracts --full --json
|
|
79
93
|
```
|
|
80
94
|
|
|
@@ -93,6 +107,7 @@ const result = await pm.list({
|
|
|
93
107
|
outputInclude: "id,title,status",
|
|
94
108
|
outputLimit: 10,
|
|
95
109
|
outputBudget: 800,
|
|
110
|
+
outputRowContract: true,
|
|
96
111
|
outputSession: {
|
|
97
112
|
version: 1,
|
|
98
113
|
id: "orientation",
|