@unbrained/pm-cli 2026.8.21 → 2026.8.23
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/error-guidance.d.ts +22 -4
- package/dist/cli/error-guidance.js +73 -16
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.js +51 -9
- package/dist/cli/register-mutation.js +6 -6
- package/dist/cli/register-operations.d.ts +73 -0
- package/dist/cli/register-operations.js +39 -14
- package/dist/cli/register-setup.js +3 -3
- package/dist/cli/schema-registration-helpers.d.ts +8 -1
- package/dist/cli/schema-registration-helpers.js +14 -5
- package/dist/cli-bundle/bundle-manifest.json +149 -149
- package/dist/cli-bundle/chunks/chunk-3ENVHX6C.js +36 -0
- package/dist/cli-bundle/chunks/{chunk-LOVTQ52Z.js → chunk-DW2CGEMU.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-EG6CLDZT.js +5 -0
- package/dist/cli-bundle/chunks/{chunk-LARJJ3RK.js → chunk-F3AI2JFL.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-N3DSV4CH.js → chunk-HWZ6CELB.js} +8 -8
- package/dist/cli-bundle/chunks/chunk-HZBMLSZI.js +201 -0
- package/dist/cli-bundle/chunks/chunk-JB4KZWBF.js +3 -0
- package/dist/cli-bundle/chunks/chunk-KPH73XXJ.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-BKYB45NQ.js → chunk-KXPMB2YL.js} +50 -50
- package/dist/cli-bundle/chunks/{chunk-BUNIEJNE.js → chunk-QDVHNHAQ.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-TFI5V5N2.js +13 -0
- package/dist/cli-bundle/chunks/{register-list-query-F57EWDEF.js → register-list-query-UJB5FMV2.js} +2 -2
- package/dist/cli-bundle/chunks/register-mutation-NX5XE4VX.js +20 -0
- package/dist/cli-bundle/chunks/register-operations-RXIJIYXC.js +2 -0
- package/dist/cli-bundle/chunks/{register-setup-HXU7IZZD.js → register-setup-GFUZEKRE.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-F4YEW5I2.js → chunk-37Z4OEAP.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-3UPTYG44.js +8 -0
- package/dist/cli-bundle/focused-chunks/chunk-5S7E72FY.js +16 -0
- package/dist/cli-bundle/focused-chunks/{chunk-4ERLO7QD.js → chunk-AUFH5H35.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-E7X25GC3.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-FQCSTBWE.js +4 -0
- package/dist/cli-bundle/focused-chunks/{chunk-FH6DYED3.js → chunk-FZS4H32O.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-IFLWKY2R.js +156 -0
- package/dist/cli-bundle/focused-chunks/{chunk-YKBKIEAJ.js → chunk-JOWDB2MH.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-LYVSW5VM.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-MRCNF3U6.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-UZE7XUZK.js → chunk-OFVUGTLJ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-FJ22HNRP.js → chunk-OGLQBL46.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-OY7QAV4Y.js +51 -0
- package/dist/cli-bundle/focused-chunks/chunk-QGFNI65N.js +26 -0
- package/dist/cli-bundle/focused-chunks/{chunk-KDNG7TKQ.js → chunk-R27IDGHD.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-UYRFYCDQ.js +5 -0
- package/dist/cli-bundle/focused-chunks/{chunk-2NIY5NKG.js → chunk-ZHVA42R5.js} +9 -9
- package/dist/cli-bundle/main.js +13 -13
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +2 -2
- package/dist/cli-bundle/sdk-core.js +40 -40
- 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 +33 -32
- 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 +5 -5
- package/dist/core/config/nested-settings.js +8 -2
- package/dist/core/config/positional-value.d.ts +1 -1
- package/dist/core/config/positional-value.js +5 -2
- package/dist/core/extensions/extension-hook-runtime.js +22 -20
- package/dist/core/extensions/extension-types.d.ts +8 -1
- package/dist/core/extensions/extension-types.js +2 -2
- package/dist/core/extensions/loader.js +7 -3
- package/dist/core/extensions/service-ownership.d.ts +8 -0
- package/dist/core/extensions/service-ownership.js +20 -0
- package/dist/core/history/history.js +3 -3
- package/dist/core/item/id.js +20 -5
- package/dist/core/item/item-format.js +81 -2
- package/dist/core/reproducibility/context.d.ts +4 -0
- package/dist/core/reproducibility/context.js +14 -8
- package/dist/core/shared/author.d.ts +55 -1
- package/dist/core/shared/author.js +333 -16
- package/dist/core/shared/constants.js +3 -2
- package/dist/core/shared/errors.d.ts +4 -0
- package/dist/core/shared/errors.js +2 -2
- package/dist/core/store/settings-validator.d.ts +1 -0
- package/dist/core/store/settings-validator.js +6 -3
- package/dist/core/store/settings.js +5 -2
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +30 -9
- package/dist/sdk/agent/identity-config.d.ts +63 -0
- package/dist/sdk/agent/identity-config.js +107 -0
- package/dist/sdk/agent/refusal-corpus-contracts.d.ts +76 -0
- package/dist/sdk/agent/refusal-corpus-contracts.js +194 -0
- package/dist/sdk/agent/refusal-reachability.d.ts +1 -1
- package/dist/sdk/authoring.d.ts +1 -1
- package/dist/sdk/authoring.js +2 -2
- package/dist/sdk/cli-contracts/agent-output-contracts.d.ts +77 -0
- package/dist/sdk/cli-contracts/agent-output-contracts.js +326 -2
- package/dist/sdk/cli-contracts/commander-mutation-options.js +3 -3
- package/dist/sdk/cli-contracts/enum-contracts.d.ts +4 -0
- package/dist/sdk/cli-contracts/enum-contracts.js +9 -2
- package/dist/sdk/cli-contracts/flag-contracts.js +9 -2
- package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +4 -4
- package/dist/sdk/cli-contracts/registration-helpers.js +5 -2
- package/dist/sdk/cli-contracts/runtime-contracts.d.ts +3 -1
- package/dist/sdk/cli-contracts/runtime-contracts.js +4 -3
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +22 -2
- package/dist/sdk/cli-contracts/tool-schema.d.ts +1 -1
- package/dist/sdk/cli-contracts/tool-schema.js +14 -3
- package/dist/sdk/cli-contracts.d.ts +4 -4
- package/dist/sdk/cli-contracts.js +5 -5
- package/dist/sdk/config.d.ts +6 -1
- package/dist/sdk/config.js +119 -14
- package/dist/sdk/context-intent-contracts.js +4 -2
- package/dist/sdk/core-governance.d.ts +1 -1
- package/dist/sdk/core-governance.js +3 -3
- package/dist/sdk/extension/install-sources.d.ts +1 -1
- package/dist/sdk/extension/install-sources.js +6 -3
- package/dist/sdk/extension/output-ownership.d.ts +1 -0
- package/dist/sdk/extension/output-ownership.js +3 -2
- package/dist/sdk/extension/scaffold.js +11 -5
- package/dist/sdk/flag-invocation-contracts.js +4 -2
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +74 -2
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +87 -26
- package/dist/sdk/governance/assurance-action.js +30 -10
- package/dist/sdk/governance/health.d.ts +3 -0
- package/dist/sdk/governance/health.js +39 -7
- package/dist/sdk/governance/hierarchy-validation.d.ts +29 -0
- package/dist/sdk/governance/hierarchy-validation.js +109 -0
- package/dist/sdk/governance/validate.d.ts +3 -9
- package/dist/sdk/governance/validate.js +84 -111
- package/dist/sdk/graph/assembly.d.ts +6 -1
- package/dist/sdk/graph/assembly.js +16 -22
- package/dist/sdk/graph/governance-contracts.d.ts +1 -1
- package/dist/sdk/graph/governance-contracts.js +8 -2
- package/dist/sdk/graph/governance.js +46 -2
- package/dist/sdk/graph/hierarchy-integrity.d.ts +94 -0
- package/dist/sdk/graph/hierarchy-integrity.js +311 -0
- package/dist/sdk/graph/index.d.ts +2 -1
- package/dist/sdk/graph/index.js +3 -2
- package/dist/sdk/graph/remediation.js +32 -2
- package/dist/sdk/graph/run.d.ts +31 -2
- package/dist/sdk/graph/run.js +80 -31
- package/dist/sdk/graph/workspace-relationship-kind-registry.d.ts +8 -0
- package/dist/sdk/graph/workspace-relationship-kind-registry.js +28 -0
- package/dist/sdk/index.d.ts +8 -3
- package/dist/sdk/index.js +9 -4
- package/dist/sdk/item-children.js +21 -8
- package/dist/sdk/lifecycle/create.js +129 -97
- package/dist/sdk/lifecycle/hierarchy-mutation-lock.d.ts +15 -0
- package/dist/sdk/lifecycle/hierarchy-mutation-lock.js +25 -0
- package/dist/sdk/lifecycle/update.d.ts +2 -0
- package/dist/sdk/lifecycle/update.js +174 -84
- package/dist/sdk/merge/three-way.js +105 -26
- package/dist/sdk/query/complete-list.d.ts +3 -3
- package/dist/sdk/query/complete-list.js +46 -3
- package/dist/sdk/query/list.d.ts +4 -3
- package/dist/sdk/query/list.js +89 -49
- package/dist/sdk/read-output-budget.d.ts +21 -0
- package/dist/sdk/read-output-budget.js +39 -2
- package/dist/sdk/read-output-contracts.d.ts +10 -4
- package/dist/sdk/read-output-contracts.js +105 -32
- package/dist/sdk/relationship-context.js +3 -4
- package/dist/sdk/relationships.js +17 -10
- package/dist/sdk/reproducibility/process.d.ts +19 -0
- package/dist/sdk/reproducibility/process.js +88 -0
- package/dist/sdk/runtime-primitives.d.ts +1 -1
- package/dist/sdk/runtime-primitives.js +3 -3
- package/dist/sdk/runtime.d.ts +3 -2
- package/dist/sdk/runtime.js +7 -5
- package/dist/sdk/test/batch.d.ts +6 -0
- package/dist/sdk/test/batch.js +26 -6
- package/dist/sdk/test/entry.d.ts +1 -1
- package/dist/sdk/test/entry.js +3 -2
- package/dist/sdk/test/execution.d.ts +28 -3
- package/dist/sdk/test/execution.js +201 -34
- package/dist/sdk/test/parsers.d.ts +6 -0
- package/dist/sdk/test/parsers.js +21 -2
- package/dist/sdk/test/trust.d.ts +33 -0
- package/dist/sdk/test/trust.js +207 -0
- package/dist/types.d.ts +34 -0
- package/dist/types.js +2 -2
- package/docs/AGENT_PROVENANCE_ADR.md +41 -5
- package/docs/AGENT_UX_CONTRACTS.md +20 -4
- package/docs/COMMANDS.md +29 -14
- package/docs/CONFIGURATION.md +4 -0
- package/docs/DEPENDENCY_KIND_CONTRACT.md +31 -3
- package/docs/DIAGNOSTIC_OUTPUT_CONTRACTS.md +115 -0
- package/docs/EXTENSIONS.md +2 -1
- package/docs/MERGE_SAFETY.md +15 -1
- package/docs/README.md +1 -0
- package/docs/READ_OUTPUT_CONTRACTS.md +19 -2
- package/docs/RELATIONSHIP_GRAPH.md +6 -3
- package/docs/REPRODUCIBLE_WORKSPACES.md +42 -8
- package/docs/SDK.md +9 -0
- package/docs/SDK_AGENT_SESSION_CONTEXT.md +6 -4
- package/docs/SDK_EVIDENCE_TRACEABILITY.md +1 -1
- package/docs/TESTING.md +83 -1
- package/docs/agent-task-token-baseline.json +2 -2
- package/docs/generated/FLAG_LEXICON_BUDGETS.md +2 -2
- package/marketplace.json +2 -2
- package/package.json +2 -2
- 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 +1021 -53
- package/dist/cli-bundle/chunks/chunk-2MA6ZQVZ.js +0 -197
- package/dist/cli-bundle/chunks/chunk-3AFAUHUE.js +0 -2
- package/dist/cli-bundle/chunks/chunk-7VHZS727.js +0 -5
- package/dist/cli-bundle/chunks/chunk-JSLOFXGA.js +0 -3
- package/dist/cli-bundle/chunks/chunk-OCLPLFAY.js +0 -35
- package/dist/cli-bundle/chunks/chunk-S4IRYKBU.js +0 -13
- package/dist/cli-bundle/chunks/register-mutation-7IY2D5KO.js +0 -20
- package/dist/cli-bundle/chunks/register-operations-FALL3YTU.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-7WZRLCYF.js +0 -50
- package/dist/cli-bundle/focused-chunks/chunk-CKKQSJNN.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-EEFKYMDR.js +0 -16
- package/dist/cli-bundle/focused-chunks/chunk-F2A56DHV.js +0 -8
- package/dist/cli-bundle/focused-chunks/chunk-FV5ACOK7.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-JEAVFOWM.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-NJ63LOP6.js +0 -155
- package/dist/cli-bundle/focused-chunks/chunk-NXRTQ7HI.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-TJ7EMJ46.js +0 -4
- package/dist/cli-bundle/focused-chunks/chunk-ZOSEELYJ.js +0 -26
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Diagnostic Output Contracts
|
|
2
|
+
|
|
3
|
+
Tracker references: [pm-cha95z](../.agents/pm/tasks/pm-cha95z.toon), [pm-5t33or](../.agents/pm/features/pm-5t33or.toon), [pm-f05lsg](../.agents/pm/features/pm-f05lsg.toon), and [pm-h8tpeh](../.agents/pm/features/pm-h8tpeh.toon).
|
|
4
|
+
|
|
5
|
+
## Agent Quick Context
|
|
6
|
+
|
|
7
|
+
Failures are context-management surfaces. Every diagnostic family now declares
|
|
8
|
+
a format-aware token ceiling and one degradation ladder in the public SDK:
|
|
9
|
+
|
|
10
|
+
| Class | Text | JSON | Corrective action that survives degradation |
|
|
11
|
+
| -------------------- | ---: | ---: | ------------------------------------------- |
|
|
12
|
+
| `error` | 768 | 2000 | required action, retry/domain, or next step |
|
|
13
|
+
| `warning` | 768 | 2000 | required action, retry/domain, or next step |
|
|
14
|
+
| `validation_summary` | 1500 | 3000 | required action, retry/domain, or next step |
|
|
15
|
+
| `recovery_bundle` | 768 | 2000 | required action, retry/domain, or next step |
|
|
16
|
+
|
|
17
|
+
The smallest explicit ceiling is 192 estimated tokens. At that floor, the
|
|
18
|
+
projector may reduce the diagnostic to its code, required action, compact
|
|
19
|
+
recovery, and exit status. It never removes the first corrective action.
|
|
20
|
+
|
|
21
|
+
## SDK Contract
|
|
22
|
+
|
|
23
|
+
Use the public contract surface rather than maintaining a package-local error
|
|
24
|
+
budget:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import {
|
|
28
|
+
PM_DIAGNOSTIC_OUTPUT_BUDGET_CONTRACTS,
|
|
29
|
+
projectPmDiagnosticOutput,
|
|
30
|
+
projectPmDiagnosticText,
|
|
31
|
+
resolvePmDiagnosticOutputBudget,
|
|
32
|
+
} from "@unbrained/pm-cli/sdk/contracts";
|
|
33
|
+
|
|
34
|
+
const contract = resolvePmDiagnosticOutputBudget("error");
|
|
35
|
+
const projected = projectPmDiagnosticOutput(
|
|
36
|
+
{
|
|
37
|
+
code: "invalid_argument_value",
|
|
38
|
+
required: "Use --status open and retry.",
|
|
39
|
+
recovery: { suggested_retry: "pm list --status open" },
|
|
40
|
+
detail: "The supplied status is not declared.",
|
|
41
|
+
exit_code: 2,
|
|
42
|
+
},
|
|
43
|
+
{ maxEstimatedTokens: contract.minimum_max_estimated_tokens },
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const text = projectPmDiagnosticText(
|
|
47
|
+
"A long rendered diagnostic",
|
|
48
|
+
"Use --status open and retry.",
|
|
49
|
+
).output;
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The JSON projector orders `code`, `required`, recovery, and next steps before
|
|
53
|
+
explanation. Untruncated diagnostics add no per-call receipt overhead; their
|
|
54
|
+
binding declaration is discoverable from `pm contracts --full --json` under
|
|
55
|
+
`diagnostic_output_contracts`. When degradation occurs, the returned
|
|
56
|
+
`diagnostic_output` receipt records the effective budget, original and emitted
|
|
57
|
+
estimates, applied stages, and omitted top-level fields. Minimal fallbacks bound
|
|
58
|
+
the named omission list and disclose any additional count through
|
|
59
|
+
`omitted_fields_overflow_count`.
|
|
60
|
+
|
|
61
|
+
Structured CLI refusals also include a compact `refusal` identity with the
|
|
62
|
+
failing command/flag/operand surface, rejected scalar when observable, complete
|
|
63
|
+
legal domain when one exists, and the process exit code. Recovery-bearing
|
|
64
|
+
errors use the `recovery_bundle` diagnostic class. Collection degradation may
|
|
65
|
+
compact explanatory domains inside `recovery`, but `refusal.legal_domain`
|
|
66
|
+
remains complete and `recovery.suggested_retry_args` is atomic: the projector
|
|
67
|
+
either retains the executable argv or removes the recovery rather than slicing
|
|
68
|
+
it into a dead command.
|
|
69
|
+
|
|
70
|
+
The deterministic ladder is:
|
|
71
|
+
|
|
72
|
+
1. full diagnostic;
|
|
73
|
+
2. omit explanation;
|
|
74
|
+
3. limit diagnostic collections;
|
|
75
|
+
4. compact recovery to actionable keys;
|
|
76
|
+
5. retain the action-only envelope.
|
|
77
|
+
|
|
78
|
+
Human diagnostics lead with `What is required` and next steps before explaining
|
|
79
|
+
what happened. If their declared ceiling binds, the compact text still begins
|
|
80
|
+
with the required action and points to structured JSON for the bounded recovery
|
|
81
|
+
envelope.
|
|
82
|
+
|
|
83
|
+
## Executable Assurance
|
|
84
|
+
|
|
85
|
+
`pnpm quality:recovery-closure` builds the current CLI and replays 117 refusal
|
|
86
|
+
contracts in isolated trackers: 18 closed-domain rows, 88 required-argument
|
|
87
|
+
omissions derived from core executable positional signatures, seven
|
|
88
|
+
closed-action families, and four tracker-preflight states. Package-owned
|
|
89
|
+
commands enter executable coverage when their package runtime is active rather
|
|
90
|
+
than being misreported as core. Ten representative, high-frequency failure
|
|
91
|
+
paths are also ratcheted by
|
|
92
|
+
`scripts/release/diagnostic-output-baseline.json`. The gate requires every row
|
|
93
|
+
to remain within the SDK-declared JSON ceiling and retain a mechanically
|
|
94
|
+
actionable correction. It reports the aggregate original and emitted token
|
|
95
|
+
estimates without claiming a reduction when no degradation was required.
|
|
96
|
+
|
|
97
|
+
The baseline is a coverage ratchet, not permission to weaken a ceiling. Its
|
|
98
|
+
negative control requires a missing baseline probe to fail. The existing
|
|
99
|
+
refusal-closure negative controls independently prove that incomplete domains,
|
|
100
|
+
broken retries, and malformed recovery envelopes remain blocking findings.
|
|
101
|
+
The grammar corpus additionally hashes authoritative tracker state around each
|
|
102
|
+
refusal; schema, items, history, settings, and package state must not change.
|
|
103
|
+
Ephemeral runtime lock/cache directories are excluded from that semantic
|
|
104
|
+
snapshot.
|
|
105
|
+
|
|
106
|
+
Run the focused proof with:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
pnpm build
|
|
110
|
+
node scripts/release/refusal-closure-gate.mjs
|
|
111
|
+
node scripts/run-tests.mjs test -- \
|
|
112
|
+
tests/unit/sdk/agent-output-contracts.spec.ts \
|
|
113
|
+
tests/unit/cli/error-guidance.spec.ts \
|
|
114
|
+
tests/unit/scripts/refusal-closure-gate.spec.ts
|
|
115
|
+
```
|
package/docs/EXTENSIONS.md
CHANGED
|
@@ -45,6 +45,7 @@ pm install kanban --project
|
|
|
45
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.
|
|
46
46
|
Local `.tgz` and `.tar.gz` npm archives are inspected and extracted in an isolated temporary directory without invoking a shell. Archives must contain one `package/package.json` root, regular files/directories only, and bounded entry and expanded-byte totals. Absolute paths, traversal, alternate roots, links, device entries, oversized entries, and decompression-ratio abuse fail before installation. The managed source remains the original archive path, so reload and upgrade provenance do not point at a temporary extraction directory.
|
|
47
47
|
Registry dependency names and versions are parsed as npm package specs before the install subprocess starts. Leading-option names and shell control syntax are rejected. npm reads those validated dependencies from an isolated runtime-only manifest; no caller-controlled spec is forwarded through the Windows command shell, and the fixed invocation still ends option parsing with `--`. Runtime verification then activates a temporary snapshot of the complete installed extension directory, so an upgrade cannot silently reuse stale transitive ESM dependencies from the current process. Successful install details expose `module_graph_verification: "fresh_snapshot"` for this check.
|
|
48
|
+
pm-owned npm subprocesses clear any inherited, case-insensitive `npm_config_allow_scripts` value while retaining registry, auth, proxy, and executable-path environment; `--ignore-scripts` remains authoritative. Tracked by [pm-gh1072](../.agents/pm/issues/pm-gh1072.toon).
|
|
48
49
|
An explicit `--pm-path` scopes project installs to that tracker root, including extension files, managed state, settings, type-folder scaffolding, and verification output. This is the safe form for temporary package testing from inside another repository checkout.
|
|
49
50
|
|
|
50
51
|
```bash
|
|
@@ -308,7 +309,7 @@ Common APIs:
|
|
|
308
309
|
- `api.registerMigration(definition)` adds schema migrations.
|
|
309
310
|
- `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
311
|
- `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.
|
|
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.
|
|
312
|
+
- `api.registerService("output_format", handler, ownership?)` 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. An override that is unconditionally inert can declare `{ passThrough: true }`; the host then ignores and diagnoses any handled result, and package doctor treats the registration as statically safe. Legacy `null`/`undefined` declines remain supported; returning the original payload is now an unambiguous handled result. Tracked by [pm-gh1074](../.agents/pm/issues/pm-gh1074.toon).
|
|
312
313
|
- `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.
|
|
313
314
|
- `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.
|
|
314
315
|
- `api.hooks.beforeCommand(handler)`, `api.hooks.beforeMutation(handler)`, `api.hooks.afterCommand(handler)`, `api.hooks.onWrite(handler)`, `api.hooks.onRead(handler)`, and `api.hooks.onIndex(handler)` add lifecycle hooks.
|
package/docs/MERGE_SAFETY.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Multi-Branch Tracker Merge Safety
|
|
2
2
|
|
|
3
|
-
Tracked by [pm-wc1r](../.agents/pm/features/pm-wc1r.toon), with the integrity and concurrency fixes [pm-9q2t](../.agents/pm/issues/pm-9q2t.toon), [pm-cxyv](../.agents/pm/issues/pm-cxyv.toon), [pm-gpo7](../.agents/pm/issues/pm-gpo7.toon), [pm-m3nl](../.agents/pm/issues/pm-m3nl.toon), [pm-wwfd](../.agents/pm/issues/pm-wwfd.toon), and [pm-xdn6](../.agents/pm/issues/pm-xdn6.toon). Fresh-init fence ownership is tracked by [pm-1w3ljt](../.agents/pm/issues/pm-1w3ljt.toon); runtime-cache index governance by [pm-hous](../.agents/pm/issues/pm-hous.toon); local allocation safety by [pm-khdq](../.agents/pm/issues/pm-khdq.toon); fence-coverage completeness and drift detection by [pm-i4fx](../.agents/pm/issues/pm-i4fx.toon); package-defined item coverage by [pm-5rexki](../.agents/pm/issues/pm-5rexki.toon); non-item JSON coverage by [pm-gjicmx](../.agents/pm/issues/pm-gjicmx.toon); portable driver identity by [pm-w91mvg](../.agents/pm/issues/pm-w91mvg.toon); pending receipt validation by [pm-ysqb6n](../.agents/pm/issues/pm-ysqb6n.toon); receipt classification by [pm-jtwsct](../.agents/pm/issues/pm-jtwsct.toon); direction-independent item conflict selection by [pm-dlx7v7](../.agents/pm/issues/pm-dlx7v7.toon); corrected reconciliation guidance by [pm-lwmstb](../.agents/pm/issues/pm-lwmstb.toon); cross-branch id collision safety by [pm-pibw](../.agents/pm/issues/pm-pibw.toon); auditable merge history by [pm-9j2r3b](../.agents/pm/tasks/pm-9j2r3b.toon); durable conflict decisions by [pm-rh98vo](../.agents/pm/issues/pm-rh98vo.toon); continuous conformance by [pm-76dnfg](../.agents/pm/tasks/pm-76dnfg.toon); workspace-wide CI enforcement by [pm-pdr8t1](../.agents/pm/tasks/pm-pdr8t1.toon); post-merge reconciliation by [pm-mfkv92](../.agents/pm/issues/pm-mfkv92.toon); this repository's own adoption by [pm-iwsj](../.agents/pm/chores/pm-iwsj.toon).
|
|
3
|
+
Tracked by [pm-wc1r](../.agents/pm/features/pm-wc1r.toon), with the integrity and concurrency fixes [pm-9q2t](../.agents/pm/issues/pm-9q2t.toon), [pm-cxyv](../.agents/pm/issues/pm-cxyv.toon), [pm-gpo7](../.agents/pm/issues/pm-gpo7.toon), [pm-m3nl](../.agents/pm/issues/pm-m3nl.toon), [pm-wwfd](../.agents/pm/issues/pm-wwfd.toon), and [pm-xdn6](../.agents/pm/issues/pm-xdn6.toon). Fresh-init fence ownership is tracked by [pm-1w3ljt](../.agents/pm/issues/pm-1w3ljt.toon); runtime-cache index governance by [pm-hous](../.agents/pm/issues/pm-hous.toon); local allocation safety by [pm-khdq](../.agents/pm/issues/pm-khdq.toon); fence-coverage completeness and drift detection by [pm-i4fx](../.agents/pm/issues/pm-i4fx.toon); package-defined item coverage by [pm-5rexki](../.agents/pm/issues/pm-5rexki.toon); non-item JSON coverage by [pm-gjicmx](../.agents/pm/issues/pm-gjicmx.toon); portable driver identity by [pm-w91mvg](../.agents/pm/issues/pm-w91mvg.toon); pending receipt validation by [pm-ysqb6n](../.agents/pm/issues/pm-ysqb6n.toon); receipt classification by [pm-jtwsct](../.agents/pm/issues/pm-jtwsct.toon); direction-independent item conflict selection by [pm-dlx7v7](../.agents/pm/issues/pm-dlx7v7.toon); corrected reconciliation guidance by [pm-lwmstb](../.agents/pm/issues/pm-lwmstb.toon); cross-branch id collision safety by [pm-pibw](../.agents/pm/issues/pm-pibw.toon); auditable merge history by [pm-9j2r3b](../.agents/pm/tasks/pm-9j2r3b.toon); durable conflict decisions by [pm-rh98vo](../.agents/pm/issues/pm-rh98vo.toon); continuous conformance by [pm-76dnfg](../.agents/pm/tasks/pm-76dnfg.toon); workspace-wide CI enforcement by [pm-pdr8t1](../.agents/pm/tasks/pm-pdr8t1.toon); post-merge reconciliation by [pm-mfkv92](../.agents/pm/issues/pm-mfkv92.toon); linked-command execution trust by [pm-ed28wi](../.agents/pm/issues/pm-ed28wi.toon); this repository's own adoption by [pm-iwsj](../.agents/pm/chores/pm-iwsj.toon).
|
|
4
4
|
|
|
5
5
|
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.
|
|
6
6
|
|
|
@@ -61,6 +61,20 @@ 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
|
+
The `tests` collection has an additional execution-safety rule. Its semantic
|
|
65
|
+
identity excludes provenance so the same command/context does not duplicate
|
|
66
|
+
when branches record different authorship metadata. A test definition newly
|
|
67
|
+
contributed by the other merge side is persisted with
|
|
68
|
+
`provenance.source_kind=merge_union` while retaining its author, creation time,
|
|
69
|
+
and source ref. `pm test --run` and `pm test-all` refuse that command before
|
|
70
|
+
spawning a process until the receiving clone acknowledges its fingerprint or
|
|
71
|
+
uses the two-part project-policy plus per-run override documented in
|
|
72
|
+
[Testing](TESTING.md#linked-test-command-trust). `pm validate
|
|
73
|
+
--check-command-references` reports outstanding entries. This is the threat
|
|
74
|
+
boundary for append-like data that becomes executable after a merge; ordinary
|
|
75
|
+
notes, files, and other non-executable collections retain normal set-union
|
|
76
|
+
behavior.
|
|
77
|
+
|
|
64
78
|
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
79
|
|
|
66
80
|
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).
|
package/docs/README.md
CHANGED
|
@@ -51,6 +51,7 @@ pm guide release --json
|
|
|
51
51
|
- [SDK Context Platform](SDK_CONTEXT.md) - task-oriented entry point for authoritative reads, ranking, package workflows, diagnostics, recovery, and verification.
|
|
52
52
|
- [Self-Describing Context Contracts](SELF_DESCRIBING_CONTEXT_CONTRACTS.md) - intent-scoped reads, semantic flag invocation metadata, visibility parity, and generated error vocabulary.
|
|
53
53
|
- [Universal Read Output Contracts](READ_OUTPUT_CONTRACTS.md) - cross-command include, amount, cost, and encoding controls for CLI, SDK, MCP, and packages.
|
|
54
|
+
- [Diagnostic Output Contracts](DIAGNOSTIC_OUTPUT_CONTRACTS.md) - action-first error budgets, deterministic degradation, SDK projection, and executable refusal assurance.
|
|
54
55
|
- [Mutation Integrity](MUTATION_INTEGRITY.md) - shared CLI/SDK/MCP author, secret, append-only disposition, and stale-work guardrails.
|
|
55
56
|
- [Agent Provenance ADR Amendment](AGENT_PROVENANCE_ADR.md) - extensible model, effort, role, and host provenance with privacy and compatibility boundaries.
|
|
56
57
|
- [SDK Agent Session and Episode Context](SDK_AGENT_SESSION_CONTEXT.md) - inherited role/topic context, cross-process episode identity, and deterministic history grouping.
|
|
@@ -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-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-e5gl05](../.agents/pm/issues/pm-e5gl05.toon), [pm-cha95z](../.agents/pm/tasks/pm-cha95z.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-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-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
|
|
|
@@ -140,7 +140,7 @@ pm stats --output-row-contract
|
|
|
140
140
|
pm contracts --full --json
|
|
141
141
|
```
|
|
142
142
|
|
|
143
|
-
Every projected result carries a `read_output` receipt with the requested dimensions, precedence, observed
|
|
143
|
+
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.
|
|
144
144
|
|
|
145
145
|
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`.
|
|
146
146
|
|
|
@@ -164,6 +164,16 @@ an unbounded multi-megabyte response;
|
|
|
164
164
|
`recovery_budget_multiplier: 1` declares that each next page retains the same
|
|
165
165
|
useful-result ceiling.
|
|
166
166
|
|
|
167
|
+
When compaction affects a nested collection that is not declared resumable,
|
|
168
|
+
the recovery budget is derived from the larger of the binding ceiling plus one
|
|
169
|
+
and the measured pre-compaction result. The SDK adds a 25% envelope margin and
|
|
170
|
+
rounds up to 100 tokens. The CLI, SDK, and MCP bindings therefore receive the
|
|
171
|
+
same finite value, which is strictly larger than the request that already
|
|
172
|
+
truncated. If safe-integer arithmetic cannot represent that value, recovery
|
|
173
|
+
uses `unbounded` explicitly. `resolveReadOutputRecoveryBudget()` exposes the
|
|
174
|
+
versioned pure calculation to package authors; there is no hard-coded smaller
|
|
175
|
+
retry and no recovery cycle.
|
|
176
|
+
|
|
167
177
|
Assurance declares `budget_retention_policy: verdict_priority`: failing block,
|
|
168
178
|
warn, and observe rows precede retired and passing rows while preserving order
|
|
169
179
|
within each class. `assertions_total` remains the pre-projection denominator,
|
|
@@ -179,6 +189,13 @@ key. Health retains at most 100 warning rows and reports `warning_count`,
|
|
|
179
189
|
projection unless `--full` is explicit, keeping the failing check identities
|
|
180
190
|
and warning codes inside the ordinary budget.
|
|
181
191
|
|
|
192
|
+
Failure transports use the companion
|
|
193
|
+
[Diagnostic Output Contracts](DIAGNOSTIC_OUTPUT_CONTRACTS.md). Those contracts
|
|
194
|
+
bind errors, warnings, validation summaries, and recovery bundles independently
|
|
195
|
+
from successful command results. Corrective actions precede explanation and
|
|
196
|
+
survive every degradation stage, while untruncated JSON avoids a per-call
|
|
197
|
+
receipt tax.
|
|
198
|
+
|
|
182
199
|
## SDK and Package Usage
|
|
183
200
|
|
|
184
201
|
Typed `PmClient` read methods accept `PmReadOutputOptions` directly:
|
|
@@ -314,9 +314,12 @@ outcome milestones are roots, not work subjects, and are excluded from those
|
|
|
314
314
|
populations. Rate or
|
|
315
315
|
all-status floors are lifecycle-stable; an absolute active-population floor is
|
|
316
316
|
invalid because completing reachable work legitimately moves it into the
|
|
317
|
-
terminal population.
|
|
318
|
-
|
|
319
|
-
clean class with a
|
|
317
|
+
terminal population. Detailed output's nested SDK profile census,
|
|
318
|
+
`finding_subjects_by_code`, includes every known finding code even when its
|
|
319
|
+
population is zero, so assurance selectors never confuse a clean class with a
|
|
320
|
+
missing contract field. The top-level audit and persisted-baseline census is
|
|
321
|
+
`affected_subjects_by_code`; both fields count affected subjects, but their
|
|
322
|
+
locations and consumers differ and neither is an alias for the other.
|
|
320
323
|
|
|
321
324
|
```ts
|
|
322
325
|
import {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# Reproducible Workspaces and Snapshots
|
|
2
2
|
|
|
3
|
-
Tracked by [pm-rbcvt2](../.agents/pm/features/pm-rbcvt2.toon)
|
|
4
|
-
[pm-dkrmzv](../.agents/pm/features/pm-dkrmzv.toon)
|
|
3
|
+
Tracked by [pm-rbcvt2](../.agents/pm/features/pm-rbcvt2.toon),
|
|
4
|
+
[pm-dkrmzv](../.agents/pm/features/pm-dkrmzv.toon), and
|
|
5
|
+
[pm-gh1089](../.agents/pm/issues/pm-gh1089.toon).
|
|
5
6
|
|
|
6
7
|
These SDK primitives make a pm workspace reproducible without changing normal
|
|
7
8
|
interactive behavior. Recipes control time and identifier entropy only inside
|
|
@@ -22,9 +23,7 @@ const recipe: WorkspaceRecipe = {
|
|
|
22
23
|
seed: "example-fixture-v1",
|
|
23
24
|
clock: "2026-07-28T10:00:00.000Z",
|
|
24
25
|
tickMs: 1,
|
|
25
|
-
operations: [
|
|
26
|
-
{ action: "create", input: { title: "Deterministic task" } },
|
|
27
|
-
],
|
|
26
|
+
operations: [{ action: "create", input: { title: "Deterministic task" } }],
|
|
28
27
|
};
|
|
29
28
|
|
|
30
29
|
const results = await executeWorkspaceRecipe(
|
|
@@ -36,9 +35,9 @@ const results = await executeWorkspaceRecipe(
|
|
|
36
35
|
The caller owns action dispatch. pm owns the deterministic execution context:
|
|
37
36
|
`nowIso()` advances from `clock` by `tickMs`, and generated item identifiers
|
|
38
37
|
derive from `seed`. Async scopes are isolated with `AsyncLocalStorage`, so
|
|
39
|
-
concurrent recipes do not share counters.
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
concurrent recipes do not share counters. Normal CLI and MCP execution still
|
|
39
|
+
uses the system clock and cryptographic randomness unless the process opts in
|
|
40
|
+
through the environment contract below.
|
|
42
41
|
|
|
43
42
|
`defineWorkspaceRecipe` immediately validates the clock, seed, tick, schema,
|
|
44
43
|
operation actions, and recursively JSON-compatible inputs. Its TypeScript
|
|
@@ -51,6 +50,41 @@ Seeds are reproducibility inputs, not secrets. A replay is byte-identical only
|
|
|
51
50
|
when it begins from equivalent authoritative state and invokes the same ordered
|
|
52
51
|
operations with the same recipe.
|
|
53
52
|
|
|
53
|
+
## CLI and MCP process configuration
|
|
54
|
+
|
|
55
|
+
Shell-based harnesses can install the same SDK-owned deterministic context for
|
|
56
|
+
the `pm` and `pm-mcp` processes without patching JavaScript globals:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
PM_CLOCK=2026-07-28T10:00:00.000Z \
|
|
60
|
+
PM_CLOCK_TICK_MS=1 \
|
|
61
|
+
PM_SEED=example-fixture-v1 \
|
|
62
|
+
pm create --title "Deterministic task" --type Task --json
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`PM_CLOCK` and `PM_SEED` are required together. `PM_CLOCK` must be an ISO-8601
|
|
66
|
+
instant with `Z` or a numeric UTC offset; timezone-less and non-ISO inputs are
|
|
67
|
+
rejected so separate hosts cannot interpret the same configuration differently.
|
|
68
|
+
`PM_CLOCK_TICK_MS` is optional, defaults to `1`, and must be a non-negative integer. Partial or invalid input
|
|
69
|
+
fails before command dispatch with the stable
|
|
70
|
+
`invalid_reproducible_process_environment` code and recovery that names the
|
|
71
|
+
missing or invalid variable. Unset all three variables for normal interactive
|
|
72
|
+
behavior.
|
|
73
|
+
|
|
74
|
+
Every CLI process invocation begins a fresh deterministic scope. A workflow
|
|
75
|
+
that launches several CLI processes must derive a stable, distinct seed for
|
|
76
|
+
each ordered step; reusing one seed intentionally reproduces the same entropy
|
|
77
|
+
sequence and can reproduce an existing generated identifier. A long-lived MCP
|
|
78
|
+
server instead owns one process-lifetime sequence and advances it across its
|
|
79
|
+
serialized JSON-RPC requests. Two equivalent servers therefore produce the
|
|
80
|
+
same files without generating duplicate identifiers inside either server.
|
|
81
|
+
|
|
82
|
+
The public SDK exports `PM_REPRODUCIBLE_PROCESS_ENV`,
|
|
83
|
+
`resolveReproducibleProcessEnvironment`,
|
|
84
|
+
`runWithReproducibleProcessEnvironment`, and
|
|
85
|
+
`createReproducibleProcessRunner` for custom one-shot and long-lived process
|
|
86
|
+
transports.
|
|
87
|
+
|
|
54
88
|
## Content-addressed snapshots
|
|
55
89
|
|
|
56
90
|
The SDK exports:
|
package/docs/SDK.md
CHANGED
|
@@ -1702,6 +1702,15 @@ const telemetry = await runTelemetry(
|
|
|
1702
1702
|
global tracker roots. `pm_context_mode`, run-level overrides, automatic tracker
|
|
1703
1703
|
context, assertion requirements, empty-run detection, and failure categories are
|
|
1704
1704
|
part of the SDK result contract rather than presentation-layer behavior.
|
|
1705
|
+
Workspace results distinguish the run-level requested mode from the effective
|
|
1706
|
+
per-test mode. `isolated` executes from an empty disposable directory;
|
|
1707
|
+
`snapshot` executes from a filtered disposable workspace. Trust preflight
|
|
1708
|
+
failures report `trust_refusal`, while malformed or incomplete provenance uses
|
|
1709
|
+
the additive `provenance_invalid` storage marker and fail-closed
|
|
1710
|
+
`invalid_provenance` trust reason. Package mutation adapters can call
|
|
1711
|
+
`attachLinkedTestMutationProvenance` so Git inspection occurs only when commands
|
|
1712
|
+
are added; `resolveLinkedTestSourceWorkspaceRoot` keeps their source-ref lookup
|
|
1713
|
+
aligned with CLI execution and `PM_SOURCE_WORKSPACE_ROOT` overrides.
|
|
1705
1714
|
When item test-result tracking is enabled, `measure` persists typed numeric
|
|
1706
1715
|
evidence on the producing run. Each entry has a stable name, finite numeric
|
|
1707
1716
|
value, optional unit and threshold, and the run timestamp. Run history remains
|
|
@@ -6,7 +6,8 @@ Tracker references: [pm-9wbiye](../.agents/pm/issues/pm-9wbiye.toon),
|
|
|
6
6
|
[pm-3zgh2c](../.agents/pm/features/pm-3zgh2c.toon),
|
|
7
7
|
[pm-eq9dlw](../.agents/pm/issues/pm-eq9dlw.toon), and
|
|
8
8
|
[pm-lu6sca](../.agents/pm/features/pm-lu6sca.toon), plus
|
|
9
|
-
[pm-5q8wa0](../.agents/pm/issues/pm-5q8wa0.toon)
|
|
9
|
+
[pm-5q8wa0](../.agents/pm/issues/pm-5q8wa0.toon) and
|
|
10
|
+
[pm-c0lrdm](../.agents/pm/features/pm-c0lrdm.toon).
|
|
10
11
|
|
|
11
12
|
Project management is context management. The public SDK therefore carries a
|
|
12
13
|
session's purpose and episode boundary through the same immutable history that
|
|
@@ -128,9 +129,10 @@ public SDK exports for custom hosts.
|
|
|
128
129
|
the bounded built-in resolver. It never contains environment values, session
|
|
129
130
|
paths, prompts, or file contents.
|
|
130
131
|
|
|
131
|
-
New mutation history records failed
|
|
132
|
-
`context.agent_provenance_outcomes`;
|
|
133
|
-
the compact legacy-compatible null projection.
|
|
132
|
+
New mutation history records failed or explicitly unavailable configured
|
|
133
|
+
resolver outcomes under `context.agent_provenance_outcomes`; dimensions with
|
|
134
|
+
no configured resolver retain the compact legacy-compatible null projection.
|
|
135
|
+
A resolver is only counted as
|
|
134
136
|
attempted when its required input belongs to the detected harness; a foreign
|
|
135
137
|
host's shared `AI_AGENT` value is not Codex input. Consequently `pm health` can report
|
|
136
138
|
`provenance_resolver_zero_success:<harness>:<dimension>:<resolver>:<attempts>`
|
|
@@ -111,7 +111,7 @@ pair pre-redaction item content with post-redaction history during validation.
|
|
|
111
111
|
|
|
112
112
|
## Operational receipts
|
|
113
113
|
|
|
114
|
-
Linked tests recognize compound acquisition failures such as “could not acquire … lock” together with contention context such as “already running” or “held by another” as `infra_collision`. Generic assertion text mentioning a lock or timeout remains `assertion_failure`, preventing false infrastructure classifications.
|
|
114
|
+
Linked tests recognize compound acquisition failures such as “could not acquire … lock” together with contention context such as “already running” or “held by another” as `infra_collision`. Generic assertion text mentioning a lock or timeout remains `assertion_failure`, preventing false infrastructure classifications. A command refused by clone-local provenance policy is classified separately as `trust_refusal`, so reports do not misstate a pre-execution safety decision as an assertion failure.
|
|
115
115
|
|
|
116
116
|
Telemetry flush receipts distinguish progress from completion:
|
|
117
117
|
|
package/docs/TESTING.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
This page describes safe local tests, linked tests, coverage, and release-readiness checks.
|
|
4
4
|
|
|
5
|
-
Tracked implementation updates: [pm-52eh](../.agents/pm/features/pm-52eh.toon), [pm-mcxr](../.agents/pm/issues/pm-mcxr.toon), [pm-u42x](../.agents/pm/issues/pm-u42x.toon), [pm-atfm](../.agents/pm/features/pm-atfm.toon), [pm-xmp5](../.agents/pm/tasks/pm-xmp5.toon), [pm-39cqqx](../.agents/pm/tasks/pm-39cqqx.toon), [pm-5cgm2z](../.agents/pm/chores/pm-5cgm2z.toon), [pm-avv3wx](../.agents/pm/issues/pm-avv3wx.toon), [pm-rizqb6](../.agents/pm/issues/pm-rizqb6.toon), [pm-95h7pg](../.agents/pm/issues/pm-95h7pg.toon), [pm-giks4s](../.agents/pm/issues/pm-giks4s.toon), [pm-xa3t0o](../.agents/pm/issues/pm-xa3t0o.toon).
|
|
5
|
+
Tracked implementation updates: [pm-52eh](../.agents/pm/features/pm-52eh.toon), [pm-mcxr](../.agents/pm/issues/pm-mcxr.toon), [pm-u42x](../.agents/pm/issues/pm-u42x.toon), [pm-atfm](../.agents/pm/features/pm-atfm.toon), [pm-xmp5](../.agents/pm/tasks/pm-xmp5.toon), [pm-39cqqx](../.agents/pm/tasks/pm-39cqqx.toon), [pm-5cgm2z](../.agents/pm/chores/pm-5cgm2z.toon), [pm-avv3wx](../.agents/pm/issues/pm-avv3wx.toon), [pm-rizqb6](../.agents/pm/issues/pm-rizqb6.toon), [pm-95h7pg](../.agents/pm/issues/pm-95h7pg.toon), [pm-giks4s](../.agents/pm/issues/pm-giks4s.toon), [pm-xa3t0o](../.agents/pm/issues/pm-xa3t0o.toon), [pm-e97jyf](../.agents/pm/issues/pm-e97jyf.toon), [pm-efkvdy](../.agents/pm/issues/pm-efkvdy.toon), and [pm-ed28wi](../.agents/pm/issues/pm-ed28wi.toon).
|
|
6
6
|
|
|
7
7
|
## Agent Quick Context
|
|
8
8
|
|
|
@@ -366,6 +366,21 @@ The manifest records baseline bytes and estimated tokens for visible review
|
|
|
366
366
|
deltas. Updating it cannot raise answer ceilings, which remain owned by
|
|
367
367
|
`PM_COMMAND_OUTPUT_BUDGET_CONTRACTS`.
|
|
368
368
|
|
|
369
|
+
Diagnostic ceilings share the executable refusal gate:
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
pnpm quality:recovery-closure
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
The gate replays 117 refusal contracts: 18 closed-domain rows, 88
|
|
376
|
+
grammar-derived required-argument omissions, seven closed positional-action
|
|
377
|
+
families, and four tracker-preflight states. It also ratchets ten representative
|
|
378
|
+
failure paths against `PM_DIAGNOSTIC_OUTPUT_BUDGET_CONTRACTS`. Every diagnostic
|
|
379
|
+
must fit its declared JSON ceiling and preserve a mechanically actionable
|
|
380
|
+
correction; executable retry argv is never collection-truncated. The
|
|
381
|
+
missing-probe negative control and the authoritative tracker-state snapshot
|
|
382
|
+
prove that the corpus cannot silently shrink or turn a refusal into a mutation.
|
|
383
|
+
|
|
369
384
|
The gate derives every supported harness, model, session, and provenance
|
|
370
385
|
environment key from the SDK-owned harness descriptor registry. It deletes
|
|
371
386
|
those host inputs before each fixture invocation, then supplies only the
|
|
@@ -429,6 +444,69 @@ into constrained temporary storage.
|
|
|
429
444
|
Capacity, permission, and resource failures while seeding a required tracker
|
|
430
445
|
surface as typed, path-redacted host-environment refusals with recovery steps.
|
|
431
446
|
|
|
447
|
+
## Source Workspace Modes
|
|
448
|
+
|
|
449
|
+
Linked tests have a separate source-workspace contract. Store a default on one
|
|
450
|
+
entry with `workspace_context_mode`, or choose a run-level mode with
|
|
451
|
+
`--workspace-context`:
|
|
452
|
+
|
|
453
|
+
```bash
|
|
454
|
+
pm test <item-id> --add-json '{"command":"pnpm quality:static","workspace_context_mode":"isolated"}'
|
|
455
|
+
pm test <item-id> --run --workspace-context snapshot --override-linked-workspace-context
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
- `source` (default) runs in the source checkout and exposes its read-only
|
|
459
|
+
source-context environment, preserving existing linked-test behavior.
|
|
460
|
+
- `isolated` runs from an empty disposable directory and removes
|
|
461
|
+
`PM_SOURCE_WORKSPACE_ROOT`, `PM_SOURCE_PM_PATH`, and the source-context access
|
|
462
|
+
declaration. Use it only for commands that do not require checkout files.
|
|
463
|
+
- `snapshot` copies the workspace into the linked-test sandbox, runs from that
|
|
464
|
+
copy, and binds its `.agents/pm` path to the selected temporary tracker.
|
|
465
|
+
`.git`, `.agents`, `node_modules`, coverage output, and common cache
|
|
466
|
+
directories are excluded at every directory depth; an existing top-level
|
|
467
|
+
`node_modules` is linked read-only by convention. Built output remains
|
|
468
|
+
available so linked commands such as `node dist/cli.js` keep working. Writes
|
|
469
|
+
therefore land in the disposable snapshot rather than the source checkout.
|
|
470
|
+
|
|
471
|
+
Every result reports the requested/effective workspace mode, working
|
|
472
|
+
directory, exposed source root, and trust decision. Recorded `test_runs` retain
|
|
473
|
+
the effective workspace mode and trust reason beside the command.
|
|
474
|
+
|
|
475
|
+
## Linked-Test Command Trust
|
|
476
|
+
|
|
477
|
+
Linked commands are stored shell programs, so merge-unioned tracker data is an
|
|
478
|
+
execution boundary. New command entries record author, creation time, source
|
|
479
|
+
branch when available, and whether the item merge driver introduced the entry.
|
|
480
|
+
Locally created commands keep their previous run behavior. Commands marked as
|
|
481
|
+
merge-unioned or carrying a different source ref fail before process creation.
|
|
482
|
+
Malformed provenance is sanitized to the additive `provenance_invalid` marker
|
|
483
|
+
and receives the same fail-closed treatment; it is never normalized into a
|
|
484
|
+
trusted legacy command.
|
|
485
|
+
These pre-execution refusals use the `trust_refusal` failure category, separate
|
|
486
|
+
from command or assertion failures.
|
|
487
|
+
|
|
488
|
+
Choose one explicit recovery:
|
|
489
|
+
|
|
490
|
+
```bash
|
|
491
|
+
# Review and trust the item's current command fingerprints in this clone.
|
|
492
|
+
pm test <item-id> --acknowledge-linked-tests
|
|
493
|
+
|
|
494
|
+
# Or permit a single reviewed run. Both controls are required.
|
|
495
|
+
pm config project set untrusted-linked-test-execution enabled
|
|
496
|
+
pm test <item-id> --run --allow-untrusted-linked-tests
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
Acknowledgments live in the clone-local ignored runtime directory and bind to
|
|
500
|
+
the full command, tracker/workspace context, environment controls, host-safety
|
|
501
|
+
mode, and provenance fingerprint; editing any of those fields requires a new
|
|
502
|
+
review. Enabling the project policy alone never executes
|
|
503
|
+
an untrusted command, and the per-run flag alone is also refused. Inspect all
|
|
504
|
+
unacknowledged entries without executing them with:
|
|
505
|
+
|
|
506
|
+
```bash
|
|
507
|
+
pm validate --check-command-references --verbose-diagnostics
|
|
508
|
+
```
|
|
509
|
+
|
|
432
510
|
Use explicit modes when needed:
|
|
433
511
|
|
|
434
512
|
```bash
|
|
@@ -480,6 +558,10 @@ pm test <item-id> --metric-below coverage=100 --metric-diff p95_latency
|
|
|
480
558
|
|
|
481
559
|
Measurements are stored on the producing `test_runs` row, retained with the
|
|
482
560
|
bounded run history, and exposed consistently by CLI, SDK, MCP, and contracts.
|
|
561
|
+
Each recorded row also keeps a bounded `executions` list with the exact linked
|
|
562
|
+
command, requested/effective `pm_context_mode`, effective workspace mode, and
|
|
563
|
+
trust reason, so tracker-backed verification remains attributable after the
|
|
564
|
+
transient process logs are gone.
|
|
483
565
|
|
|
484
566
|
## Linked-Test Assertions
|
|
485
567
|
|
|
@@ -55,8 +55,8 @@ This file is generated by `listPmFlagLexicon()`. Compatibility aliases do not co
|
|
|
55
55
|
| `docs` | evidence | 30 | 30 |
|
|
56
56
|
| `deps` | graph | 32 | 32 |
|
|
57
57
|
| `plan` | graph | 109 | 109 |
|
|
58
|
-
| `test` | quality |
|
|
59
|
-
| `test-all` | quality |
|
|
58
|
+
| `test` | quality | 52 | 52 |
|
|
59
|
+
| `test-all` | quality | 40 | 40 |
|
|
60
60
|
| `telemetry` | workspace | 21 | 21 |
|
|
61
61
|
| `stats` | context | 29 | 29 |
|
|
62
62
|
| `health` | workspace | 36 | 36 |
|
package/marketplace.json
CHANGED
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Official marketplace for pm CLI — native git-based project management for Claude Code and AI coding agents.",
|
|
9
|
-
"version": "2026.8.
|
|
9
|
+
"version": "2026.8.23"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "pm-claude",
|
|
14
14
|
"source": "./plugins/pm-claude",
|
|
15
15
|
"description": "Native pm CLI integration for Claude Code — 28 MCP tools, 5 workflow skills, 14 slash commands, 4 subagents, hybrid TUI task tracking, session context injection, and coordination subagents for git-based project management without leaving Claude Code.",
|
|
16
|
-
"version": "2026.8.
|
|
16
|
+
"version": "2026.8.23",
|
|
17
17
|
"author": {
|
|
18
18
|
"name": "unbrained",
|
|
19
19
|
"url": "https://github.com/unbraind/pm-cli"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unbrained/pm-cli",
|
|
3
|
-
"version": "2026.8.
|
|
3
|
+
"version": "2026.8.23",
|
|
4
4
|
"description": "Git-native project management CLI for humans and agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "pnpm@11.10.0",
|
|
@@ -220,7 +220,7 @@
|
|
|
220
220
|
"@types/npm-package-arg": "^6.1.4",
|
|
221
221
|
"@vitest/coverage-v8": "^4.1.11",
|
|
222
222
|
"esbuild": "0.28.2",
|
|
223
|
-
"eslint": "^10.
|
|
223
|
+
"eslint": "^10.9.0",
|
|
224
224
|
"eslint-plugin-sonarjs": "^4.2.0",
|
|
225
225
|
"eslint-plugin-unicorn": "^73.0.0",
|
|
226
226
|
"fast-check": "^4.9.0",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unbrained/pm-digital-twin",
|
|
3
|
-
"version": "2026.8.
|
|
3
|
+
"version": "2026.8.23",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Beyond-PM exemplar: a temporal production-facility digital twin built entirely on public pm SDK and extension primitives.",
|