@unbrained/pm-cli 2026.8.20 → 2026.8.22
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 +38 -0
- package/dist/cli/error-guidance.d.ts +29 -4
- package/dist/cli/error-guidance.js +43 -43
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.js +40 -7
- package/dist/cli-bundle/bundle-manifest.json +150 -150
- package/dist/cli-bundle/chunks/{chunk-L4LGPBJU.js → chunk-BWX4SK46.js} +58 -58
- package/dist/cli-bundle/chunks/chunk-EMWDM5FI.js +13 -0
- package/dist/cli-bundle/chunks/chunk-HYG6LRL4.js +200 -0
- package/dist/cli-bundle/chunks/{chunk-TSMWLCHS.js → chunk-MYYI3ZOA.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-4GB2LTOQ.js → chunk-MZTZQTMS.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-7BRF2BX2.js → chunk-QI2CT3IX.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-SMWXHMVB.js +35 -0
- package/dist/cli-bundle/chunks/{chunk-US2ZQW2M.js → chunk-U6GQ4VMV.js} +47 -47
- package/dist/cli-bundle/chunks/{chunk-K3EN3LK2.js → chunk-VMMIL3SI.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-WG4STC36.js +5 -0
- package/dist/cli-bundle/chunks/{chunk-XYDDWBZN.js → chunk-YBPJAOQQ.js} +3 -3
- package/dist/cli-bundle/chunks/{register-list-query-JSAQCVOC.js → register-list-query-HZKBQNWW.js} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-XJPAW63D.js → register-mutation-HTKEEGRD.js} +2 -2
- package/dist/cli-bundle/chunks/{register-operations-DSOSB2XQ.js → register-operations-6EMRWJJY.js} +2 -2
- package/dist/cli-bundle/chunks/{register-setup-QUR6QL2C.js → register-setup-QK4OTOXN.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-TDR5OGG3.js → chunk-2ARQGDDW.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-AZBACT5T.js → chunk-2AZT5WXZ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-M32HFIQB.js → chunk-2POVTNLY.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-3LKU6PTJ.js +4 -0
- package/dist/cli-bundle/focused-chunks/chunk-5SHSBMX2.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-UGSS4F5X.js → chunk-6S2MO3Q3.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-5L7M4AI7.js → chunk-A2BC5PQL.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-C4S4A4JJ.js +5 -0
- package/dist/cli-bundle/focused-chunks/{chunk-OM65KHGF.js → chunk-D6RBZEJJ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-E2EWYPY6.js +16 -0
- package/dist/cli-bundle/focused-chunks/{chunk-G3C5ERXG.js → chunk-GMYPD4FX.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-L5LDSRO2.js +155 -0
- package/dist/cli-bundle/focused-chunks/{chunk-BLJCGGID.js → chunk-MB37AYN6.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-MCOR37QK.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-FUREQLQN.js → chunk-PH2OXXVZ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-325UXIO7.js → chunk-PMGJUFNQ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-R6SR45XU.js +50 -0
- package/dist/cli-bundle/focused-chunks/chunk-WZE4LIPW.js +8 -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 +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 +32 -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/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/item/id.js +20 -5
- package/dist/core/item/item-format.js +27 -2
- package/dist/core/shared/errors.d.ts +20 -0
- package/dist/core/shared/errors.js +2 -2
- package/dist/core/store/item-store.js +6 -91
- package/dist/core/store/tracker-preflight.d.ts +7 -0
- package/dist/core/store/tracker-preflight.js +142 -0
- package/dist/sdk/agent/refusal-reachability.d.ts +1 -1
- package/dist/sdk/agent/tracker-preflight-contracts.d.ts +63 -0
- package/dist/sdk/agent/tracker-preflight-contracts.js +127 -0
- package/dist/sdk/annotations.js +6 -7
- 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 +324 -2
- package/dist/sdk/cli-contracts/commander-mutation-options.js +3 -3
- 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.d.ts +1 -1
- package/dist/sdk/cli-contracts.js +3 -3
- package/dist/sdk/config.d.ts +5 -0
- package/dist/sdk/config.js +5 -5
- package/dist/sdk/context-intent-runtime.js +7 -4
- package/dist/sdk/contracts.d.ts +1 -0
- package/dist/sdk/contracts.js +3 -2
- package/dist/sdk/dependencies.js +5 -7
- package/dist/sdk/dependency-flag-validation.d.ts +1 -1
- package/dist/sdk/dependency-flag-validation.js +10 -4
- package/dist/sdk/environment/tracker-preflight.d.ts +6 -0
- package/dist/sdk/environment/tracker-preflight.js +10 -0
- package/dist/sdk/eval.js +5 -7
- 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/files.js +6 -10
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +75 -15
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +81 -8
- package/dist/sdk/governance/assurance.d.ts +36 -2
- package/dist/sdk/governance/assurance.js +184 -10
- package/dist/sdk/governance/gc.js +5 -6
- package/dist/sdk/governance/health.d.ts +3 -0
- package/dist/sdk/governance/health.js +42 -11
- package/dist/sdk/governance/hierarchy-validation.d.ts +29 -0
- package/dist/sdk/governance/hierarchy-validation.js +109 -0
- package/dist/sdk/governance/reindex.js +5 -6
- package/dist/sdk/governance/validate.d.ts +2 -9
- package/dist/sdk/governance/validate.js +51 -109
- 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.d.ts +7 -5
- package/dist/sdk/graph/governance.js +76 -16
- 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 +83 -36
- package/dist/sdk/graph/traversal.js +14 -5
- 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/history-compact.js +6 -9
- package/dist/sdk/history-read.js +5 -7
- package/dist/sdk/history-redact.js +5 -6
- package/dist/sdk/history-repair.js +6 -9
- package/dist/sdk/improvement-ledger.js +7 -10
- package/dist/sdk/index.d.ts +4 -2
- package/dist/sdk/index.js +5 -3
- package/dist/sdk/item-children.js +21 -8
- package/dist/sdk/lifecycle/append.d.ts +0 -5
- package/dist/sdk/lifecycle/append.js +5 -6
- package/dist/sdk/lifecycle/claim.d.ts +0 -5
- package/dist/sdk/lifecycle/claim.js +6 -9
- package/dist/sdk/lifecycle/close-many.d.ts +0 -5
- package/dist/sdk/lifecycle/close-many.js +5 -6
- package/dist/sdk/lifecycle/close.d.ts +0 -5
- package/dist/sdk/lifecycle/close.js +5 -6
- package/dist/sdk/lifecycle/copy.d.ts +0 -5
- package/dist/sdk/lifecycle/copy.js +5 -6
- package/dist/sdk/lifecycle/create.d.ts +0 -5
- package/dist/sdk/lifecycle/create.js +127 -102
- package/dist/sdk/lifecycle/delete.js +5 -6
- package/dist/sdk/lifecycle/focus.d.ts +0 -5
- package/dist/sdk/lifecycle/focus.js +5 -6
- 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/plan.d.ts +0 -5
- package/dist/sdk/lifecycle/plan.js +5 -6
- package/dist/sdk/lifecycle/restore.js +5 -6
- package/dist/sdk/lifecycle/update-many.d.ts +0 -5
- package/dist/sdk/lifecycle/update-many.js +5 -6
- package/dist/sdk/lifecycle/update.d.ts +2 -5
- package/dist/sdk/lifecycle/update.js +211 -84
- package/dist/sdk/linked-artifacts.js +6 -7
- package/dist/sdk/merge/install.js +5 -6
- package/dist/sdk/mutation-events.js +5 -7
- package/dist/sdk/package-import-adapters.js +6 -8
- package/dist/sdk/profile.js +6 -7
- package/dist/sdk/query/activity.js +5 -6
- package/dist/sdk/query/calendar.js +5 -6
- package/dist/sdk/query/complete-list.d.ts +3 -3
- package/dist/sdk/query/complete-list.js +46 -3
- package/dist/sdk/query/get.d.ts +0 -5
- package/dist/sdk/query/get.js +5 -6
- package/dist/sdk/query/history.d.ts +0 -5
- package/dist/sdk/query/history.js +5 -6
- package/dist/sdk/query/list.d.ts +4 -3
- package/dist/sdk/query/list.js +92 -54
- package/dist/sdk/query/search.js +5 -7
- package/dist/sdk/read-output-contracts.d.ts +5 -1
- package/dist/sdk/read-output-contracts.js +87 -22
- package/dist/sdk/relationship-context.js +3 -4
- package/dist/sdk/relationship-kinds/contract.d.ts +8 -0
- package/dist/sdk/relationship-kinds/contract.js +13 -13
- package/dist/sdk/relationships.d.ts +1 -1
- package/dist/sdk/relationships.js +27 -2
- package/dist/sdk/runtime.d.ts +3 -2
- package/dist/sdk/runtime.js +3 -2
- package/dist/sdk/schema-migration.js +6 -7
- package/dist/sdk/schema.js +5 -6
- package/dist/sdk/stats.js +5 -8
- package/dist/sdk/templates.js +5 -6
- package/dist/sdk/test/batch.js +15 -9
- package/dist/sdk/test/execution.js +12 -5
- package/dist/sdk/test/runs.js +5 -7
- package/dist/types.d.ts +11 -0
- package/dist/types.js +2 -2
- package/docs/AGENT_UX_CONTRACTS.md +24 -1
- package/docs/COMMANDS.md +29 -14
- package/docs/DEPENDENCY_KIND_CONTRACT.md +40 -1
- package/docs/DIAGNOSTIC_OUTPUT_CONTRACTS.md +98 -0
- package/docs/EXTENSIONS.md +2 -1
- package/docs/README.md +1 -0
- package/docs/READ_OUTPUT_CONTRACTS.md +9 -2
- package/docs/RECURRENCE_RECOVERY_CONTRACTS.md +37 -0
- package/docs/RELATIONSHIP_GRAPH.md +97 -12
- package/docs/SDK_PRIMITIVE_INVENTORY.md +15 -1
- package/docs/TESTING.md +15 -0
- package/marketplace.json +2 -2
- package/package.json +1 -1
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-digital-twin/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/packages/pm-vcs/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/sdk/public-surface.json +848 -56
- package/dist/cli-bundle/chunks/chunk-2RDVGYWE.js +0 -13
- package/dist/cli-bundle/chunks/chunk-BLVQHFSY.js +0 -35
- package/dist/cli-bundle/chunks/chunk-CU25EQVV.js +0 -5
- package/dist/cli-bundle/chunks/chunk-RS3IV2R6.js +0 -197
- package/dist/cli-bundle/focused-chunks/chunk-6AHG2YW7.js +0 -50
- package/dist/cli-bundle/focused-chunks/chunk-GXWQBE3T.js +0 -8
- package/dist/cli-bundle/focused-chunks/chunk-JWKEDZJI.js +0 -4
- package/dist/cli-bundle/focused-chunks/chunk-KYZ6JGPL.js +0 -155
- package/dist/cli-bundle/focused-chunks/chunk-Q47EX4DI.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-RIHDMCUM.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-T4ZFY7ZJ.js +0 -16
- package/dist/cli-bundle/focused-chunks/chunk-Z3PLWSGM.js +0 -2
package/docs/COMMANDS.md
CHANGED
|
@@ -6,6 +6,8 @@ Tracked implementation updates: [pm-52eh](../.agents/pm/features/pm-52eh.toon),
|
|
|
6
6
|
|
|
7
7
|
Workspace-integrity contracts are tracked by [pm-22rzjp](../.agents/pm/issues/pm-22rzjp.toon), [pm-76fkpp](../.agents/pm/issues/pm-76fkpp.toon), [pm-igdvfq](../.agents/pm/issues/pm-igdvfq.toon), [pm-643e0k](../.agents/pm/issues/pm-643e0k.toon), and [pm-larv4r](../.agents/pm/issues/pm-larv4r.toon).
|
|
8
8
|
|
|
9
|
+
Create-safe init prefix normalization is tracked by [pm-gh1073](../.agents/pm/issues/pm-gh1073.toon).
|
|
10
|
+
|
|
9
11
|
```bash
|
|
10
12
|
pm <command> --help
|
|
11
13
|
pm <command> --help --json
|
|
@@ -49,21 +51,21 @@ JSON ceiling; TOON uses the smaller default agent ceiling.
|
|
|
49
51
|
|
|
50
52
|
## Command Families
|
|
51
53
|
|
|
52
|
-
| Family | Commands
|
|
53
|
-
| ------------ |
|
|
54
|
-
| Bootstrap | `init`, `config`, `health`, `telemetry`
|
|
54
|
+
| Family | Commands | Purpose |
|
|
55
|
+
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
56
|
+
| Bootstrap | `init`, `config`, `health`, `telemetry` | create and inspect tracker setup |
|
|
55
57
|
| Lifecycle | `create`, `copy`, `focus`, `claim`, `update`, `item reopen`, `append`, `close`, `release`, `delete`, `start-task`, `pause-task`, `close-task` | mutate item state, including terminal-work recurrence without duplicate creation |
|
|
56
|
-
| Bulk | `item mutate`, `item complete`, `update-many`, `close-many`
|
|
57
|
-
| Scheduling | `meet`, `event`, `remind`
|
|
58
|
-
| Planning | `plan create`, `plan add-step`, `plan update-step`, `plan complete-step`, `plan link`, `plan approve`, `plan materialize`
|
|
59
|
-
| Links | `files`, `docs`, `test`, `deps`
|
|
60
|
-
| Verification | `test`, `test-all`, `test-runs`†, `validate`, `gc`
|
|
61
|
-
| History | `history`, `history-compact`, `history-redact`, `history-repair`, `activity`, `restore`, `stats`
|
|
62
|
-
| Schema | `schema add/remove-*` / `rename-type` / `rename-field` / `remap-status` / `apply-preset`
|
|
63
|
-
| Profiles | `profile list` / `show` / `apply` / `lint`
|
|
64
|
-
| Calendar | `calendar`, `cal`
|
|
65
|
-
| Packages | `install`, `upgrade`, `package`, `packages`, `extension`, package/extension command groups
|
|
66
|
-
| Machines | `contracts`, `help`, optional `guide`/`completion`
|
|
58
|
+
| Bulk | `item mutate`, `item complete`, `update-many`, `close-many` | atomically commit heterogeneous SDK mutation batches or evidence-backed completion, or apply one change across a matched, dry-run-previewed set with a rollback checkpoint |
|
|
59
|
+
| Scheduling | `meet`, `event`, `remind` | low-friction Meeting/Event/Reminder creation |
|
|
60
|
+
| Planning | `plan create`, `plan add-step`, `plan update-step`, `plan complete-step`, `plan link`, `plan approve`, `plan materialize` | agent-optimized living plans with ordered steps, evidence, decisions, validation, and materialization |
|
|
61
|
+
| Links | `files`, `docs`, `test`, `deps` | connect items to artifacts, tests, and relationships |
|
|
62
|
+
| Verification | `test`, `test-all`, `test-runs`†, `validate`, `gc` | run linked tests and repository checks |
|
|
63
|
+
| History | `history`, `history-compact`, `history-redact`, `history-repair`, `activity`, `restore`, `stats` | inspect, compact, redact, re-anchor, and recover item state |
|
|
64
|
+
| Schema | `schema add/remove-*` / `rename-type` / `rename-field` / `remap-status` / `apply-preset` | manage config-driven types, statuses, and fields; losslessly migrate existing items when definitions evolve; adopt presets or infer types |
|
|
65
|
+
| Profiles | `profile list` / `show` / `apply` / `lint` | compose item types, statuses, fields, workflows, config, templates, and recommended packages into archetype bundles (agile/ops/research); `apply` stages every dimension idempotently; `lint` reports author-time consistency findings without writing |
|
|
66
|
+
| Calendar | `calendar`, `cal` | project deadlines, reminders, and events |
|
|
67
|
+
| Packages | `install`, `upgrade`, `package`, `packages`, `extension`, package/extension command groups | install, upgrade, manage, and run package-backed extension commands |
|
|
68
|
+
| Machines | `contracts`, `help`, optional `guide`/`completion` | command contracts plus optional guide-shell docs routing and shell helpers |
|
|
67
69
|
|
|
68
70
|
`†` `test-runs` subcommands are provided by the optional `linked-test-adapters` package (`pm install linked-test-adapters --project`).
|
|
69
71
|
|
|
@@ -89,6 +91,15 @@ ID prefix without relying on the legacy positional form. `pm init ops` remains
|
|
|
89
91
|
compatible, and supplying both forms is accepted only when they normalize to the
|
|
90
92
|
same prefix; conflicting values fail with `init_id_prefix_conflict` instead of
|
|
91
93
|
silently choosing one.
|
|
94
|
+
Prefixes normalize through the same primitive used by item creation: letters
|
|
95
|
+
become lowercase, each run of whitespace or punctuation becomes one `-`, edge
|
|
96
|
+
separators are removed, and exactly one trailing `-` is stored. For example,
|
|
97
|
+
`"Release Candidate"` persists as `release-candidate-`; an input with no ASCII
|
|
98
|
+
letters or digits falls back to `pm-`. Path-like values remain invalid tracker
|
|
99
|
+
prefixes when passed through `--id-prefix`; a path-like positional value remains
|
|
100
|
+
the advanced tracker-root target described below. To repair an older unsafe
|
|
101
|
+
value, rerun init with a safe prefix and explicit replacement intent, for example
|
|
102
|
+
`pm init --id-prefix "release candidate" --force --defaults`.
|
|
92
103
|
Use `pm init --workspace <dir>` when `<dir>` is a project root; it creates `<dir>/.agents/pm`. A path-like positional remains the advanced tracker-root form and writes tracker files directly at that path. Both explicit target forms return `target.mode`, `target.tracker_root`, and tracker-scoped executable `next_steps` so agents can run the suggestions from any working directory.
|
|
93
104
|
Implicit init discovery also reports whether the selected tracker is local or was found in an ancestor. If `pm init <name>` would change an ancestor tracker, the refusal names both directories and gives the safe current-directory retry: `pm init <name> --pm-path "$PWD/.agents/pm" --defaults`.
|
|
94
105
|
`pm init --agent-guidance ask` is the default behavior: prompt in TTY only when AGENTS/CLAUDE guidance is missing and no decline is recorded.
|
|
@@ -163,6 +174,10 @@ Use `duplicates --status all` for a true whole-history duplicate check. The
|
|
|
163
174
|
result echoes `filters.statuses: null` for the unrestricted corpus; named or
|
|
164
175
|
custom statuses are normalized through the runtime status registry and an
|
|
165
176
|
unknown status fails instead of returning a false-clean result.
|
|
177
|
+
As a read-only structured surface, `duplicates` accepts the universal output
|
|
178
|
+
controls, including `--output-format json`, `--lean`, projection/amount
|
|
179
|
+
controls, and token accounting, while its default TOON output remains bounded.
|
|
180
|
+
Tracked by [pm-gh1076](../.agents/pm/issues/pm-gh1076.toon).
|
|
166
181
|
Use `pm get <id>` to read a single item by ID — the single-item read primitive used throughout the agent loop. It accepts `--fields <list>` and `--depth brief|standard|deep|full` for token-minimal projections, and `--tree`/`--tree-depth <n>` to include descendants. Standard/deep reads expose a normalized `schedule` facet (`deadline`, `start_at`, `end_at`, `location`, reminders, and events) when scheduling metadata exists. Container-oriented built-ins (Epic, Feature, Milestone, and Plan) plus custom types automatically expose type-agnostic child counts and continuation metadata. Standard depth keeps that rollup counts-only; `--depth deep|full` or an explicit `--fields id,children` request adds the deterministic bounded child sample. Built-in leaf reads avoid a workspace scan unless children are explicitly requested. `pm get <id> --json` returns the `body` inside the `item` object (`.item.body`); see [Full results, totals, and bodies](#full-results-totals-and-bodies). To duplicate an existing item as a starting point, `pm copy <id> --title "New title"` clones it into a fresh id with lifecycle fields reset.
|
|
167
182
|
|
|
168
183
|
When the strongest duplicate match is terminal because the same work recurred,
|
|
@@ -1,6 +1,6 @@
|
|
|
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), [pm-q6n8sj](../.agents/pm/issues/pm-q6n8sj.toon), [pm-ouyq3n](../.agents/pm/issues/pm-ouyq3n.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), [pm-ouyq3n](../.agents/pm/issues/pm-ouyq3n.toon), [pm-gos426](../.agents/pm/issues/pm-gos426.toon), [pm-flnefm](../.agents/pm/issues/pm-flnefm.toon), [pm-rggtvd](../.agents/pm/issues/pm-rggtvd.toon), and [pm-vk7zek](../.agents/pm/issues/pm-vk7zek.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
|
|
|
@@ -15,6 +15,45 @@ Dependency rows have one canonical stored spelling per relationship meaning. Com
|
|
|
15
15
|
|
|
16
16
|
The SDK relationship registry is authoritative. `canonicalizeRelationshipKind()` rejects unknown spellings, while `resolveCanonicalRelationshipKind()` supports validation flows that need an undefined result. `pm contracts` publishes `relationship_kind_contracts` with canonical names, aliases, inverses, and ordering/hierarchy semantics.
|
|
17
17
|
|
|
18
|
+
Extension kinds may opt into both ordering and hierarchy semantics. Unless they
|
|
19
|
+
declare an explicit `traversal`, ordering is the primary traversal and context
|
|
20
|
+
role family; hierarchy direction and cardinality remain enforceable integrity
|
|
21
|
+
constraints. This ordering-first precedence is shared by registry snapshots and
|
|
22
|
+
direct-edge context explanations.
|
|
23
|
+
|
|
24
|
+
Dependency additions and removals share the same lossless input grammar. A
|
|
25
|
+
bare value is an item id; structured removal input uses `id=<id>` plus optional
|
|
26
|
+
canonical `kind` (with `type` accepted only as an input alias), `source_kind`, `author`, and ISO `created_at`
|
|
27
|
+
selectors. Supplying all stored coordinates retires exactly one dependency row
|
|
28
|
+
without deleting siblings that share an id and kind. Punctuation-shaped shorthand such as
|
|
29
|
+
`OTHER,related` is rejected with `dependency_flag_value_invalid` on both
|
|
30
|
+
`--dep` and `--dep-remove`, before prefix normalization can turn it into a
|
|
31
|
+
dangling id. A removal selector that matches no stored row fails with
|
|
32
|
+
`dependency_remove_no_match` and returns the unmatched selectors plus compact
|
|
33
|
+
available identities. Re-adding a stored dependency identity is idempotent; if
|
|
34
|
+
legacy storage contains that exact identity more than once, the same mutation
|
|
35
|
+
collapses the touched copies to one without creating an edge-absence window.
|
|
36
|
+
The stored identity includes normalized `id`, `kind`, `source_kind`, `author`,
|
|
37
|
+
and creation instant, so provenance-distinct sibling rows remain independent.
|
|
38
|
+
|
|
39
|
+
## Hierarchy integrity
|
|
40
|
+
|
|
41
|
+
The registry's `hierarchy`, `hierarchyDirection`, `outgoing`, and `incoming`
|
|
42
|
+
fields are executable contracts. Scalar `parent` metadata and every registered
|
|
43
|
+
hierarchy dependency spelling normalize into the same parent-to-child relation.
|
|
44
|
+
That normalized relation powers `pm list --parent`, list/get tree projections,
|
|
45
|
+
child rollups, graph traversal, graph analysis, graph audit, validate, and
|
|
46
|
+
health. Extensions therefore gain hierarchy behavior by registering semantics;
|
|
47
|
+
consumers do not hard-code kind names.
|
|
48
|
+
|
|
49
|
+
Create and update transactions reject a newly introduced hierarchy cycle,
|
|
50
|
+
registry cardinality violation, or scalar/dependency direction contradiction
|
|
51
|
+
before persistence. Existing debt remains readable and repairable. Active debt
|
|
52
|
+
is gate-failing in graph governance and health; defects confined to terminal
|
|
53
|
+
items are labeled legacy and are never mutated automatically. `pm validate`
|
|
54
|
+
reports cycle, cardinality, and parent-divergence counts and exact bounded rows,
|
|
55
|
+
while `pm graph analyze` exposes a compact `hierarchy` summary.
|
|
56
|
+
|
|
18
57
|
`recurs_from` has no alias: a later occurrence points to an earlier occurrence.
|
|
19
58
|
It is persistent after both items become terminal and carries temporal identity,
|
|
20
59
|
not execution precedence. `supersedes` keeps replacement semantics, while
|
|
@@ -0,0 +1,98 @@
|
|
|
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
|
+
The deterministic ladder is:
|
|
62
|
+
|
|
63
|
+
1. full diagnostic;
|
|
64
|
+
2. omit explanation;
|
|
65
|
+
3. limit diagnostic collections;
|
|
66
|
+
4. compact recovery to actionable keys;
|
|
67
|
+
5. retain the action-only envelope.
|
|
68
|
+
|
|
69
|
+
Human diagnostics lead with `What is required` and next steps before explaining
|
|
70
|
+
what happened. If their declared ceiling binds, the compact text still begins
|
|
71
|
+
with the required action and points to structured JSON for the bounded recovery
|
|
72
|
+
envelope.
|
|
73
|
+
|
|
74
|
+
## Executable Assurance
|
|
75
|
+
|
|
76
|
+
`pnpm quality:recovery-closure` builds the current CLI and replays 22 refusal
|
|
77
|
+
contracts in isolated trackers. Ten representative, high-frequency failure
|
|
78
|
+
paths are also ratcheted by
|
|
79
|
+
`scripts/release/diagnostic-output-baseline.json`. The gate requires every row
|
|
80
|
+
to remain within the SDK-declared JSON ceiling and retain a mechanically
|
|
81
|
+
actionable correction. It reports the aggregate original and emitted token
|
|
82
|
+
estimates without claiming a reduction when no degradation was required.
|
|
83
|
+
|
|
84
|
+
The baseline is a coverage ratchet, not permission to weaken a ceiling. Its
|
|
85
|
+
negative control requires a missing baseline probe to fail. The existing
|
|
86
|
+
refusal-closure negative controls independently prove that incomplete domains,
|
|
87
|
+
broken retries, and malformed recovery envelopes remain blocking findings.
|
|
88
|
+
|
|
89
|
+
Run the focused proof with:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pnpm build
|
|
93
|
+
node scripts/release/refusal-closure-gate.mjs
|
|
94
|
+
node scripts/run-tests.mjs test -- \
|
|
95
|
+
tests/unit/sdk/agent-output-contracts.spec.ts \
|
|
96
|
+
tests/unit/cli/error-guidance.spec.ts \
|
|
97
|
+
tests/unit/scripts/refusal-closure-gate.spec.ts
|
|
98
|
+
```
|
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/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), and [pm-2qvq7a](../.agents/pm/issues/pm-2qvq7a.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), and [pm-2qvq7a](../.agents/pm/issues/pm-2qvq7a.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
|
|
|
@@ -179,6 +179,13 @@ key. Health retains at most 100 warning rows and reports `warning_count`,
|
|
|
179
179
|
projection unless `--full` is explicit, keeping the failing check identities
|
|
180
180
|
and warning codes inside the ordinary budget.
|
|
181
181
|
|
|
182
|
+
Failure transports use the companion
|
|
183
|
+
[Diagnostic Output Contracts](DIAGNOSTIC_OUTPUT_CONTRACTS.md). Those contracts
|
|
184
|
+
bind errors, warnings, validation summaries, and recovery bundles independently
|
|
185
|
+
from successful command results. Corrective actions precede explanation and
|
|
186
|
+
survive every degradation stage, while untruncated JSON avoids a per-call
|
|
187
|
+
receipt tax.
|
|
188
|
+
|
|
182
189
|
## SDK and Package Usage
|
|
183
190
|
|
|
184
191
|
Typed `PmClient` read methods accept `PmReadOutputOptions` directly:
|
|
@@ -65,6 +65,43 @@ Generic action hosts use `item-reopen` with required `id` and `reason` fields.
|
|
|
65
65
|
The action participates in the generated action schema, SDK dispatch coverage,
|
|
66
66
|
CLI/SDK parameter parity, command grammar, and MCP `pm_run` surface.
|
|
67
67
|
|
|
68
|
+
## Tracker Preflight Recovery
|
|
69
|
+
|
|
70
|
+
Every SDK command that requires project state now enters through one shared
|
|
71
|
+
filesystem preflight instead of maintaining a command-local settings check.
|
|
72
|
+
The public aggregate SDK exposes the same primitive for packages and embedded
|
|
73
|
+
hosts:
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
import {
|
|
77
|
+
assertInitializedTracker,
|
|
78
|
+
assertReadableTrackerRoot,
|
|
79
|
+
} from "@unbrained/pm-cli/sdk";
|
|
80
|
+
|
|
81
|
+
await assertReadableTrackerRoot(candidateRoot); // an empty directory is valid
|
|
82
|
+
await assertInitializedTracker(projectRoot); // settings.json is required
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The refusal contract distinguishes four states before any command-specific
|
|
86
|
+
read or mutation begins:
|
|
87
|
+
|
|
88
|
+
| Selected root state | Code | Exit | Recovery |
|
|
89
|
+
| --- | --- | ---: | --- |
|
|
90
|
+
| Path does not exist | `tracker_root_missing` | 3 | Tokenized, non-interactive `pm --pm-path <path> init --defaults --agent-guidance skip` |
|
|
91
|
+
| Directory exists but `settings.json` does not | `tracker_not_initialized` | 3 | The same initialization retry |
|
|
92
|
+
| Path or ancestor is a regular file | `tracker_root_not_directory` | 2 | Select a directory; never suggest `pm init` against the file |
|
|
93
|
+
| Directory cannot be read or searched | `tracker_root_unreadable` | 1 | Repair permissions, then retry the same selected root |
|
|
94
|
+
|
|
95
|
+
`listTrackerPreflightRecoveryContracts` publishes this four-state corpus from
|
|
96
|
+
`@unbrained/pm-cli/sdk/contracts`.
|
|
97
|
+
`scoreTrackerPreflightRecoveryClosure` verifies code, exit class, recovery kind,
|
|
98
|
+
and executable retry evidence. The repository recovery gate runs these probes
|
|
99
|
+
beside the 18 closed-domain probes, so its ratcheted corpus is 22 and a removed
|
|
100
|
+
state, failed retry, or unsafe file-path initialization suggestion blocks the
|
|
101
|
+
release. The surface-replication gate separately requires at least 50 shared
|
|
102
|
+
preflight invocations across the 45 migrated SDK modules and forbids the former
|
|
103
|
+
inline error body from returning.
|
|
104
|
+
|
|
68
105
|
## Duplicate Intake
|
|
69
106
|
|
|
70
107
|
Create and copy similarity governance inspect all lifecycle statuses. The
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Relationship graph semantics
|
|
2
2
|
|
|
3
|
-
Tracked by [pm-4jqm](../.agents/pm/decisions/pm-4jqm.toon), [pm-dwj33e](../.agents/pm/decisions/pm-dwj33e.toon), [pm-ju83](../.agents/pm/features/pm-ju83.toon), [pm-8xr8](../.agents/pm/stories/pm-8xr8.toon), [pm-m2il](../.agents/pm/chores/pm-m2il.toon), [pm-jiusod](../.agents/pm/issues/pm-jiusod.toon), [pm-mfvsng](../.agents/pm/issues/pm-mfvsng.toon), [pm-9gzr4r](../.agents/pm/issues/pm-9gzr4r.toon), [pm-xvt7ps](../.agents/pm/issues/pm-xvt7ps.toon),
|
|
3
|
+
Tracked by [pm-4jqm](../.agents/pm/decisions/pm-4jqm.toon), [pm-dwj33e](../.agents/pm/decisions/pm-dwj33e.toon), [pm-ju83](../.agents/pm/features/pm-ju83.toon), [pm-8xr8](../.agents/pm/stories/pm-8xr8.toon), [pm-m2il](../.agents/pm/chores/pm-m2il.toon), [pm-jiusod](../.agents/pm/issues/pm-jiusod.toon), [pm-mfvsng](../.agents/pm/issues/pm-mfvsng.toon), [pm-9gzr4r](../.agents/pm/issues/pm-9gzr4r.toon), [pm-xvt7ps](../.agents/pm/issues/pm-xvt7ps.toon), [pm-ouyq3n](../.agents/pm/issues/pm-ouyq3n.toon), [pm-ayg31c](../.agents/pm/issues/pm-ayg31c.toon), [pm-3dyec2](../.agents/pm/issues/pm-3dyec2.toon), [pm-c90tfh](../.agents/pm/issues/pm-c90tfh.toon), and [pm-ob9z4y](../.agents/pm/features/pm-ob9z4y.toon).
|
|
4
4
|
|
|
5
5
|
## Decision
|
|
6
6
|
|
|
@@ -10,7 +10,17 @@ The alternatives were rejected as follows: a closed enum cannot model applicatio
|
|
|
10
10
|
|
|
11
11
|
## Contract
|
|
12
12
|
|
|
13
|
-
Each relationship kind declares direction, inverse,
|
|
13
|
+
Each relationship kind declares direction, inverse, a traversal family,
|
|
14
|
+
optional typed-outcome traversal direction, ordering and hierarchy
|
|
15
|
+
participation, optional temporal order, incoming and outgoing cardinality,
|
|
16
|
+
lifecycle, aliases, payload schema, self-edge policy, and compatibility version.
|
|
17
|
+
Built-ins normalize legacy `related_to`, `depends_on`, `child_of`,
|
|
18
|
+
`parent_child`, `epic`, and `task` spellings. Unknown custom kinds remain
|
|
19
|
+
importable only after their definitions are registered, preventing algorithms
|
|
20
|
+
from guessing their meaning. Omitted custom traversal metadata remains
|
|
21
|
+
compatible: hierarchy and ordering declarations select their corresponding
|
|
22
|
+
families, undirected kinds are associative, and other directed kinds are
|
|
23
|
+
semantic.
|
|
14
24
|
|
|
15
25
|
`recurs_from` is the canonical recurrence relation: `new --recurs_from--> old`
|
|
16
26
|
means the source is a later event with the same observable failure identity as
|
|
@@ -153,10 +163,9 @@ await assertRelationshipGraphAdapterConformance(adapter, {
|
|
|
153
163
|
workspace: "isolated-conformance-workspace",
|
|
154
164
|
});
|
|
155
165
|
|
|
156
|
-
const portfolio = federateRelationshipGraphSnapshots(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
);
|
|
166
|
+
const portfolio = federateRelationshipGraphSnapshots([productA, productB], {
|
|
167
|
+
createdAt: new Date().toISOString(),
|
|
168
|
+
});
|
|
160
169
|
```
|
|
161
170
|
|
|
162
171
|
`createRelationshipGraphScaleFixture` supplies reiterable lazy `nodes` and
|
|
@@ -251,6 +260,14 @@ for domain packages that need more than generic adjacency:
|
|
|
251
260
|
- `enumerateRelationshipPaths` returns bounded simple paths with edge evidence,
|
|
252
261
|
cost metadata, cancellation, direction/kind filters, and explicit truncation.
|
|
253
262
|
|
|
263
|
+
An explicit kind filter may include `traversal: "semantic"` kinds on either
|
|
264
|
+
hierarchy or ordering walks, giving package-defined lineage edges a bounded
|
|
265
|
+
semantic traversal surface without pretending that they are structural or
|
|
266
|
+
scheduling edges. Default walks remain family-strict when no kind filter is
|
|
267
|
+
provided. Association kinds refuse these walks with an `impact --direction
|
|
268
|
+
both` recovery route; selecting the other structural family points to the
|
|
269
|
+
matching hierarchy or ordering commands.
|
|
270
|
+
|
|
254
271
|
All semantic walks are breadth-first and deterministic. `limit`, `maxDepth`,
|
|
255
272
|
and `after` provide bounded continuation for hierarchy and ordering walks;
|
|
256
273
|
path enumeration separately bounds returned paths and expanded partial paths.
|
|
@@ -281,17 +298,28 @@ identities and structured rows proven to contradict scalar blocker precedence.
|
|
|
281
298
|
censuses so repair can tighten their ceilings without weakening the
|
|
282
299
|
information-bearing floor. `articulation_points` and `bridge_edges` reuse the exact cut-structure
|
|
283
300
|
algorithm; outcome metrics count explicit `Milestone` titles beginning with
|
|
284
|
-
`Outcome milestone:` and follow
|
|
285
|
-
|
|
301
|
+
`Outcome milestone:` and follow the registry's declared
|
|
302
|
+
`outcomeTraversal` directions toward them. The audit publishes that exact
|
|
303
|
+
`outcome_reachability_basis` direction groups beside the rates, using sorted
|
|
304
|
+
comma-separated kind names so consumers never infer lineage meaning from
|
|
305
|
+
labels while repeated direction labels stay out of the token surface. Built-in
|
|
306
|
+
hierarchy, implementation, verification,
|
|
307
|
+
discovery, incident, recurrence, and supersession edges opt in explicitly;
|
|
308
|
+
`supersedes` traverses both directions so an archived predecessor remains
|
|
309
|
+
connected to the replacement outcome lineage. Generic `related` and ordering
|
|
310
|
+
edges declare no outcome traversal and cannot satisfy the metric. Active and
|
|
311
|
+
terminal populations are reported separately, with integer
|
|
286
312
|
basis-point rates and all-status reachable/unreachable totals; the explicit
|
|
287
313
|
outcome milestones are roots, not work subjects, and are excluded from those
|
|
288
314
|
populations. Rate or
|
|
289
315
|
all-status floors are lifecycle-stable; an absolute active-population floor is
|
|
290
316
|
invalid because completing reachable work legitimately moves it into the
|
|
291
|
-
terminal population.
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
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.
|
|
295
323
|
|
|
296
324
|
```ts
|
|
297
325
|
import {
|
|
@@ -318,6 +346,63 @@ policy findings. A VCS, company operating model, digital twin, or other
|
|
|
318
346
|
non-project domain can replace the assembly adapter while reusing the same
|
|
319
347
|
registry, traversal, event, context, and audit contracts.
|
|
320
348
|
|
|
349
|
+
### Relationship assurance sources
|
|
350
|
+
|
|
351
|
+
Repository assurance can ratchet graph quality without baking one project's
|
|
352
|
+
policy into the graph kernel. A `dependency_kind` measurement may partition a
|
|
353
|
+
canonical dependency kind by exact `source_kind`, by `source_kind_prefix`, or
|
|
354
|
+
by whether provenance is present or missing. These filters are mutually
|
|
355
|
+
exclusive and preserve the unfiltered measurement contract. This supports
|
|
356
|
+
independent evidence-backed and uncited-edge floors or ceilings while keeping
|
|
357
|
+
the dependency vocabulary extensible.
|
|
358
|
+
|
|
359
|
+
The `prose_edge_gap` source measures distinct holder-target pairs where item
|
|
360
|
+
descriptions, bodies, comments, notes, or learnings mention another canonical
|
|
361
|
+
item but no structured relationship exists in either direction. It performs one
|
|
362
|
+
bounded pass over the supplied items, resolves the collected mentions after the
|
|
363
|
+
canonical id set is complete, reports the exact gap count, partitions the result
|
|
364
|
+
into `explicit_subject` and `implicit_subject` pairs, and caps contributor
|
|
365
|
+
diagnostics with `sample_limit`. Reasoned exemptions may name a whole holder,
|
|
366
|
+
one holder-target pair, or a text fragment within one holder; an exemption
|
|
367
|
+
without a non-empty reason is invalid. This makes roadmap ledgers, negative
|
|
368
|
+
statements, and analysis subjects explicit policy rather than hidden
|
|
369
|
+
false-positive suppression.
|
|
370
|
+
|
|
371
|
+
```ts
|
|
372
|
+
const evidenceBlocks = {
|
|
373
|
+
kind: "dependency_kind" as const,
|
|
374
|
+
dependency_kind: "blocks",
|
|
375
|
+
source_kind_prefix: "evidence:",
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
const unlinkedMentions = {
|
|
379
|
+
kind: "prose_edge_gap" as const,
|
|
380
|
+
sample_limit: 25,
|
|
381
|
+
exemptions: [
|
|
382
|
+
{
|
|
383
|
+
holder_id: "roadmap-ledger",
|
|
384
|
+
reason: "The ledger inventories work without asserting pairwise edges.",
|
|
385
|
+
},
|
|
386
|
+
],
|
|
387
|
+
};
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Assurance assertions should pin these measurements to observed repository
|
|
391
|
+
baselines: an evidence partition uses a non-regression floor, while uncited
|
|
392
|
+
edges and prose gaps use ceilings. Negative controls must prove the observed
|
|
393
|
+
value passes and a one-unit regression fails before the assertions join the
|
|
394
|
+
repository's graph-composition gate.
|
|
395
|
+
|
|
396
|
+
The scale acceptance runs the public SDK over one million items whose 999,999
|
|
397
|
+
prose mentions each have a corresponding structured edge. It verifies an exact
|
|
398
|
+
zero-gap result, bounded empty diagnostics, a 2,999,998-unit cost receipt, and
|
|
399
|
+
the real item scan count:
|
|
400
|
+
|
|
401
|
+
```bash
|
|
402
|
+
pnpm build
|
|
403
|
+
node --max-old-space-size=4096 scripts/benchmarks/prose-edge-gap-scale.mjs
|
|
404
|
+
```
|
|
405
|
+
|
|
321
406
|
The native workspace adapter is `pm graph <subcommand>`, also available as
|
|
322
407
|
`PmClient.graph`, `runAction({ action: "graph" })`, and the MCP `pm_graph`
|
|
323
408
|
tool. `ancestors`/`descendants`/`predecessors`/`successors` expose the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# SDK Primitive Inventory
|
|
2
2
|
|
|
3
|
-
Tracked work: [pm-lodl](../.agents/pm/tasks/pm-lodl.toon), [pm-8778](../.agents/pm/tasks/pm-8778.toon), [pm-rjqr](../.agents/pm/features/pm-rjqr.toon), [pm-oslr](../.agents/pm/features/pm-oslr.toon), capstone [pm-9x6e](../.agents/pm/tasks/pm-9x6e.toon), parent [pm-usfg](../.agents/pm/epics/pm-usfg.toon).
|
|
3
|
+
Tracked work: [pm-lodl](../.agents/pm/tasks/pm-lodl.toon), [pm-8778](../.agents/pm/tasks/pm-8778.toon), [pm-rjqr](../.agents/pm/features/pm-rjqr.toon), [pm-oslr](../.agents/pm/features/pm-oslr.toon), [pm-6qiwan](../.agents/pm/chores/pm-6qiwan.toon), capstone [pm-9x6e](../.agents/pm/tasks/pm-9x6e.toon), parent [pm-usfg](../.agents/pm/epics/pm-usfg.toon).
|
|
4
4
|
|
|
5
5
|
This inventory records the completed SDK-first migration for the principle `project management = context management`.
|
|
6
6
|
CLI and MCP modules now import shared host services through `src/sdk/runtime-primitives.ts`; direct `src/core` imports, type-only edges, re-exports, and computed dynamic imports are unconditionally rejected by the static quality gate. There is no allowance file or ratchet escape hatch.
|
|
@@ -18,6 +18,20 @@ CLI and MCP modules now import shared host services through `src/sdk/runtime-pri
|
|
|
18
18
|
|
|
19
19
|
`src/sdk/runtime-primitives.ts` is the curated low-level seam for presentation hosts. It exposes filesystem, schema, history, extension-runtime, telemetry, search, output, and storage services needed to compose the shipped CLI and MCP adapters. External integrations should still prefer typed `PmClient` and top-level SDK operations; runtime primitives exist for embedded hosts that need to build an equivalent presentation layer without private imports.
|
|
20
20
|
|
|
21
|
+
## Tracker Preflight Primitive
|
|
22
|
+
|
|
23
|
+
`assertInitializedTracker` is the shared SDK boundary for commands that require
|
|
24
|
+
an initialized project, while `assertReadableTrackerRoot` supports low-level
|
|
25
|
+
metadata enumeration that intentionally accepts an empty directory. The former
|
|
26
|
+
replaced 50 literal checks across 45 SDK modules. It preserves one structured
|
|
27
|
+
error vocabulary and one exact recovery contract for CLI, MCP dispatch through
|
|
28
|
+
the SDK runtime, first-party packages, and external SDK consumers.
|
|
29
|
+
|
|
30
|
+
The preflight is public from the aggregate SDK; its four-state static recovery
|
|
31
|
+
corpus is also public from `@unbrained/pm-cli/sdk/contracts`. A source-derived
|
|
32
|
+
ratchet prevents the adoption count from falling below 50 and refuses the old
|
|
33
|
+
inline tracker-not-initialized message anywhere under `src/sdk`.
|
|
34
|
+
|
|
21
35
|
## Promotion Partition
|
|
22
36
|
|
|
23
37
|
| Promotion item | Primitive family | Primary private domains to promote |
|
package/docs/TESTING.md
CHANGED
|
@@ -366,6 +366,18 @@ 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 22 refusal contracts and ratchets ten representative failure
|
|
376
|
+
paths against `PM_DIAGNOSTIC_OUTPUT_BUDGET_CONTRACTS`. Every diagnostic must fit
|
|
377
|
+
its declared JSON ceiling and preserve a mechanically actionable correction;
|
|
378
|
+
the missing-probe negative control proves that the diagnostic corpus cannot
|
|
379
|
+
silently shrink.
|
|
380
|
+
|
|
369
381
|
The gate derives every supported harness, model, session, and provenance
|
|
370
382
|
environment key from the SDK-owned harness descriptor registry. It deletes
|
|
371
383
|
those host inputs before each fixture invocation, then supplies only the
|
|
@@ -480,6 +492,9 @@ pm test <item-id> --metric-below coverage=100 --metric-diff p95_latency
|
|
|
480
492
|
|
|
481
493
|
Measurements are stored on the producing `test_runs` row, retained with the
|
|
482
494
|
bounded run history, and exposed consistently by CLI, SDK, MCP, and contracts.
|
|
495
|
+
Each recorded row also keeps a bounded `executions` list with the exact linked
|
|
496
|
+
command plus its requested and effective `pm_context_mode`, so tracker-backed
|
|
497
|
+
verification remains attributable after the transient process logs are gone.
|
|
483
498
|
|
|
484
499
|
## Linked-Test Assertions
|
|
485
500
|
|
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.22"
|
|
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.22",
|
|
17
17
|
"author": {
|
|
18
18
|
"name": "unbrained",
|
|
19
19
|
"url": "https://github.com/unbraind/pm-cli"
|
package/package.json
CHANGED