@unbrained/pm-cli 2026.9.18 → 2026.9.19

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.
Files changed (107) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +20 -0
  3. package/dist/cli/invocation-profile.d.ts +26 -0
  4. package/dist/cli/invocation-profile.js +3 -0
  5. package/dist/cli-bundle/bundle-manifest.json +148 -148
  6. package/dist/cli-bundle/chunks/{chunk-GRFRKHFC.js → chunk-7CN53F4S.js} +2 -2
  7. package/dist/cli-bundle/chunks/{chunk-X2EVS624.js → chunk-AACGU5IA.js} +2 -2
  8. package/dist/cli-bundle/chunks/{chunk-AOD5WE6U.js → chunk-CCLWCESZ.js} +2 -2
  9. package/dist/cli-bundle/chunks/{chunk-WD7BQXA7.js → chunk-J7NP7QLW.js} +2 -2
  10. package/dist/cli-bundle/chunks/{chunk-T4J2X3RK.js → chunk-K4VAU4HU.js} +2 -2
  11. package/dist/cli-bundle/chunks/chunk-KHN4NMKT.js +238 -0
  12. package/dist/cli-bundle/chunks/{chunk-CA5DRNGA.js → chunk-KYG2QKNY.js} +28 -28
  13. package/dist/cli-bundle/chunks/{chunk-WUDF7HWM.js → chunk-OQS2Y6VN.js} +2 -2
  14. package/dist/cli-bundle/chunks/{chunk-XFGWFVR3.js → chunk-QA4GUEKJ.js} +20 -20
  15. package/dist/cli-bundle/chunks/chunk-QTHR3LXF.js +20 -0
  16. package/dist/cli-bundle/chunks/{chunk-FZZVWWQP.js → chunk-RVMDPIGD.js} +2 -2
  17. package/dist/cli-bundle/chunks/{chunk-Y2OK7IAD.js → chunk-WASMH647.js} +2 -2
  18. package/dist/cli-bundle/chunks/{register-list-query-43EQISX7.js → register-list-query-RMZNHSII.js} +2 -2
  19. package/dist/cli-bundle/chunks/{register-mutation-TSZNAKEU.js → register-mutation-HJGSGX3H.js} +2 -2
  20. package/dist/cli-bundle/chunks/{register-operations-KFZIKATY.js → register-operations-LBEMFUMM.js} +2 -2
  21. package/dist/cli-bundle/chunks/{register-setup-KTJ4ZE65.js → register-setup-MU557JAA.js} +2 -2
  22. package/dist/cli-bundle/focused-chunks/{chunk-QVVOXVYI.js → chunk-5SZ4JSPZ.js} +2 -2
  23. package/dist/cli-bundle/focused-chunks/{chunk-PNCUNPSA.js → chunk-7Y7PAC56.js} +2 -2
  24. package/dist/cli-bundle/focused-chunks/{chunk-YJYSFWSW.js → chunk-ARK4FIO4.js} +2 -2
  25. package/dist/cli-bundle/focused-chunks/{chunk-C6SH62BX.js → chunk-CJ4QA4RW.js} +2 -2
  26. package/dist/cli-bundle/focused-chunks/{chunk-ZDX2BCOT.js → chunk-I32L3FWW.js} +2 -2
  27. package/dist/cli-bundle/focused-chunks/{chunk-GEFWBVPQ.js → chunk-I4WDON3K.js} +2 -2
  28. package/dist/cli-bundle/focused-chunks/{chunk-246P5AK7.js → chunk-IKPR4VVN.js} +2 -2
  29. package/dist/cli-bundle/focused-chunks/chunk-J3GN4SQT.js +2 -0
  30. package/dist/cli-bundle/focused-chunks/{chunk-LG3SYXBX.js → chunk-OOZHQFBF.js} +9 -9
  31. package/dist/cli-bundle/focused-chunks/{chunk-BVOQRMHF.js → chunk-P4BA7OX7.js} +27 -26
  32. package/dist/cli-bundle/focused-chunks/{chunk-7D6M45AN.js → chunk-QL4MO5M2.js} +9 -9
  33. package/dist/cli-bundle/focused-chunks/chunk-TDHVROGL.js +3 -0
  34. package/dist/cli-bundle/focused-chunks/chunk-V3YMNAO7.js +2 -0
  35. package/dist/cli-bundle/focused-chunks/chunk-YDFEWXXZ.js +59 -0
  36. package/dist/cli-bundle/focused-chunks/{chunk-MMX7BQLH.js → chunk-ZDBKYZFE.js} +2 -2
  37. package/dist/cli-bundle/focused-chunks/{chunk-7UZHYT5B.js → chunk-ZI2YBJFH.js} +2 -2
  38. package/dist/cli-bundle/main.js +2 -2
  39. package/dist/cli-bundle/sdk-authoring.js +1 -1
  40. package/dist/cli-bundle/sdk-contracts.js +2 -2
  41. package/dist/cli-bundle/sdk-core.js +2 -2
  42. package/dist/cli-bundle/sdk-governance.js +1 -1
  43. package/dist/cli-bundle/sdk-graph.js +1 -1
  44. package/dist/cli-bundle/sdk-merge.js +41 -41
  45. package/dist/cli-bundle/sdk-query.js +1 -1
  46. package/dist/cli-bundle/sdk-runtime.js +1 -1
  47. package/dist/cli-bundle/sdk-testing.js +1 -1
  48. package/dist/cli-bundle/sdk.js +8 -8
  49. package/dist/cli.js +1 -1
  50. package/dist/core/checkpoint/mutation-checkpoint.d.ts +1 -1
  51. package/dist/core/checkpoint/mutation-checkpoint.js +2 -2
  52. package/dist/core/fs/atomic-create.d.ts +7 -0
  53. package/dist/core/fs/atomic-create.js +2 -0
  54. package/dist/core/history/history.js +1 -1
  55. package/dist/core/schema/runtime-schema.d.ts +1 -1
  56. package/dist/core/schema/runtime-schema.js +2 -2
  57. package/dist/core/session/session-state.js +1 -1
  58. package/dist/core/store/settings-concurrency.d.ts +7 -0
  59. package/dist/core/store/settings-concurrency.js +2 -0
  60. package/dist/core/store/settings.d.ts +8 -1
  61. package/dist/core/store/settings.js +3 -2
  62. package/dist/sdk/cli-contracts/flag-contracts.js +1 -1
  63. package/dist/sdk/contracts.d.ts +1 -0
  64. package/dist/sdk/contracts.js +1 -1
  65. package/dist/sdk/extension/install-runtime.d.ts +1 -1
  66. package/dist/sdk/extension/install-runtime.js +2 -2
  67. package/dist/sdk/governance/health.js +1 -1
  68. package/dist/sdk/governance/provenance-health.d.ts +27 -0
  69. package/dist/sdk/governance/provenance-health.js +1 -1
  70. package/dist/sdk/graph/index.d.ts +1 -0
  71. package/dist/sdk/graph/index.js +1 -1
  72. package/dist/sdk/graph/query-contracts.d.ts +18 -0
  73. package/dist/sdk/graph/query-contracts.js +2 -0
  74. package/dist/sdk/graph/run.d.ts +2 -0
  75. package/dist/sdk/graph/run.js +1 -1
  76. package/dist/sdk/graph/traversal.js +1 -1
  77. package/dist/sdk/lifecycle-policy.js +1 -1
  78. package/dist/sdk/public-surface.json +1 -1
  79. package/docs/MCP_OPTION_CONFORMANCE.md +41 -0
  80. package/docs/OUTPUT_PROJECTION_CONTRACTS.md +18 -2
  81. package/docs/PERFORMANCE.md +37 -0
  82. package/docs/SDK_AGENT_SESSION_CONTEXT.md +28 -4
  83. package/docs/SDK_LIFECYCLE.md +16 -2
  84. package/docs/WORKSPACE_CONCURRENCY.md +67 -0
  85. package/marketplace.json +2 -2
  86. package/package.json +2 -2
  87. package/packages/pm-beads/package.json +1 -1
  88. package/packages/pm-calendar/package.json +1 -1
  89. package/packages/pm-command-kit/package.json +1 -1
  90. package/packages/pm-digital-twin/package.json +1 -1
  91. package/packages/pm-governance-audit/package.json +1 -1
  92. package/packages/pm-guide-shell/package.json +1 -1
  93. package/packages/pm-kanban/package.json +1 -1
  94. package/packages/pm-lifecycle-hooks/package.json +1 -1
  95. package/packages/pm-linked-test-adapters/package.json +1 -1
  96. package/packages/pm-search-advanced/package.json +1 -1
  97. package/packages/pm-templates/package.json +1 -1
  98. package/packages/pm-todos/package.json +1 -1
  99. package/packages/pm-vcs/package.json +1 -1
  100. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  101. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  102. package/dist/cli-bundle/chunks/chunk-CI2JCBN2.js +0 -237
  103. package/dist/cli-bundle/chunks/chunk-IPR2ICDO.js +0 -20
  104. package/dist/cli-bundle/focused-chunks/chunk-HRANNGHM.js +0 -2
  105. package/dist/cli-bundle/focused-chunks/chunk-LI6IGGB3.js +0 -2
  106. package/dist/cli-bundle/focused-chunks/chunk-QKG7JD34.js +0 -3
  107. package/dist/cli-bundle/focused-chunks/chunk-QYQFBJXD.js +0 -59
@@ -0,0 +1,41 @@
1
+ # MCP Option Conformance
2
+
3
+ Tracked by [pm-v0s2rm](../.agents/pm/chores/pm-v0s2rm.toon).
4
+
5
+ An integration test can pass while an undeclared option is ignored. That leaves
6
+ the test asserting a behavior it never exercised. The repository therefore
7
+ treats emitted MCP unknown-option diagnostics as test failures, while the
8
+ production server retains its advisory warning behavior for clients.
9
+
10
+ Every run using [vitest.config.ts](../vitest.config.ts) installs
11
+ [McpContractReporter](../scripts/mcp-contract-reporter.mts). The reporter records
12
+ the emitting file, full test name, option, tool, and action, and rejects the run
13
+ after execution even when all assertions pass. Unattributed warnings also fail.
14
+ Diagnostics retain option names, never option values.
15
+
16
+ The sandboxed test runner also retains the reporter when command-line reporter
17
+ selection overrides the config, including CI coverage shards that emit blobs.
18
+
19
+ Intentional negative tests must have an exact entry in
20
+ `MCP_OPTION_WARNING_ALLOWLIST`, including a reason. A matching file or test alone
21
+ does not exempt other warning identities. The current exemption verifies that
22
+ mutation-shaped options cannot mutate a read tool. New integration behavior
23
+ should use declared parameters and assert the actual resulting state.
24
+
25
+ The [gate registry](../scripts/release/gate-registry.json) registers this check
26
+ as `mcp-option-contracts`. Its
27
+ [negative control](../tests/unit/scripts/mcp-contract-reporter.spec.ts) starts a
28
+ real Vitest child process whose assertion passes but whose undeclared-option
29
+ diagnostic must produce exit status 1. Run the gate and its integration consumers
30
+ with the sandboxed repository runner:
31
+
32
+ ```bash
33
+ node scripts/run-tests.mjs test -- tests/unit/scripts/mcp-contract-reporter.spec.ts tests/integration/mcp-dynamic-package-actions.spec.ts tests/unit/mcp/mcp-server-nested-options.spec.ts
34
+ ```
35
+
36
+ Published MCP acceptance also isolates project and global configuration, tracked
37
+ by [pm-prmt1y](../.agents/pm/issues/pm-prmt1y.toon). The npm, npx, and bunx checks
38
+ use temporary tracker roots for both stdio and HTTP servers. This prevents a
39
+ caller's installed skills from changing discovery pagination and hiding the
40
+ bundled skills being verified. Protocol and skill-content assertions remain
41
+ mandatory; acceptance processes disable production telemetry and Sentry.
@@ -19,7 +19,11 @@ and canonical TOON tables are tracked by
19
19
  is tracked by [pm-8nev0o](../.agents/pm/issues/pm-8nev0o.toon) and
20
20
  [pm-oahhyc](../.agents/pm/issues/pm-oahhyc.toon). Exact command-local
21
21
  projection discovery is tracked by
22
- [pm-q4isdq](../.agents/pm/issues/pm-q4isdq.toon).
22
+ [pm-q4isdq](../.agents/pm/issues/pm-q4isdq.toon). Shared graph defaults and
23
+ scale enforcement are tracked by [pm-mfy1ux](../.agents/pm/issues/pm-mfy1ux.toon).
24
+
25
+ For enforcement of declared MCP input options in repository tests, see
26
+ [MCP Option Conformance](MCP_OPTION_CONFORMANCE.md).
23
27
 
24
28
  ## Agent Quick Context
25
29
 
@@ -167,7 +171,19 @@ Passing `--full` with the corresponding compact flag is a usage error. An
167
171
  explicit full request and the default full request produce the same payload
168
172
  shape; the flag exists as a machine-actionable restore instruction.
169
173
 
170
- `graph impact` is bounded to ten rows by default, returns `next_cursor` when
174
+ Graph row collections default to ten rows, including hierarchy and ordering
175
+ traversals, audit findings, and slack's critical path. The public
176
+ `GRAPH_QUERY_DEFAULTS` contract is available from `@unbrained/pm-cli/sdk/graph`
177
+ and `@unbrained/pm-cli/sdk/contracts`; `pm contracts --command graph --flags-only`
178
+ declares the same defaults before invoking a graph query. Analytics still compute over the complete graph. `--full`
179
+ restores row collections, while `--limit` chooses a finite cap; combining those
180
+ two controls is rejected. Path enumeration retains its separate five-path,
181
+ eight-edge-depth and 10,000-expansion safety defaults. Audit evidence uses
182
+ `--sample` independently of the finding-row limit. The thousand-item graph
183
+ regression enumerates every registered subcommand, bounds serialized output,
184
+ and proves full traversal and cursor continuation.
185
+
186
+ `graph impact` returns `next_cursor` when
171
187
  more affected nodes exist, and accepts `--after <cursor>` to resume in stable
172
188
  breadth-first order. `graph impact --full` is the explicit unbounded override;
173
189
  combining `--full` with `--limit` is rejected. A zero-row page remains
@@ -135,3 +135,40 @@ Review the report and budget diff together. Before a refresh, compare the delive
135
135
  ## Startup and observability
136
136
 
137
137
  Sentry is loaded only when an error-reporting path actually initializes it. Disabled and normal successful commands do not resolve or compile the `@sentry/node` → OpenTelemetry → Undici graph. The loader uses the package's supported CommonJS export after the opt-out gate, preserving the repo-wide ban on dynamic/inline imports while keeping enabled capture, sanitization, and flush behavior intact.
138
+
139
+ ## Invocation timing
140
+
141
+ Tracked by [pm-ag9nka](../.agents/pm/issues/pm-ag9nka.toon).
142
+
143
+ Use `pm --profile list --limit 5` to print diagnostics on stderr while retaining
144
+ normal stdout (including JSON). Every executable invocation with `--profile`
145
+ emits one final receipt on normal process drain, including help, version, and
146
+ handled refusals:
147
+
148
+ ```text
149
+ profile:command=list took_ms=20
150
+ profile:invocation total_ms=324.125 scope=process_start_to_output_drain command_took_ms_scope=handler
151
+ ```
152
+
153
+ `total_ms` uses monotonic runtime uptime, starting before module initialization
154
+ and ending after pending command output and event-loop work drain. It includes
155
+ bootstrap, settings/schema and extension loading, dispatch, rendering, and
156
+ foreground cleanup. Existing `profile:command` records retain their compatible
157
+ `took_ms` field; `command_took_ms_scope=handler` explicitly labels those narrower
158
+ spans. Extension discovery timing is another component, never an invocation
159
+ total. Components may overlap and must not be added to the total.
160
+
161
+ The total excludes parent-side scheduling/spawn, final OS teardown, and remote
162
+ telemetry delivery after a detached flush. A forcibly terminated process may
163
+ never reach the drain callback. In-process SDK calls do not emit a process-total
164
+ receipt: their host owns the lifetime. `--profile` after the `--` positional
165
+ terminator does not enable the receipt.
166
+
167
+ The real-process regression compares the reported total against external wall
168
+ time across query, mutation, configuration, schema, health, discovery, and
169
+ refusal paths. It permits parent/teardown overhead of the greater of 250 ms or
170
+ 25% of external wall time, and no more than 5 ms of clock rounding above it.
171
+ This is an instrument agreement tolerance, not a performance budget. Existing
172
+ transport/scale gates retain external end-to-end process wall time and their
173
+ unchanged stricter regression budgets; never gate invocation latency on handler
174
+ `took_ms`.
@@ -7,7 +7,8 @@ Tracker references: [pm-9wbiye](../.agents/pm/issues/pm-9wbiye.toon),
7
7
  [pm-eq9dlw](../.agents/pm/issues/pm-eq9dlw.toon), and
8
8
  [pm-lu6sca](../.agents/pm/features/pm-lu6sca.toon), plus
9
9
  [pm-5q8wa0](../.agents/pm/issues/pm-5q8wa0.toon) and
10
- [pm-c0lrdm](../.agents/pm/features/pm-c0lrdm.toon).
10
+ [pm-c0lrdm](../.agents/pm/features/pm-c0lrdm.toon) and
11
+ [pm-4f1l7f](../.agents/pm/issues/pm-4f1l7f.toon).
11
12
 
12
13
  Project management is context management. The public SDK therefore carries a
13
14
  session's purpose and episode boundary through the same immutable history that
@@ -129,8 +130,8 @@ public SDK exports for custom hosts.
129
130
  the bounded built-in resolver. It never contains environment values, session
130
131
  paths, prompts, or file contents.
131
132
 
132
- New mutation history records failed or explicitly unavailable configured
133
- resolver outcomes under `context.agent_provenance_outcomes`; dimensions with
133
+ New mutation history records successful probes, failed probes, and explicitly
134
+ unavailable configured resolver outcomes under `context.agent_provenance_outcomes`; dimensions with
134
135
  no configured resolver retain the compact legacy-compatible null projection.
135
136
  A resolver is only counted as
136
137
  attempted when its required input belongs to the detected harness; a foreign
@@ -138,7 +139,30 @@ host's shared `AI_AGENT` value is not Codex input. Consequently `pm health` can
138
139
  `provenance_resolver_zero_success:<harness>:<dimension>:<resolver>:<attempts>`
139
140
  without confusing an unavailable harness signal with a failed resolver. The
140
141
  warning is advisory and the storage check includes the bounded attempt and
141
- success counters for diagnosis.
142
+ success counters for diagnosis. Resolved environment, session, client, and
143
+ inferred observations do not count as probe successes merely because that
144
+ harness declares a resolver. Existing immutable records are preserved; a new
145
+ successful probe clears an all-failed advisory when the complete sample includes
146
+ that event.
147
+
148
+ `scanProvenanceResolverHealth()` from `@unbrained/pm-cli/sdk/governance` returns
149
+ `sample`, also exposed as `checks[name=storage].details.provenance_sample` by
150
+ `pm health --full --json`. The receipt declares `scope=history_prefix`, the
151
+ 10,000-event and 8 MiB ceilings, events/bytes read, truncation, unreadable sources, malformed rows,
152
+ and the earliest/latest valid event timestamps inspected. Files are traversed
153
+ by sorted name and events by append order: this is a bounded history prefix,
154
+ not a rolling recent window. Timestamp bounds describe observed events only.
155
+ `sample.complete=false` suppresses population-wide zero-success conclusions;
156
+ `truncated` separately identifies byte/event limits. Missing or malformed input
157
+ is diagnosed by the integrity checks. An empty or unavailable-only sample is
158
+ not proof that a resolver works. These measurements describe the sampled
159
+ history, not current probe availability or an unobserved historical success.
160
+ The optional `eventLimit` argument must be a non-negative safe integer;
161
+ invalid bounds throw `RangeError`, and zero requests an empty bounded sample.
162
+
163
+ The `ProvenanceResolverHealthScan` TypeScript result adds a required `sample`
164
+ receipt. Consumers that construct this result themselves must supply the receipt;
165
+ consumers that only read returned scans retain all prior fields unchanged.
142
166
 
143
167
  Older immutable history can also contain roles outside the controlled domain,
144
168
  including values recorded from presence-only harness flags before semantic role
@@ -1,8 +1,9 @@
1
1
  # SDK Lifecycle Policy
2
2
 
3
3
  Tracked by [pm-z5pmf8](../.agents/pm/issues/pm-z5pmf8.toon),
4
- [pm-xm0id4](../.agents/pm/issues/pm-xm0id4.toon), and
5
- [pm-2ew0w3](../.agents/pm/issues/pm-2ew0w3.toon).
4
+ [pm-xm0id4](../.agents/pm/issues/pm-xm0id4.toon),
5
+ [pm-2ew0w3](../.agents/pm/issues/pm-2ew0w3.toon), and
6
+ [pm-scbr0s](../.agents/pm/issues/pm-scbr0s.toon).
6
7
 
7
8
  The public SDK owns lifecycle transactions and policy. CLI and MCP operations
8
9
  delegate to SDK modules, so an item does not gain different storage,
@@ -39,6 +40,10 @@ Package authors can import these operations from `@unbrained/pm-cli/sdk`
39
40
  without importing CLI modules or spawning the executable. Existing CLI import
40
41
  paths remain source-compatible while integrations migrate.
41
42
 
43
+ See [Concurrent Workspace Mutations](WORKSPACE_CONCURRENCY.md) for settings
44
+ snapshot reconciliation, schema publication, session locks, and checkpoint
45
+ collision semantics shared by these operations.
46
+
42
47
  ## Relationship Identity
43
48
 
44
49
  Tracked by [pm-olcoon](../.agents/pm/issues/pm-olcoon.toon).
@@ -94,6 +99,15 @@ An embedded SDK consumer can explicitly choose `orderingEdges: "remove"` for
94
99
  a domain where predecessor facts are intentionally ephemeral. The CLI and MCP
95
100
  do not expose that override and use the durable default.
96
101
 
102
+ Explicit removal returns `closed_removed_predecessors:<item>:<ids>` for the
103
+ complete removed row set and `closed_removed_predecessors_count:<item>:<n>`
104
+ for its cardinality. The count is the number of dependency rows, including
105
+ distinct provenance rows that reference the same item. Clearing a transient
106
+ `blocked_by` scalar is reported separately as
107
+ `closed_cleared_blocked_by:<item>:<blocker>` and does not inflate that count.
108
+ Both removal and its receipts use the same selected rows; other relationship
109
+ kinds survive unchanged.
110
+
97
111
  ```ts
98
112
  import {
99
113
  closeItem,
@@ -0,0 +1,67 @@
1
+ # Concurrent Workspace Mutations
2
+
3
+ Tracked by [pm-bgcu](../.agents/pm/issues/pm-bgcu.toon). Power-loss durability is
4
+ governed by [pm-o2kc](../.agents/pm/epics/pm-o2kc.toon).
5
+
6
+ The CLI and MCP use the SDK's persistence primitives. Atomic replacement makes
7
+ one file write indivisible, but preserving concurrent edits also requires
8
+ protecting the read and decision that precede that write.
9
+
10
+ ## Settings snapshots
11
+
12
+ `readSettings` attaches an internal, non-enumerable persistence snapshot.
13
+ `writeSettings` compares the caller's edited snapshot with the latest document
14
+ while holding the `workspace-history` lock. Changes to different object keys
15
+ are combined, including separate keys in a newly introduced nested object.
16
+ Unchanged keys keep the current persisted values; sparse defaults and
17
+ file-backed schema definitions remain sparse.
18
+
19
+ Concurrent incompatible edits to the same scalar, array, or deleted object
20
+ return a conflict before writing. Read a fresh settings snapshot and reapply
21
+ the intended operation. Equal concurrent changes are idempotent. A successful
22
+ write advances that instance's baseline, so reusing it cannot replay an earlier
23
+ edit over another writer. Conflict messages name keys without exposing values.
24
+ Deleting the settings document also invalidates an unchanged read snapshot;
25
+ its next write returns the same structured conflict.
26
+
27
+ Keep the object returned by `readSettings` when editing settings. Constructing
28
+ a new object, spreading it, or using `structuredClone` drops the internal
29
+ snapshot; `writeSettings` treats such objects as explicit whole-document
30
+ replacements. They are suitable for initialization, not concurrent edits.
31
+
32
+ The same lock protects the persisted document, its workspace history entry,
33
+ and compensation if history append fails. This prevents concurrent writers
34
+ from forking the chain or leaving an accepted write unrecorded. It does not
35
+ claim crash atomicity across separate filesystem writes.
36
+
37
+ ## Schema, session, and rollback state
38
+
39
+ Schema mutations hold the existing `schema-types`, `schema-statuses`, or
40
+ `schema-fields` lock while reading and modifying their file. Profile application
41
+ uses the same lock order. Bootstrap stages complete seed bytes and publishes
42
+ them through a non-replacing hard link: a concurrent schema writer or reader
43
+ can never be overwritten by a delayed bootstrap. A filesystem that refuses
44
+ hard links returns an error instead of falling back to an unsafe overwrite.
45
+
46
+ Focus and semantic attribution share the `session-state` lock across the full
47
+ read-modify-write operation. Independent agents retain their attribution while
48
+ focus changes. This state remains local and ephemeral.
49
+
50
+ Rollback checkpoints use the same atomic, non-replacing publication as schema
51
+ seeds. Filesystem identity also protects paths reached through symlink aliases.
52
+ A byte-identical retry succeeds; reusing an ID for different contents fails without
53
+ replacing the original rollback evidence. Different checkpoint paths remain
54
+ independent.
55
+
56
+ Atomic publication guarantees complete visible bytes and prevents replacement.
57
+ It does not flush file data or directory entries to stable storage, so success
58
+ does not guarantee survival of power loss. A stronger durability policy must
59
+ cover all writers, newly created ancestor directories, retry acknowledgements,
60
+ and supported filesystems; syncing only this publication path would not establish
61
+ that workspace-wide guarantee.
62
+
63
+ The mutation locks use the existing bounded contention and stale-owner recovery
64
+ mechanism. Settings use configured lock TTL and wait values. Internal session
65
+ locks use the standard defaults; `PM_LOCK_WAIT_MS` still
66
+ overrides their wait budget. Every acquired lock is released on success and
67
+ failure.
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.9.18"
9
+ "version": "2026.9.19"
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.9.18",
16
+ "version": "2026.9.19",
17
17
  "author": {
18
18
  "name": "unbrained",
19
19
  "url": "https://github.com/unbraind/pm-cli"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-cli",
3
- "version": "2026.9.18",
3
+ "version": "2026.9.19",
4
4
  "description": "Git-native project management CLI for humans and agents.",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@11.10.0",
@@ -222,7 +222,7 @@
222
222
  "@eslint/js": "^10.0.1",
223
223
  "@modelcontextprotocol/ext-apps": "2.0.0",
224
224
  "@sentry/cli": "^3.8.0",
225
- "@types/node": "^26.5.1",
225
+ "@types/node": "^26.6.1",
226
226
  "@types/npm-package-arg": "^6.1.4",
227
227
  "@vitest/coverage-v8": "^4.1.11",
228
228
  "esbuild": "0.28.2",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-beads",
3
- "version": "2026.9.18",
3
+ "version": "2026.9.19",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package for importing Beads JSONL records.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-calendar",
3
- "version": "2026.9.18",
3
+ "version": "2026.9.19",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package for calendar and agenda views.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-command-kit",
3
- "version": "2026.9.18",
3
+ "version": "2026.9.19",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm exemplar package for the commands capability: registerCommand, registerFlags, and registerParser.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-digital-twin",
3
- "version": "2026.9.18",
3
+ "version": "2026.9.19",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "Beyond-PM exemplar: a temporal production-facility digital twin built entirely on public pm SDK and extension primitives.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-governance-audit",
3
- "version": "2026.9.18",
3
+ "version": "2026.9.19",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package for governance audit and normalization workflows.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-guide-shell",
3
- "version": "2026.9.18",
3
+ "version": "2026.9.19",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package for guide and shell completion workflows.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-kanban",
3
- "version": "2026.9.18",
3
+ "version": "2026.9.19",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm archetype package: a complete Kanban continuous-flow profile built on public SDK primitives.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-lifecycle-hooks",
3
- "version": "2026.9.18",
3
+ "version": "2026.9.19",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package demonstrating safe lifecycle hook registration.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-linked-test-adapters",
3
- "version": "2026.9.18",
3
+ "version": "2026.9.19",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package for optional linked-test run management adapters and reporters.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-search-advanced",
3
- "version": "2026.9.18",
3
+ "version": "2026.9.19",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package for semantic, hybrid, and reindex search workflows.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-templates",
3
- "version": "2026.9.18",
3
+ "version": "2026.9.19",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package for reusable create templates.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-todos",
3
- "version": "2026.9.18",
3
+ "version": "2026.9.19",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package for Todo markdown import and export.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-vcs-sdk-exemplar",
3
- "version": "2026.9.18",
3
+ "version": "2026.9.19",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "Beyond-PM exemplar: a VCS-style changeset workflow built entirely on public pm SDK and extension primitives.",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pm-claude",
3
3
  "description": "Native pm CLI integration for Claude Code — 28 MCP tools, 5 workflow skills, 14 slash commands, 4 subagents (coordinator, delivery-chain, triage, verification), hybrid TUI task tracking (pm as persistent store + Claude Code task panel as live view), session context injection, and full git-based project management without leaving Claude Code.",
4
- "version": "2026.9.18",
4
+ "version": "2026.9.19",
5
5
  "author": {
6
6
  "name": "unbrained",
7
7
  "url": "https://github.com/unbraind/pm-cli"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pm-codex",
3
- "version": "2026.9.18",
3
+ "version": "2026.9.19",
4
4
  "description": "Native Codex integration for pm-cli with bundled MCP tools, skills, commands, and agent workflows.",
5
5
  "author": {
6
6
  "name": "unbrained",