@unbrained/pm-cli 2026.9.8 → 2026.9.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/pm-user/SKILL.md +2 -2
- package/.agents/skills/pm-user/references/ECOSYSTEM_PLANNING.md +1 -1
- package/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +38 -2
- package/dist/cli/command-namespaces.d.ts +9 -0
- package/dist/cli/command-namespaces.js +2 -0
- package/dist/cli/help-content.js +1 -1
- package/dist/cli/help-json-payload.d.ts +5 -1
- package/dist/cli/help-json-payload.js +2 -2
- package/dist/cli/main.d.ts +1 -0
- package/dist/cli/main.js +3 -3
- package/dist/cli/register-list-query.js +4 -4
- package/dist/cli/register-mutation.d.ts +0 -5
- package/dist/cli/register-mutation.js +2 -2
- package/dist/cli/register-operations.d.ts +0 -5
- package/dist/cli/register-operations.js +1 -1
- package/dist/cli-bundle/bundle-manifest.json +154 -154
- package/dist/cli-bundle/chunks/chunk-4SFBH77G.js +2233 -0
- package/dist/cli-bundle/chunks/{chunk-LEZOUXG6.js → chunk-74RGSPLL.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-7WIHZI2M.js +5 -0
- package/dist/cli-bundle/chunks/{chunk-JAAEYHUA.js → chunk-EOCKPCEY.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-GLQMKUGP.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-FLDWYEND.js → chunk-I6XT3DLQ.js} +62 -60
- package/dist/cli-bundle/chunks/chunk-MACGGTLQ.js +29 -0
- package/dist/cli-bundle/chunks/chunk-NKOYVKFM.js +3 -0
- package/dist/cli-bundle/chunks/{chunk-YVEQ2AMO.js → chunk-P6BEYAON.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-G5ADGQ2D.js → chunk-PYUITRSV.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-T3AMFUCN.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-XOD2PCB6.js → chunk-TSWEX72T.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-YKQTETJI.js +235 -0
- package/dist/cli-bundle/chunks/{register-list-query-KSK3R63M.js → register-list-query-CUIW7SSE.js} +7 -7
- package/dist/cli-bundle/chunks/register-mutation-5F5CYUWZ.js +20 -0
- package/dist/cli-bundle/chunks/register-operations-XIZPLPQY.js +2 -0
- package/dist/cli-bundle/chunks/{register-setup-BQ5SVD4B.js → register-setup-JVGPCAIL.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-RXT4P5QH.js → chunk-26O2WB73.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-5YU75QLV.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-EE5QSM4Z.js → chunk-7N5MRONP.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-B2CMFYRZ.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-OPFHFGDD.js → chunk-CRY5MHEI.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-COPBO5HW.js → chunk-F6WKFXBT.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-HJVARYM3.js → chunk-FHUARRMA.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-3WRPWLA7.js → chunk-M36SF4GE.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-OROZM37I.js +177 -0
- package/dist/cli-bundle/focused-chunks/{chunk-7MBUII7U.js → chunk-PNGYYQY7.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-SL5YVVPV.js +58 -0
- package/dist/cli-bundle/focused-chunks/chunk-TPOL4TWE.js +9 -0
- package/dist/cli-bundle/focused-chunks/{chunk-RMWES4M6.js → chunk-U5SHHU7E.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-XSMA2W6Q.js +12 -0
- package/dist/cli-bundle/focused-chunks/chunk-ZAWAL2CG.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-ZDNAWWQI.js +26 -0
- package/dist/cli-bundle/focused-chunks/{chunk-DUN4IXYN.js → chunk-ZJHYQOTM.js} +2 -2
- package/dist/cli-bundle/main.js +26 -26
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +2 -2
- package/dist/cli-bundle/sdk-core.js +29 -29
- package/dist/cli-bundle/sdk-governance.js +1 -1
- package/dist/cli-bundle/sdk-graph.js +1 -1
- package/dist/cli-bundle/sdk-merge.js +42 -42
- package/dist/cli-bundle/sdk-query.js +1 -1
- package/dist/cli-bundle/sdk-runtime.js +1 -1
- package/dist/cli-bundle/sdk-testing.js +1 -1
- package/dist/cli-bundle/sdk.js +10 -10
- package/dist/core/config/nested-settings.js +1 -1
- package/dist/core/policy/workflow-policy-schema.d.ts +312 -0
- package/dist/core/policy/workflow-policy-schema.js +2 -0
- package/dist/core/policy/workflow-policy-store.d.ts +24 -0
- package/dist/core/policy/workflow-policy-store.js +2 -0
- package/dist/core/policy/workflow-policy.d.ts +139 -0
- package/dist/core/policy/workflow-policy.js +2 -0
- package/dist/core/shared/constants.js +1 -1
- package/dist/core/store/item-store.js +1 -1
- package/dist/core/store/settings-validator.d.ts +1 -0
- package/dist/core/store/settings-validator.js +1 -1
- package/dist/core/store/settings.js +1 -1
- package/dist/mcp/tool-definitions.js +1 -1
- package/dist/sdk/agent/item-addressing.js +1 -1
- package/dist/sdk/agent-capability-contracts.js +1 -1
- package/dist/sdk/cli-bootstrap.js +1 -1
- package/dist/sdk/cli-contracts/command-aliases.d.ts +11 -1
- package/dist/sdk/cli-contracts/command-aliases.js +1 -1
- package/dist/sdk/cli-contracts/enum-contracts.d.ts +1 -1
- package/dist/sdk/cli-contracts/enum-contracts.js +1 -1
- package/dist/sdk/cli-contracts/flag-contracts.js +1 -1
- package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +1 -1
- package/dist/sdk/cli-contracts/grammar-contracts.js +1 -1
- package/dist/sdk/cli-contracts/runtime-contracts.d.ts +4 -1
- package/dist/sdk/cli-contracts/runtime-contracts.js +1 -1
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +1 -1
- package/dist/sdk/cli-contracts/tool-schema.d.ts +3 -3
- package/dist/sdk/cli-contracts/tool-schema.js +1 -1
- package/dist/sdk/cli-contracts/typed-action-inputs.d.ts +2 -0
- package/dist/sdk/cli-contracts.d.ts +1 -1
- package/dist/sdk/cli-contracts.js +1 -1
- package/dist/sdk/completion.js +375 -347
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -1
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1 -1
- package/dist/sdk/governance/validate.d.ts +3 -1
- package/dist/sdk/governance/validate.js +1 -1
- package/dist/sdk/governance/workflow-completeness.d.ts +32 -0
- package/dist/sdk/governance/workflow-completeness.js +2 -0
- package/dist/sdk/governance/workflow-policy.d.ts +47 -0
- package/dist/sdk/governance/workflow-policy.js +4 -0
- package/dist/sdk/governance.d.ts +1 -0
- package/dist/sdk/governance.js +1 -1
- package/dist/sdk/index.d.ts +2 -2
- package/dist/sdk/index.js +1 -1
- package/dist/sdk/lifecycle/claim.js +1 -1
- package/dist/sdk/lifecycle/create.js +1 -1
- package/dist/sdk/lifecycle/lifecycle-transitions.d.ts +1 -1
- package/dist/sdk/lifecycle/lifecycle-transitions.js +1 -1
- package/dist/sdk/lifecycle/mcp-actions.js +1 -1
- package/dist/sdk/lifecycle/recurrence-parsers.d.ts +1 -1
- package/dist/sdk/lifecycle/recurrence-parsers.js +1 -1
- package/dist/sdk/lifecycle/restore.js +1 -1
- package/dist/sdk/lifecycle/task-composition.d.ts +17 -0
- package/dist/sdk/lifecycle/task-composition.js +2 -0
- package/dist/sdk/lifecycle/update.js +1 -1
- package/dist/sdk/package-import-adapters.js +1 -1
- package/dist/sdk/public-surface.json +1 -1
- package/dist/sdk/query/search-contracts.d.ts +27 -0
- package/dist/sdk/query/search-contracts.js +1 -1
- package/dist/sdk/query/search.d.ts +6 -4
- package/dist/sdk/query/search.js +2 -2
- package/dist/sdk/query/workspace-contracts.d.ts +3 -0
- package/dist/sdk/query/workspace-contracts.js +2 -0
- package/dist/sdk/read-output-contracts.d.ts +1 -1
- package/dist/sdk/read-output-contracts.js +1 -1
- package/dist/sdk/runtime-input.js +1 -1
- package/dist/sdk/runtime-public-contracts.d.ts +2 -1
- package/dist/sdk/runtime.d.ts +73 -9
- package/dist/sdk/runtime.js +1 -1
- package/dist/sdk/schema.d.ts +2 -1
- package/dist/sdk/schema.js +1 -1
- package/dist/types.d.ts +4 -0
- package/dist/types.js +1 -1
- package/docs/COMMANDS.md +36 -24
- package/docs/COMMAND_NAMESPACES.md +65 -0
- package/docs/CONFIGURATION.md +12 -1
- package/docs/LIFECYCLE_COMMANDS.md +77 -0
- package/docs/README.md +3 -0
- package/docs/READ_OUTPUT_CONTRACTS.md +5 -0
- package/docs/TESTING.md +10 -0
- package/docs/WORKFLOW_POLICIES.md +129 -0
- package/docs/generated/AGENT_CAPABILITY_ROUTING.md +6 -6
- package/docs/generated/AGENT_COMMAND_SURFACE.md +19 -0
- package/docs/generated/FLAG_LEXICON_BUDGETS.md +23 -5
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +11 -5
- package/marketplace.json +2 -2
- package/package.json +5 -5
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-digital-twin/package.json +1 -1
- package/packages/pm-governance-audit/README.md +4 -2
- 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/README.md +6 -4
- 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/dist/cli-bundle/chunks/chunk-3BZZA6A3.js +0 -5
- package/dist/cli-bundle/chunks/chunk-AMRDVX36.js +0 -235
- package/dist/cli-bundle/chunks/chunk-DAM4CBBR.js +0 -2202
- package/dist/cli-bundle/chunks/chunk-KR3RP4FH.js +0 -3
- package/dist/cli-bundle/chunks/chunk-NSAPNEYH.js +0 -2
- package/dist/cli-bundle/chunks/chunk-QOEKOECV.js +0 -29
- package/dist/cli-bundle/chunks/chunk-RHSFOMHU.js +0 -2
- package/dist/cli-bundle/chunks/register-mutation-IQ5C7U6O.js +0 -20
- package/dist/cli-bundle/chunks/register-operations-DWVHR2NC.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-IAUOUGVR.js +0 -177
- package/dist/cli-bundle/focused-chunks/chunk-KOOMJ54F.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-MZDXX7JY.js +0 -56
- package/dist/cli-bundle/focused-chunks/chunk-QHNETP77.js +0 -9
- package/dist/cli-bundle/focused-chunks/chunk-SDOL6FM2.js +0 -12
- package/dist/cli-bundle/focused-chunks/chunk-SQV4AAUC.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-WE3IUNIW.js +0 -26
- package/dist/cli-bundle/focused-chunks/chunk-YALOUBWJ.js +0 -2
package/docs/COMMANDS.md
CHANGED
|
@@ -54,8 +54,8 @@ JSON ceiling; TOON uses the smaller default agent ceiling.
|
|
|
54
54
|
| Family | Commands | Purpose |
|
|
55
55
|
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
56
56
|
| Bootstrap | `init`, `config`, `health`, `telemetry` | create and inspect tracker setup |
|
|
57
|
-
| Lifecycle | `create`, `copy`, `focus`, `claim`, `update`, `item reopen`, `append`, `close`, `release`, `delete
|
|
58
|
-
| Bulk | `item mutate`, `item complete`, `update
|
|
57
|
+
| Lifecycle | `create`, `copy`, `focus`, `claim`, `update`, `item reopen`, `append`, `close`, `release`, `close delete` | mutate item state, including terminal-work recurrence without duplicate creation |
|
|
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
59
|
| Scheduling | `meet`, `event`, `remind` | low-friction Meeting/Event/Reminder creation |
|
|
60
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
61
|
| Links | `files`, `docs`, `test`, `deps` | connect items to artifacts, tests, and relationships |
|
|
@@ -254,6 +254,16 @@ Use only one updated-at window per list call: `--today`, `--recent`, and `--upda
|
|
|
254
254
|
|
|
255
255
|
Keyword mode now applies the configured `search.max_results` default (50) when `--limit` is omitted, so a broad query no longer returns every hit. When the limit drops rows the result adds a top-level `total` (pre-limit match count).
|
|
256
256
|
|
|
257
|
+
### Default search mode (pm-n8a6e7)
|
|
258
|
+
|
|
259
|
+
A bare `pm search` runs in the mode the SDK resolves from `search.default_mode`, never from a literal in the CLI. `auto` (the default) picks `hybrid` exactly when the stored settings name the active embedding provider (`search.provider`, the same `configured` verdict `pm health` reports) and a vector store or extension adapter resolves, or when an extension search provider is active; every other workspace runs `keyword`. Auto-detected Ollama/LanceDB runtime defaults do not count as configured, so an unconfigured host never pays an embedding round-trip it did not ask for. A concrete `search.default_mode` (`keyword`, `semantic`, `hybrid`) pins the answer, and `--mode` always wins. The result reports `mode` (what ran, after any runtime fallback) beside `mode_source` (`explicit`, `settings`, or `auto`), so a caller can tell a chosen mode from a derived one (compact responses carry `mode_source` only for `settings`, since `explicit` is the caller's own choice and `auto` is the documented default); when the provider is unreachable a hybrid default still degrades to keyword hits with the usual `search_semantic_fallback` warning.
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
pm search "context budget" # auto: hybrid here because search.provider is configured and the index resolves
|
|
263
|
+
pm config project set search_default_mode keyword # pin keyword for a workspace that prefers exact-token results
|
|
264
|
+
pm search "context budget" --mode semantic # explicit request, mode_source: explicit
|
|
265
|
+
```
|
|
266
|
+
|
|
257
267
|
```bash
|
|
258
268
|
pm search "reminder validation queue" --match-mode and # require all three tokens
|
|
259
269
|
pm search "exact title phrase" --match-mode exact # contiguous-phrase match
|
|
@@ -394,28 +404,28 @@ pm list --status open --has-tests --no-files --json
|
|
|
394
404
|
|
|
395
405
|
## Bulk Operations
|
|
396
406
|
|
|
397
|
-
`update
|
|
407
|
+
`update many` and `close many` apply one change across a matched set with a dry-run preview and a rollback checkpoint. Both share the `--filter-*` scoping family (`--filter-status/-type/-tag/-priority/-sprint/-release/-parent/-assignee/-deadline-before|after/-updated-after|before/-created-after|before`) plus `--ids` for an explicit comma-separated allowlist intersected with the other filters. `update many` additionally accepts the missing-metadata selectors `--filter-ac-missing`/`--filter-estimates-missing`/`--filter-resolution-missing`/`--filter-metadata-missing` for bulk metadata backfill.
|
|
398
408
|
|
|
399
|
-
Both `update
|
|
409
|
+
Both `update many` and `close many` also accept the governance-field selectors `--filter-reviewer-missing`/`--filter-risk-missing`/`--filter-confidence-missing`/`--filter-sprint-missing`/`--filter-release-missing` and the content-field presence selectors under the `--filter-` prefix: `--filter-has-notes`/`--filter-no-notes`, `--filter-has-learnings`/`--filter-no-learnings`, `--filter-has-files`/`--filter-no-files`, `--filter-has-docs`/`--filter-no-docs`, `--filter-has-tests`/`--filter-no-tests`, `--filter-has-comments`/`--filter-no-comments`, `--filter-has-deps`/`--filter-no-deps`, `--filter-has-body`/`--filter-empty-body`, and `--filter-has-linked-command`/`--filter-no-linked-command`. These mirror the list/search presence filters and intersect with the rest of the scoping family, so you can bulk-select (for example) closed Tasks with no documented learnings before applying a change.
|
|
400
410
|
|
|
401
411
|
```bash
|
|
402
412
|
# Bulk metadata update by explicit id allowlist (compose with search --json | jq)
|
|
403
|
-
pm update
|
|
404
|
-
pm update
|
|
413
|
+
pm update many --ids pm-a,pm-b,pm-c --priority 1 --dry-run
|
|
414
|
+
pm update many --filter-tag wave:7 --reviewer maintainer-review
|
|
405
415
|
|
|
406
416
|
# Bulk-backfill a placeholder estimate onto open Tasks that have none
|
|
407
|
-
pm update
|
|
417
|
+
pm update many --filter-status open --filter-type Task --filter-estimates-missing --estimate 60 --dry-run
|
|
408
418
|
|
|
409
419
|
# Audited bulk close: routes EACH match through full `pm close` semantics
|
|
410
420
|
# (close validation, active-child orphan checks, blocked-edge cleanup) — unlike
|
|
411
421
|
# `update-many --status closed`, which bypasses them. A shared --reason is required
|
|
412
422
|
# and at least one filter is required so it never matches every item.
|
|
413
|
-
pm close
|
|
414
|
-
pm close
|
|
415
|
-
pm close
|
|
423
|
+
pm close many --filter-sprint S-12 --reason "Sprint S-12 acceptance criteria met" --dry-run
|
|
424
|
+
pm close many --filter-sprint S-12 --reason "Sprint S-12 acceptance criteria met"
|
|
425
|
+
pm close many --rollback close-many-20260604-abc123 # restore the batch
|
|
416
426
|
```
|
|
417
427
|
|
|
418
|
-
`close
|
|
428
|
+
`close many` skips already-terminal matches by default (pass `--force` to re-close), accepts `--completed-at <timestamp>` to preserve one shared actual-completion time across the batch, reports a per-item plan (`close`/`skip`, plus `active_child_ids` for parents that would be orphaned) under `--dry-run`, and writes a checkpoint by default (`--no-checkpoint` to disable). Checkpoints for both commands live under `.agents/pm/checkpoints/<command>/` and are restored with `--rollback <checkpoint-id>`.
|
|
419
429
|
|
|
420
430
|
When a flag is rejected with `Unknown option`, the error guidance now suggests the nearest supported flag (including abbreviations like `--desc` → `--description`) and notes when the flag is valid on a different command (for example `--type` on `test-all` points to `create`/`list`). Unknown-command guidance ranks agent verb synonyms first, bounded edit distance second, and substring matches last; `pm log` therefore points to `history`, `comments`, and `notes`, never a `catalog` command.
|
|
421
431
|
|
|
@@ -501,10 +511,10 @@ did-you-mean diagnostic instead of becoming an accidental custom field.
|
|
|
501
511
|
|
|
502
512
|
Repeated singular/plural list flags now accumulate, so `--tag a --tag b` is equivalent to `--tags a,b` (the same holds for `--status`, `--ids`, and `--fields` on read commands). Earlier versions silently kept only the last value. `list`/`search` also accept `--tags` as a never-block alias for the canonical read filter `--tag`.
|
|
503
513
|
|
|
504
|
-
`--tags` REPLACES the whole tag list. To edit tags without restating the full set, use the additive/subtractive flags on `create`/`update`/`update
|
|
514
|
+
`--tags` REPLACES the whole tag list. To edit tags without restating the full set, use the additive/subtractive flags on `create`/`update`/`update many`:
|
|
505
515
|
|
|
506
516
|
- `--add-tags <value>` adds tags to the existing list without replacing it (repeatable; CSV or JSON-array values accepted).
|
|
507
|
-
- `--remove-tags <value>` prunes the given tags from the existing list (repeatable; CSV or JSON-array). Available on `update`/`update
|
|
517
|
+
- `--remove-tags <value>` prunes the given tags from the existing list (repeatable; CSV or JSON-array). Available on `update`/`update many` only — `create` has no prior tags to remove.
|
|
508
518
|
|
|
509
519
|
```bash
|
|
510
520
|
pm update pm-abc1 --add-tags urgent,backend # keeps existing tags, adds two
|
|
@@ -512,7 +522,7 @@ pm update pm-abc1 --remove-tags stale # drops "stale", keeps the rest
|
|
|
512
522
|
pm create "New backend task" --add-tags backend,p1
|
|
513
523
|
```
|
|
514
524
|
|
|
515
|
-
Acceptance criteria get the same additive treatment on `update`/`update
|
|
525
|
+
Acceptance criteria get the same additive treatment on `update`/`update many`: `--acceptance-criteria`/`--ac` explicitly REPLACES the whole value and returns an `acceptance_criteria_replaced:<before-count>:<after-count>` warning when it changes existing criteria. `--add-ac <text>` appends one criterion (repeatable; deduped on exact text), while `--remove-ac <text>` removes one criterion by exact text match. Every requested removal must match: otherwise the mutation fails atomically with `acceptance_criteria_remove_unmatched` and reports the unmatched selectors, without applying valid removals or additions. Whole-value replacement cannot be combined with additive flags in one mutation. Criteria are stored with semicolon-space separators, so one criterion cannot contain a semicolon. Disjoint `--add-ac` edits from concurrent agents/branches merge cleanly instead of clobbering each other.
|
|
516
526
|
|
|
517
527
|
```bash
|
|
518
528
|
pm update pm-abc1 --add-ac "error path covered by a regression test"
|
|
@@ -545,7 +555,7 @@ pm update <id> \
|
|
|
545
555
|
--message "Append audit evidence"
|
|
546
556
|
```
|
|
547
557
|
|
|
548
|
-
`--expected` and `--actual` are short aliases for `--expected-result` and `--actual-result` on `create`/`update`/`update
|
|
558
|
+
`--expected` and `--actual` are short aliases for `--expected-result` and `--actual-result` on `create`/`update`/`update many`, matching the aliases `pm close` already accepts:
|
|
549
559
|
|
|
550
560
|
```bash
|
|
551
561
|
pm update <id> --expected "Retry succeeds after backoff" --actual "Retry threw on first attempt"
|
|
@@ -692,12 +702,12 @@ Use `pm close <id> "<reason>"` instead of `pm update --status closed`.
|
|
|
692
702
|
|
|
693
703
|
## Lifecycle Aliases
|
|
694
704
|
|
|
695
|
-
Lifecycle
|
|
705
|
+
Lifecycle composition flags combine claim, status, and close operations:
|
|
696
706
|
|
|
697
707
|
```bash
|
|
698
|
-
pm
|
|
699
|
-
pm
|
|
700
|
-
pm close
|
|
708
|
+
pm claim <id> --start # claim + move to the configured in-progress status
|
|
709
|
+
pm release <id> --pause # move to the configured open status + release claim
|
|
710
|
+
pm close <id> "<reason>" --release-assignment # close with evidence + release assignment
|
|
701
711
|
```
|
|
702
712
|
|
|
703
713
|
For lifecycle ownership commands, `--assignee <agent>` is accepted as an alias
|
|
@@ -705,9 +715,11 @@ for `--author <agent>` on `claim`, `release`, `start-task`, `pause-task`, and
|
|
|
705
715
|
`close-task`. Use `pm update --assignee <person>` when changing item metadata
|
|
706
716
|
rather than active work ownership.
|
|
707
717
|
|
|
708
|
-
|
|
718
|
+
The old task spellings remain hidden compatibility aliases. See [Lifecycle Commands and Ownership](LIFECYCLE_COMMANDS.md) for migration, typed SDK receipts, MCP controls, and partial-failure semantics.
|
|
719
|
+
|
|
720
|
+
Tracker references: [pm-eq4x](../.agents/pm/tasks/pm-eq4x.toon), [pm-ik19](../.agents/pm/tasks/pm-ik19.toon), [pm-qfte](../.agents/pm/tasks/pm-qfte.toon), [pm-98cz](../.agents/pm/features/pm-98cz.toon).
|
|
709
721
|
|
|
710
|
-
After `pm create` of a workable item type, the result includes a non-binding `next_transition` hint (`pm
|
|
722
|
+
After `pm create` of a workable item type, the result includes a non-binding `next_transition` hint (`pm claim <id> --start` → `in_progress`) when the workflow defines a distinct in-progress status. This nudges agents to move work through `in_progress` instead of jumping straight from `open` to `closed`. Scheduling/reference types (Event, Meeting, Reminder, Milestone, Decision) never receive the hint. (GH-216)
|
|
711
723
|
|
|
712
724
|
## Scheduling Shortcuts
|
|
713
725
|
|
|
@@ -898,7 +910,7 @@ Use dry-run modes before broad lifecycle or cleanup changes.
|
|
|
898
910
|
- `embeddings` removes keyword/semantic artifacts (`search/embeddings.jsonl`, `search/vectorization-status.json`, `search/lancedb/`) plus `search/pending-refresh.json` and its gate, preventing a background worker from rebuilding a partial index against an empty ledger. Rebuild with keyword reindex and semantic reindex when enabled.
|
|
899
911
|
- `locks` removes only provably expired locks, using embedded `created_at + ttl_seconds`. Active, unreadable, or unparseable locks remain. The result reports `scanned`, `removed`, and `retained` counts.
|
|
900
912
|
|
|
901
|
-
The `checkpoints` scope prunes bulk-mutation rollback checkpoints under `checkpoints/` (written by `pm update
|
|
913
|
+
The `checkpoints` scope prunes bulk-mutation rollback checkpoints under `checkpoints/` (written by `pm update many`/`pm close many`) that are older than `checkpoints.retention_days` (default 14; set via `pm config <scope> set checkpoints_retention_days <n>`). Checkpoints whose `created_at` cannot be parsed are retained (safety-first, like the locks sweep), and the result includes a `checkpoints` summary (`scanned`/`removed`/`retained`/`retention_days`). Removing aged checkpoints permanently closes their `--rollback` window.
|
|
902
914
|
|
|
903
915
|
`--fix-hints` is a read-only flag: each failing check gains `details.fix_hints`, an array of `pm` command templates derived from the warning codes it raised (for example `pm history-repair <id>` for history drift, or `pm update <id> --reviewer "<name>"` for a missing reviewer). Generic hints may contain `<id>`/`<field>`/`<path>` placeholders the agent substitutes from the check's detail rows; the resolution check aliases concrete per-row commands and marks `fix_hints_truncated` when the list is summarized. It never mutates items. The mapping comes from the shared remediation registry that also backs `pm health --json` (see Self-Repair Remediation below), so agents gating on `pm validate` can auto-repair findings without hardcoding warning-code-to-command lookups.
|
|
904
916
|
|
|
@@ -906,7 +918,7 @@ The `checkpoints` scope prunes bulk-mutation rollback checkpoints under `checkpo
|
|
|
906
918
|
|
|
907
919
|
`--counts` keeps the validation envelope, check statuses, warning codes, scalar counts/totals, nested count maps, and fix summary totals while recursively omitting diagnostic and fix row arrays. False `*_truncated` markers are omitted; true markers, other false values, and zero counts remain. It is the preferred agent projection when deciding whether drift exists; remove it only when the affected ids or remediation rows are needed. The public SDK `projectValidateCounts` helper applies the identical projection to an already-computed `ValidateResult`.
|
|
908
920
|
|
|
909
|
-
By default the human view caps each diagnostic `*_item_ids` list at 5 entries and sets the matching `*_truncated` flag. `--json` **never** truncates those lists (machine consumers always receive the complete arrays), and `--all-affected-ids` (equivalent to `--verbose-diagnostics`) emits the full lists in human mode too — so bulk remediation can pipe every affected id straight into `pm update
|
|
921
|
+
By default the human view caps each diagnostic `*_item_ids` list at 5 entries and sets the matching `*_truncated` flag. `--json` **never** truncates those lists (machine consumers always receive the complete arrays), and `--all-affected-ids` (equivalent to `--verbose-diagnostics`) emits the full lists in human mode too — so bulk remediation can pipe every affected id straight into `pm update many`:
|
|
910
922
|
|
|
911
923
|
```bash
|
|
912
924
|
pm validate --check-metadata --all-affected-ids
|
|
@@ -1228,7 +1240,7 @@ Invariants:
|
|
|
1228
1240
|
- Promoting a step link preserves its semantic kind. `depends_on` normalizes to the canonical top-level `blocked_by`; `implements` and `verifies` remain first-class directed dependency kinds available to SDK relationship registries and graph consumers.
|
|
1229
1241
|
- Search keyword corpus includes plan_scope, step titles/bodies, decisions, discoveries, validation, and step linked items.
|
|
1230
1242
|
|
|
1231
|
-
`pm delete <id> --json` reports an explicit `outcome` (`deleted` or `would_delete`), `deleted` boolean, and `previous_status`. Compact and `--id-only` output use the mutation outcome as `status`, so agents never mistake the deleted item's former lifecycle state for the delete result.
|
|
1243
|
+
`pm close delete <id> --json` reports an explicit `outcome` (`deleted` or `would_delete`), `deleted` boolean, and `previous_status`. Compact and `--id-only` output use the mutation outcome as `status`, so agents never mistake the deleted item's former lifecycle state for the delete result.
|
|
1232
1244
|
|
|
1233
1245
|
## Machine Contracts
|
|
1234
1246
|
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Context and operations command namespaces
|
|
2
|
+
|
|
3
|
+
Tracked in [pm-kcs4](../.agents/pm/tasks/pm-kcs4.toon),
|
|
4
|
+
[pm-6apl](../.agents/pm/tasks/pm-6apl.toon), and
|
|
5
|
+
[pm-3i9q8g](../.agents/pm/tasks/pm-3i9q8g.toon).
|
|
6
|
+
|
|
7
|
+
The CLI groups navigation and maintenance under stable nouns. Existing root
|
|
8
|
+
spellings remain executable compatibility aliases with the same arguments,
|
|
9
|
+
results, exit codes, and SDK behavior.
|
|
10
|
+
|
|
11
|
+
| Native invocation | Compatibility spelling | Purpose |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| `pm context next` | `pm next` | Select ready work and explain blockers |
|
|
14
|
+
| `pm context focus` | `pm focus` | Read, set, or clear the focused item |
|
|
15
|
+
| `pm ops stats` | `pm stats` | Inspect tracker statistics |
|
|
16
|
+
| `pm ops health` | `pm health` | Diagnose tracker health |
|
|
17
|
+
| `pm ops validate` | `pm validate` | Validate metadata and history |
|
|
18
|
+
| `pm ops gc` | `pm gc` | Clean optional cache artifacts |
|
|
19
|
+
| `pm ops telemetry` | `pm telemetry` | Inspect and manage telemetry |
|
|
20
|
+
| `pm ops eval` | `pm eval` | Evaluate retrieval quality |
|
|
21
|
+
| `pm ops test-all` | `pm test-all` | Run selected linked tests |
|
|
22
|
+
| `pm ops reindex` | `pm reindex` | Refresh indexes through search-advanced |
|
|
23
|
+
| `pm ops normalize` | `pm normalize` | Normalize through an active governance package |
|
|
24
|
+
| `pm history events` | `pm events` | Read or follow committed mutation events |
|
|
25
|
+
|
|
26
|
+
`pm context --limit 10 --for orient` still produces a context snapshot.
|
|
27
|
+
`pm history <id> --verify` still reads and verifies one item's history.
|
|
28
|
+
Namespace leaves do not change either default operation.
|
|
29
|
+
|
|
30
|
+
## Discover only what the current task needs
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pm context next --limit 5 --ready-only
|
|
34
|
+
pm context focus --id pm-example
|
|
35
|
+
pm ops health --check-only --summary
|
|
36
|
+
pm ops validate --check-history-drift
|
|
37
|
+
pm history events --item pm-example --limit 10
|
|
38
|
+
pm ops --help
|
|
39
|
+
pm contracts --command "ops stats" --flags-only
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Help, contracts, and shell completion expose native paths. Compatibility aliases
|
|
43
|
+
remain declared in the SDK alias table. Alias guidance uses the existing
|
|
44
|
+
`ux.deprecation_hints` setting. Human-readable calls emit it on stderr; JSON and
|
|
45
|
+
quiet calls suppress it. Compact contract summaries omit duplicate root alias
|
|
46
|
+
rows; full and explicitly selected contracts retain them. Optional commands appear only when their providing package is active;
|
|
47
|
+
namespace placement does not promote package behavior into core.
|
|
48
|
+
|
|
49
|
+
## SDK and package integration
|
|
50
|
+
|
|
51
|
+
`PM_NAMESPACED_COMMAND_ALIASES` and `resolvePmCommandOperation` are exported
|
|
52
|
+
from `@unbrained/pm-cli/sdk` and `@unbrained/pm-cli/sdk/contracts`.
|
|
53
|
+
The resolver maps a native path such as `context next` to the existing SDK
|
|
54
|
+
operation identity `next`. Unknown paths are preserved. SDK functions, MCP
|
|
55
|
+
action names, extension activation selectors, and command hooks retain their
|
|
56
|
+
existing operation identities.
|
|
57
|
+
|
|
58
|
+
Packages that provide `reindex` or `normalize` keep their existing command
|
|
59
|
+
registration. The CLI places the registered handler beneath `ops` after
|
|
60
|
+
activation, preserving flags, argument parsing, and nested commands. A conflicting
|
|
61
|
+
native destination fails explicitly instead of silently replacing a handler.
|
|
62
|
+
|
|
63
|
+
Generated Bash, Zsh, and Fish scripts recognize namespace command positions and
|
|
64
|
+
skip global option values when selecting a leaf. Re-generate installed completion
|
|
65
|
+
scripts after upgrading with `pm completion <shell>` from guide-shell.
|
package/docs/CONFIGURATION.md
CHANGED
|
@@ -388,6 +388,16 @@ Advanced relevance tuning is opt-in:
|
|
|
388
388
|
When query expansion or rerank providers fail, `pm search` degrades gracefully and keeps the query runnable; warning codes are emitted in the result payload.
|
|
389
389
|
`pm search` filter metadata now reports `query_expansion_*` and `rerank_*` fields so automation can detect when advanced tuning is active.
|
|
390
390
|
|
|
391
|
+
`search.default_mode` decides the mode a bare `pm search` runs in (`--mode` always wins):
|
|
392
|
+
|
|
393
|
+
| Value | Behavior |
|
|
394
|
+
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
395
|
+
| `auto` | default; `hybrid` when `search.provider` names the active embedding provider and a vector store or extension adapter resolves (or an extension search provider is active), `keyword` otherwise |
|
|
396
|
+
| `keyword` | pin exact-token ranking for every bare search |
|
|
397
|
+
| `semantic`, `hybrid` | pin the semantic path; an unreachable provider still degrades to keyword hits with a `search_semantic_fallback` warning |
|
|
398
|
+
|
|
399
|
+
Every search result reports `mode_source` (`explicit`, `settings`, or `auto`) beside the effective `mode`.
|
|
400
|
+
|
|
391
401
|
Mutation commands invalidate keyword search caches immediately. Semantic vector refresh is controlled by `search.mutation_refresh_policy`:
|
|
392
402
|
|
|
393
403
|
| Policy | Behavior |
|
|
@@ -399,6 +409,7 @@ Mutation commands invalidate keyword search caches immediately. Semantic vector
|
|
|
399
409
|
Useful commands:
|
|
400
410
|
|
|
401
411
|
```bash
|
|
412
|
+
pm config project set search_default_mode keyword
|
|
402
413
|
pm config project set search_mutation_refresh_policy cache_only
|
|
403
414
|
pm config project set search_embedding_corpus_max_characters 12000
|
|
404
415
|
pm config project set search_query_expansion_enabled true
|
|
@@ -468,7 +479,7 @@ pm config project set qdrant_api_key '<QDRANT_API_KEY>' # omit on unauthentica
|
|
|
468
479
|
|
|
469
480
|
After changing any of these, run `pm reindex --mode hybrid` so the vector index reflects the new provider/store. `pm search ... --mode semantic|hybrid` emits a `vector_index_stale` warning when items have been modified since the last reindex.
|
|
470
481
|
|
|
471
|
-
**Refresh contract (important for agents):** by default a mutation (`pm create`/`pm update`) does **not** synchronously re-embed the changed item, so a brand-new item is absent from `--mode semantic|hybrid` results until the next `pm reindex`. This keeps writes fast. Control the tradeoff with `search.mutation_refresh_policy`: `cache_only` (never refresh on write — fastest), `semantic_auto` (refresh when implicit Ollama/LanceDB defaults are active), or `semantic_configured` (refresh only when semantic search is explicitly configured). Keyword mode (`--mode keyword`, the default) always reflects writes immediately because it reads items directly.
|
|
482
|
+
**Refresh contract (important for agents):** by default a mutation (`pm create`/`pm update`) does **not** synchronously re-embed the changed item, so a brand-new item is absent from `--mode semantic|hybrid` results until the next `pm reindex`. This keeps writes fast. Control the tradeoff with `search.mutation_refresh_policy`: `cache_only` (never refresh on write — fastest), `semantic_auto` (refresh when implicit Ollama/LanceDB defaults are active), or `semantic_configured` (refresh only when semantic search is explicitly configured). Keyword mode (`--mode keyword`, or the `auto` default on a workspace without a configured semantic provider) always reflects writes immediately because it reads items directly.
|
|
472
483
|
|
|
473
484
|
## Custom Item Types
|
|
474
485
|
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Lifecycle Commands and Ownership
|
|
2
|
+
|
|
3
|
+
Tracked by [pm-ik19](../.agents/pm/tasks/pm-ik19.toon) and
|
|
4
|
+
[pm-eq4x](../.agents/pm/tasks/pm-eq4x.toon).
|
|
5
|
+
|
|
6
|
+
Bulk mutations and ownership compositions share SDK implementations with their
|
|
7
|
+
compatibility spellings. Runtime help and contracts describe the active surface:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pm update many --help
|
|
11
|
+
pm close many --help
|
|
12
|
+
pm close delete --help
|
|
13
|
+
pm contracts --command 'close many' --flags-only --json
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Command migration
|
|
17
|
+
|
|
18
|
+
| Canonical invocation | Compatibility invocation |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| `pm update many --ids <ids> --priority 1` | `pm update-many --ids <ids> --priority 1` |
|
|
21
|
+
| `pm close many --ids <ids> --reason "Verified"` | `pm close-many --ids <ids> --reason "Verified"` |
|
|
22
|
+
| `pm close delete <id> --dry-run` | `pm delete <id> --dry-run` |
|
|
23
|
+
| `pm claim <id> --start` | `pm start-task <id>` |
|
|
24
|
+
| `pm release <id> --pause` | `pm pause-task <id>` |
|
|
25
|
+
| `pm close <id> "Verified" --release-assignment` | `pm close-task <id> "Verified"` |
|
|
26
|
+
|
|
27
|
+
The old spellings remain accepted as hidden aliases. Bulk aliases are permanent;
|
|
28
|
+
the three task aliases are deprecated. Human output for deprecated aliases can
|
|
29
|
+
include migration hints according to `ux.deprecation_hints`; JSON and quiet
|
|
30
|
+
invocations suppress those hints. Bulk commands retain their existing filters,
|
|
31
|
+
stdin selection, dry runs, rollback behavior, and evidence flags. Put bulk flags
|
|
32
|
+
after `many`. Deletion recovery remains `pm history restore <id> <version>`.
|
|
33
|
+
|
|
34
|
+
Plain `claim`, `release`, `update`, and `close` keep their original semantics.
|
|
35
|
+
`claim --start` requires an explicit item and rejects `--next` and
|
|
36
|
+
`--if-available` before mutation. It claims ownership, then moves the item to the
|
|
37
|
+
configured in-progress status. `release --pause` moves work to the configured
|
|
38
|
+
open status, then releases ownership. `close --release-assignment` records the
|
|
39
|
+
close and its inline evidence, then releases ownership.
|
|
40
|
+
|
|
41
|
+
Each constituent operation enforces its own policy and writes its own history.
|
|
42
|
+
Compositions do not provide rollback across operations: for example, if the
|
|
43
|
+
status transition fails after a successful claim, the claim remains. Inspect the
|
|
44
|
+
item before retrying after an error.
|
|
45
|
+
|
|
46
|
+
## SDK and MCP
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { PmClient } from "@unbrained/pm-cli/sdk";
|
|
50
|
+
|
|
51
|
+
const pm = new PmClient({ pmRoot: "/project/.agents/pm" });
|
|
52
|
+
const started = await pm.claim("pm-example", { start: true });
|
|
53
|
+
const paused = await pm.release("pm-example", { pause: true });
|
|
54
|
+
const closed = await pm.close("pm-example", "Acceptance verified", {
|
|
55
|
+
releaseAssignment: true,
|
|
56
|
+
resolution: "Implemented the requested behavior",
|
|
57
|
+
expectedResult: "Acceptance checks pass",
|
|
58
|
+
actualResult: "Acceptance checks passed",
|
|
59
|
+
validateClose: "warn",
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Literal `true` options return typed `StartTaskResult`, `PauseTaskResult`, or
|
|
64
|
+
`CloseTaskResult` receipts. Their discriminators remain `start_task`,
|
|
65
|
+
`pause_task`, and `close_task`, with the constituent results available under
|
|
66
|
+
`claim`, `update`, `close`, or `release`. Public `runStartTask`, `runPauseTask`, and
|
|
67
|
+
`runCloseTask` primitives expose the same SDK-owned compositions.
|
|
68
|
+
|
|
69
|
+
MCP actions remain `claim`, `release`, and `close`, using `start`, `pause`, and
|
|
70
|
+
`releaseAssignment`. Action-specific discovery types claim's `start` as boolean;
|
|
71
|
+
scheduling actions retain string timestamps. For the broad provider tool schema,
|
|
72
|
+
pass the claim boolean through `options: { start: true }` because its shared flat
|
|
73
|
+
`start` property retains the scheduling string contract. Bulk action names remain
|
|
74
|
+
`update_many`, `close_many`, and `delete` for transport compatibility.
|
|
75
|
+
|
|
76
|
+
See [SDK Lifecycle Policy](SDK_LIFECYCLE.md) for transaction and policy ownership
|
|
77
|
+
and [CLI Scripting Contract](SCRIPTING.md) for output projection.
|
package/docs/README.md
CHANGED
|
@@ -35,6 +35,7 @@ pm guide release --json
|
|
|
35
35
|
- [Onboarding](ONBOARDING.md) - first-two-hours maintainer and contributor setup.
|
|
36
36
|
- [Agent Guide](AGENT_GUIDE.md) - canonical agent loop, tracker linking, and token-minimal command choices.
|
|
37
37
|
- [Command Reference](COMMANDS.md) - command families with examples and when to use each family.
|
|
38
|
+
- [Context and Operations Namespaces](COMMAND_NAMESPACES.md) - native navigation, diagnostics, event streams, and compatibility aliases.
|
|
38
39
|
- [CLI Scripting Contract](SCRIPTING.md) - exit codes, flat mutation receipts versus read envelopes, stdout/stderr boundaries, stable JSON fields, uniform OR filters, and shell composition recipes.
|
|
39
40
|
- [Configuration](CONFIGURATION.md) - settings, storage formats, output, search, validation, and environment variables.
|
|
40
41
|
- [Testing](TESTING.md) - sandbox-safe local tests and linked-test orchestration.
|
|
@@ -62,6 +63,7 @@ pm guide release --json
|
|
|
62
63
|
- [Universal Read Output Contracts](READ_OUTPUT_CONTRACTS.md) - cross-command include, amount, cost, and encoding controls for CLI, SDK, MCP, and packages.
|
|
63
64
|
- [Diagnostic Output Contracts](DIAGNOSTIC_OUTPUT_CONTRACTS.md) - action-first error budgets, deterministic degradation, SDK projection, and executable refusal assurance.
|
|
64
65
|
- [History Maintenance and Recovery](HISTORY_MAINTENANCE.md) - native history commands, permanent aliases, shared SDK transforms, and transactional recovery.
|
|
66
|
+
- [Declarative Workflow Policies](WORKFLOW_POLICIES.md) - portable lifecycle requirements, independent approvals, and completeness reports.
|
|
65
67
|
- [Mutation Integrity](MUTATION_INTEGRITY.md) - shared CLI/SDK/MCP author, secret, append-only disposition, and stale-work guardrails.
|
|
66
68
|
- [Agent Provenance ADR Amendment](AGENT_PROVENANCE_ADR.md) - extensible model, effort, role, and host provenance with privacy and compatibility boundaries.
|
|
67
69
|
- [SDK Agent Session and Episode Context](SDK_AGENT_SESSION_CONTEXT.md) - inherited role/topic context, cross-process episode identity, and deterministic history grouping.
|
|
@@ -99,6 +101,7 @@ Additional SDK, operations, and generated contracts:
|
|
|
99
101
|
- [Item Read Projections](ITEM_READ_PROJECTIONS.md) - identity, projections, and read completeness.
|
|
100
102
|
- [MCP Capability Surfaces](MCP_CAPABILITY_SURFACES.md) - negotiated MCP discovery contracts.
|
|
101
103
|
- [PR Review Loop](PR_REVIEW_LOOP.md) - complete review inventories and feedback acknowledgment.
|
|
104
|
+
- [Lifecycle Commands and Ownership](LIFECYCLE_COMMANDS.md) - canonical bulk commands, ownership compositions, and SDK/MCP migration.
|
|
102
105
|
- [SDK Lifecycle](SDK_LIFECYCLE.md) - lifecycle primitives and package integration.
|
|
103
106
|
- [SDK Runtime Boundaries](SDK_RUNTIME_BOUNDARIES.md) - runtime ownership and import boundaries.
|
|
104
107
|
- [Sentry Contract Epochs](SENTRY_CONTRACT_EPOCHS.md) - diagnostic compatibility and release epochs.
|
|
@@ -167,6 +167,11 @@ Cursor recovery carries the opaque value once in `recovery.cursor` and declares
|
|
|
167
167
|
the accepting `cli`, `sdk`, and `mcp` binding beside it. This avoids
|
|
168
168
|
serializing the same cursor once per transport while retaining an executable,
|
|
169
169
|
machine-readable binding for each surface.
|
|
170
|
+
When `restore_with` is `"recovery"`, consumers must resolve the adjacent
|
|
171
|
+
`recovery` object: pass its `cursor` value through `cli` (`--output-cursor`)
|
|
172
|
+
or the `sdk`/`mcp` field (`outputCursor`) while repeating the original query.
|
|
173
|
+
The string is a reference, not a shell command. Other `restore_with` values
|
|
174
|
+
provide retry guidance when no declared row collection can continue.
|
|
170
175
|
|
|
171
176
|
Budget-compacted declared row paths are independently resumable. The
|
|
172
177
|
disclosure's `continuations` entries name the row path, retained/remaining/total
|
package/docs/TESTING.md
CHANGED
|
@@ -88,6 +88,16 @@ so PR-local CodeFactor maintainability annotations fail locally before commit or
|
|
|
88
88
|
push. Existing legacy high-complexity test fixtures are tracked separately and
|
|
89
89
|
must not be used as precedent for new changed production/script code.
|
|
90
90
|
|
|
91
|
+
`lint:duplicates` runs three zero-clone profiles: the broad repository profile,
|
|
92
|
+
the production cross-format profile, and a supplemental long-table profile at
|
|
93
|
+
28 lines / 80 tokens. The last profile detects the historical GH-508 normalizer
|
|
94
|
+
tables below the other profiles' token floors; it does not replace their shorter
|
|
95
|
+
line thresholds. Its real detector regression rejects the historical table rows
|
|
96
|
+
and accepts a shared declaration. The earlier 12-line / 60-token exploratory
|
|
97
|
+
census informed calibration, but is not the enforced profile. These bounded
|
|
98
|
+
profiles do not claim complete equivalence with hosted analyzers.
|
|
99
|
+
See [pm-xspd](../.agents/pm/chores/pm-xspd.toon) for calibration evidence.
|
|
100
|
+
|
|
91
101
|
The local parity rules catch analyzer classes before push. The mandatory hosted
|
|
92
102
|
proof runs after the final commit is pushed and both apps have finished:
|
|
93
103
|
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Declarative workflow policies
|
|
2
|
+
|
|
3
|
+
Tracker: [pm-mj42og](../.agents/pm/features/pm-mj42og.toon) and [pm-htbetn](../.agents/pm/features/pm-htbetn.toon).
|
|
4
|
+
|
|
5
|
+
Projects can describe their lifecycle requirements as versioned data. The SDK
|
|
6
|
+
uses the same evaluator for item mutations, policy previews, and completeness
|
|
7
|
+
reports. Existing projects have no implicit policies. A declaration can advise,
|
|
8
|
+
warn, or refuse; refusal also requires an explicit workspace opt-in.
|
|
9
|
+
|
|
10
|
+
## Configure a requirement
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pm schema policy-put close-evidence --definition '{"id":"close-evidence","effect":"refuse","subject":{"statuses":["closed"]},"rule":{"kind":"require_fields","fields":["resolution","actual_result"]}}'
|
|
14
|
+
pm schema policies
|
|
15
|
+
pm schema policy-check pm-example --definition '{"status":"closed"}'
|
|
16
|
+
pm schema policy-mode refuse
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Use canonical status ids and metadata field names. `body` selects the Markdown
|
|
20
|
+
body. Custom fields can use dotted paths with at most eight segments. Empty
|
|
21
|
+
strings, arrays, objects, null, and absent values do not satisfy required fields;
|
|
22
|
+
zero and false are meaningful values.
|
|
23
|
+
|
|
24
|
+
`policy-put` replaces a declaration with the same id. `policy-remove <id>` removes
|
|
25
|
+
one declaration. `policy-mode advise` disables refusal while retaining diagnostics.
|
|
26
|
+
Registry writes are locked and recorded in workspace history. `--dry-run` previews
|
|
27
|
+
registry changes without writing. Malformed registries fail closed.
|
|
28
|
+
|
|
29
|
+
## Selectors and rules
|
|
30
|
+
|
|
31
|
+
All selectors in `subject` must match; values within one selector are alternatives.
|
|
32
|
+
Supported selectors are `types` (case insensitive), `tags`, `statuses`, `operations`,
|
|
33
|
+
`parents`, and `dependency: { "kind": "implements", "id": "pm-example" }` (id optional).
|
|
34
|
+
Parent and dependency selectors inspect direct relationships. Status selectors
|
|
35
|
+
match the destination; other selectors inspect both snapshots so a mutation cannot
|
|
36
|
+
escape a protected scope by removing its tag or changing its type.
|
|
37
|
+
|
|
38
|
+
| Rule kind | Required properties | Behavior |
|
|
39
|
+
| --- | --- | --- |
|
|
40
|
+
| `require_fields` | `fields` | Checks evidence on lifecycle, scope, or required-field changes |
|
|
41
|
+
| `transition` | `allowed` | Allows listed `[from, to]` status pairs; `$create` and `$delete` represent absent records |
|
|
42
|
+
| `authors` | `authors` | Requires a listed mutation actor |
|
|
43
|
+
| `field_writers` | `fields`, `authors` | Requires a listed actor when protected fields change |
|
|
44
|
+
| `approval` | `fields`, `authors` | Requires independent approval when an existing item changes status or is deleted |
|
|
45
|
+
|
|
46
|
+
Operation selectors use exact history operation names. Unknown declaration keys
|
|
47
|
+
are errors. Policies contain no executable expressions or regular expressions.
|
|
48
|
+
At most 256 declarations and 64 terms per selector/rule are accepted. Registry
|
|
49
|
+
reads are bounded to 1 MiB, and approval-history reads to 4 MiB.
|
|
50
|
+
|
|
51
|
+
Actor names are provenance supplied by the caller or local configuration. They
|
|
52
|
+
are not authenticated identities, and these rules are not an access-control
|
|
53
|
+
boundary against a caller who can edit the tracker or choose an author name.
|
|
54
|
+
Authenticated, signed identity ([pm-u14c](../.agents/pm/stories/pm-u14c.toon))
|
|
55
|
+
is a prerequisite for stronger authorization guarantees.
|
|
56
|
+
|
|
57
|
+
## Approvals
|
|
58
|
+
|
|
59
|
+
Prepare the declared fields, then have a different workflow actor record approval:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pm schema policy-put review --definition '{"id":"review","effect":"refuse","subject":{"statuses":["closed"]},"rule":{"kind":"approval","fields":["body","resolution"],"authors":["reviewer"]}}'
|
|
63
|
+
pm schema policy-approve pm-example --policy review --author reviewer --message 'Reviewed acceptance evidence'
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Approval events bind the item id, selected field values, and complete policy
|
|
67
|
+
revision. Changing reviewed content or the declaration invalidates the approval.
|
|
68
|
+
Unrelated metadata changes do not. The actor performing the transition must differ
|
|
69
|
+
from the approval actor. Only sealed approval events from a verified item history
|
|
70
|
+
chain count. `policy-check` previews transitions; `policy-approve` always records
|
|
71
|
+
an event and rejects `--dry-run`.
|
|
72
|
+
|
|
73
|
+
Approval rules apply to existing items. Creation and initial imports have no
|
|
74
|
+
reviewable history and skip approval requirements; use `transition` rules with
|
|
75
|
+
`["$create", "open"]` to constrain their initial status. Deletion requires approval
|
|
76
|
+
of the current record, using the same content and independent-actor checks.
|
|
77
|
+
|
|
78
|
+
Refused mutations preserve item state and item history, and append a workspace
|
|
79
|
+
refusal event. Accepted mutations attach bounded policy decisions to their normal
|
|
80
|
+
history event. Diagnostics contain policy ids and missing field paths, without
|
|
81
|
+
copying reviewed content into errors.
|
|
82
|
+
If the mandatory refusal audit cannot be appended, the mutation instead raises
|
|
83
|
+
`workflow_policy_audit_failed` and preserves the original failure in the SDK
|
|
84
|
+
error's `cause`. Item data remains unchanged; resolve the workspace history lock
|
|
85
|
+
or storage failure before retrying. Package imports do not downgrade this error
|
|
86
|
+
to an item-lock warning.
|
|
87
|
+
|
|
88
|
+
## Completeness reports and SDK
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
pm schema policy-presets
|
|
92
|
+
pm validate --check-completeness --strict-exit
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Presets return optional advisory declarations for familiar item types. They do
|
|
96
|
+
not install policies. Author the declarations appropriate to the project's own
|
|
97
|
+
types and lifecycle using `policy-put`. Completeness reports group counts by type,
|
|
98
|
+
return bounded violation examples, and use only `require_fields` declarations
|
|
99
|
+
without `subject.operations`. The report identifies this scope as
|
|
100
|
+
`operation_independent_require_fields`. All item selectors, including status,
|
|
101
|
+
still apply. `policy-check` without a proposed definition uses the same state-only
|
|
102
|
+
scope. Operation-scoped rules remain enforced during matching mutations; a clean
|
|
103
|
+
state report does not imply permission to perform every future operation.
|
|
104
|
+
To check a lifecycle field invariant in both state reports and mutations, select
|
|
105
|
+
its `statuses` without restricting `operations`.
|
|
106
|
+
Default validation includes this check; projects without declarations remain
|
|
107
|
+
unaffected.
|
|
108
|
+
An unreadable or malformed `schema/policies.json` produces an error-level
|
|
109
|
+
`completeness` result with a repair hint. Other requested validation checks still
|
|
110
|
+
run, and `--strict-exit` fails until the policy registry is repaired.
|
|
111
|
+
|
|
112
|
+
The published `@unbrained/pm-cli/sdk/governance` entrypoint exports
|
|
113
|
+
`runWorkflowPolicyAction`, `evaluateWorkflowPolicies`, policy types, parsers,
|
|
114
|
+
`WORKFLOW_POLICY_SCHEMA`, and `WORKFLOW_POLICY_DOCUMENT_SCHEMA`. `PmClient` exposes
|
|
115
|
+
`workflowPolicy(action, name, options)`. CLI `schema` and MCP `pm_schema` use the
|
|
116
|
+
same action vocabulary and SDK implementation; MCP options accept camelCase
|
|
117
|
+
keys and structured JSON definitions.
|
|
118
|
+
|
|
119
|
+
For repeated pure evaluation, `createWorkflowPolicyEvaluator(document)` returns
|
|
120
|
+
an evaluator that owns a private normalized policy snapshot and hashes each
|
|
121
|
+
declaration once. Later edits to the supplied document do not change that
|
|
122
|
+
snapshot; create another evaluator to adopt them. Completeness validation uses
|
|
123
|
+
one such snapshot for the whole supplied corpus.
|
|
124
|
+
|
|
125
|
+
The schema contract version is 4.16. Existing schema operations remain available;
|
|
126
|
+
`SchemaResult` now also includes `WorkflowPolicyActionResult`. Consumers that
|
|
127
|
+
exhaustively narrow schema results should handle the `policy_result: true`
|
|
128
|
+
discriminant. Validation options include `checkCompleteness`, and validation
|
|
129
|
+
results can contain a `completeness` check.
|
|
@@ -6,12 +6,12 @@ This file is generated from `PM_COMMAND_CAPABILITY_CONTRACTS`. Do not edit it ma
|
|
|
6
6
|
|
|
7
7
|
| Capability family | Commands |
|
|
8
8
|
| --- | --- |
|
|
9
|
-
| workspace | `init`, `config`, `merge`, `schema`, `profile`, `telemetry`, `health`, `gc`, `workspace` |
|
|
10
|
-
| intake | `create`, `copy`, `focus`, `restore` |
|
|
11
|
-
| context | `list`, `aggregate`, `context`, `get`, `search`, `duplicates`, `eval`, `next`, `activity`, `stats`, `help` |
|
|
12
|
-
| lifecycle | `update`, `update
|
|
13
|
-
| evidence | `history`, `events`, `history
|
|
9
|
+
| workspace | `init`, `config`, `merge`, `schema`, `profile`, `ops telemetry`, `ops health`, `ops gc`, `workspace` |
|
|
10
|
+
| intake | `create`, `copy`, `context focus`, `history restore` |
|
|
11
|
+
| context | `list`, `aggregate`, `context`, `get`, `search`, `duplicates`, `ops eval`, `context next`, `history activity`, `ops stats`, `help` |
|
|
12
|
+
| lifecycle | `update`, `update many`, `close`, `close many`, `close delete`, `claim`, `release` |
|
|
13
|
+
| evidence | `history`, `history events`, `history redact`, `history repair`, `history compact`, `history-author-acknowledge`, `append`, `comments`, `notes`, `learnings`, `files`, `docs` |
|
|
14
14
|
| graph | `graph`, `deps`, `plan` |
|
|
15
|
-
| quality | `test`, `test-all`, `validate`, `assurance`, `contracts` |
|
|
15
|
+
| quality | `test`, `ops test-all`, `ops validate`, `assurance`, `contracts`, `ops` |
|
|
16
16
|
| automation | `meet`, `event`, `remind` |
|
|
17
17
|
| extensions | `package` |
|
|
@@ -15,6 +15,7 @@ This file is generated from `PM_COMMAND_CAPABILITY_CONTRACTS`. Do not edit it ma
|
|
|
15
15
|
| `item-reopen` | full | lifecycle |
|
|
16
16
|
| `copy` | full | intake |
|
|
17
17
|
| `focus` | standard | intake |
|
|
18
|
+
| `context focus` | standard | intake |
|
|
18
19
|
| `list` | core | context |
|
|
19
20
|
| `list-all` | standard | context |
|
|
20
21
|
| `list-draft` | full | context |
|
|
@@ -31,23 +32,34 @@ This file is generated from `PM_COMMAND_CAPABILITY_CONTRACTS`. Do not edit it ma
|
|
|
31
32
|
| `search` | core | context |
|
|
32
33
|
| `duplicates` | full | context |
|
|
33
34
|
| `eval` | full | context |
|
|
35
|
+
| `ops eval` | full | context |
|
|
34
36
|
| `next` | core | context |
|
|
37
|
+
| `context next` | core | context |
|
|
35
38
|
| `history` | standard | evidence |
|
|
36
39
|
| `events` | standard | evidence |
|
|
40
|
+
| `history events` | standard | evidence |
|
|
37
41
|
| `history-redact` | full | evidence |
|
|
42
|
+
| `history redact` | full | evidence |
|
|
38
43
|
| `history-repair` | full | evidence |
|
|
44
|
+
| `history repair` | full | evidence |
|
|
39
45
|
| `history-compact` | full | evidence |
|
|
46
|
+
| `history compact` | full | evidence |
|
|
40
47
|
| `history-author-acknowledge` | full | evidence |
|
|
41
48
|
| `merge` | full | workspace |
|
|
42
49
|
| `schema` | standard | workspace |
|
|
43
50
|
| `profile` | standard | workspace |
|
|
44
51
|
| `activity` | full | context |
|
|
52
|
+
| `history activity` | full | context |
|
|
45
53
|
| `restore` | full | intake |
|
|
54
|
+
| `history restore` | full | intake |
|
|
46
55
|
| `update` | core | lifecycle |
|
|
47
56
|
| `update-many` | full | lifecycle |
|
|
57
|
+
| `update many` | full | lifecycle |
|
|
48
58
|
| `close` | core | lifecycle |
|
|
49
59
|
| `close-many` | full | lifecycle |
|
|
60
|
+
| `close many` | full | lifecycle |
|
|
50
61
|
| `delete` | full | lifecycle |
|
|
62
|
+
| `close delete` | full | lifecycle |
|
|
51
63
|
| `append` | standard | evidence |
|
|
52
64
|
| `comments` | standard | evidence |
|
|
53
65
|
| `notes` | standard | evidence |
|
|
@@ -58,12 +70,18 @@ This file is generated from `PM_COMMAND_CAPABILITY_CONTRACTS`. Do not edit it ma
|
|
|
58
70
|
| `plan` | core | graph |
|
|
59
71
|
| `test` | standard | quality |
|
|
60
72
|
| `test-all` | full | quality |
|
|
73
|
+
| `ops test-all` | full | quality |
|
|
61
74
|
| `telemetry` | full | workspace |
|
|
75
|
+
| `ops telemetry` | full | workspace |
|
|
62
76
|
| `stats` | full | context |
|
|
77
|
+
| `ops stats` | full | context |
|
|
63
78
|
| `health` | standard | workspace |
|
|
79
|
+
| `ops health` | standard | workspace |
|
|
64
80
|
| `validate` | core | quality |
|
|
81
|
+
| `ops validate` | core | quality |
|
|
65
82
|
| `assurance` | full | quality |
|
|
66
83
|
| `gc` | full | workspace |
|
|
84
|
+
| `ops gc` | full | workspace |
|
|
67
85
|
| `workspace` | full | workspace |
|
|
68
86
|
| `contracts` | standard | quality |
|
|
69
87
|
| `claim` | core | lifecycle |
|
|
@@ -75,6 +93,7 @@ This file is generated from `PM_COMMAND_CAPABILITY_CONTRACTS`. Do not edit it ma
|
|
|
75
93
|
| `event` | full | automation |
|
|
76
94
|
| `remind` | full | automation |
|
|
77
95
|
| `help` | core | context |
|
|
96
|
+
| `ops` | core | quality |
|
|
78
97
|
| `completion-statuses` | internal | internal |
|
|
79
98
|
| `completion-tags` | internal | internal |
|
|
80
99
|
| `completion-types` | internal | internal |
|