@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.
- package/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +20 -0
- package/dist/cli/invocation-profile.d.ts +26 -0
- package/dist/cli/invocation-profile.js +3 -0
- package/dist/cli-bundle/bundle-manifest.json +148 -148
- package/dist/cli-bundle/chunks/{chunk-GRFRKHFC.js → chunk-7CN53F4S.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-X2EVS624.js → chunk-AACGU5IA.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-AOD5WE6U.js → chunk-CCLWCESZ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-WD7BQXA7.js → chunk-J7NP7QLW.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-T4J2X3RK.js → chunk-K4VAU4HU.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-KHN4NMKT.js +238 -0
- package/dist/cli-bundle/chunks/{chunk-CA5DRNGA.js → chunk-KYG2QKNY.js} +28 -28
- package/dist/cli-bundle/chunks/{chunk-WUDF7HWM.js → chunk-OQS2Y6VN.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-XFGWFVR3.js → chunk-QA4GUEKJ.js} +20 -20
- package/dist/cli-bundle/chunks/chunk-QTHR3LXF.js +20 -0
- package/dist/cli-bundle/chunks/{chunk-FZZVWWQP.js → chunk-RVMDPIGD.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-Y2OK7IAD.js → chunk-WASMH647.js} +2 -2
- package/dist/cli-bundle/chunks/{register-list-query-43EQISX7.js → register-list-query-RMZNHSII.js} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-TSZNAKEU.js → register-mutation-HJGSGX3H.js} +2 -2
- package/dist/cli-bundle/chunks/{register-operations-KFZIKATY.js → register-operations-LBEMFUMM.js} +2 -2
- package/dist/cli-bundle/chunks/{register-setup-KTJ4ZE65.js → register-setup-MU557JAA.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-QVVOXVYI.js → chunk-5SZ4JSPZ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-PNCUNPSA.js → chunk-7Y7PAC56.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-YJYSFWSW.js → chunk-ARK4FIO4.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-C6SH62BX.js → chunk-CJ4QA4RW.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-ZDX2BCOT.js → chunk-I32L3FWW.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-GEFWBVPQ.js → chunk-I4WDON3K.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-246P5AK7.js → chunk-IKPR4VVN.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-J3GN4SQT.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-LG3SYXBX.js → chunk-OOZHQFBF.js} +9 -9
- package/dist/cli-bundle/focused-chunks/{chunk-BVOQRMHF.js → chunk-P4BA7OX7.js} +27 -26
- package/dist/cli-bundle/focused-chunks/{chunk-7D6M45AN.js → chunk-QL4MO5M2.js} +9 -9
- package/dist/cli-bundle/focused-chunks/chunk-TDHVROGL.js +3 -0
- package/dist/cli-bundle/focused-chunks/chunk-V3YMNAO7.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-YDFEWXXZ.js +59 -0
- package/dist/cli-bundle/focused-chunks/{chunk-MMX7BQLH.js → chunk-ZDBKYZFE.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-7UZHYT5B.js → chunk-ZI2YBJFH.js} +2 -2
- package/dist/cli-bundle/main.js +2 -2
- 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 +2 -2
- 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 +41 -41
- 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 +8 -8
- package/dist/cli.js +1 -1
- package/dist/core/checkpoint/mutation-checkpoint.d.ts +1 -1
- package/dist/core/checkpoint/mutation-checkpoint.js +2 -2
- package/dist/core/fs/atomic-create.d.ts +7 -0
- package/dist/core/fs/atomic-create.js +2 -0
- package/dist/core/history/history.js +1 -1
- package/dist/core/schema/runtime-schema.d.ts +1 -1
- package/dist/core/schema/runtime-schema.js +2 -2
- package/dist/core/session/session-state.js +1 -1
- package/dist/core/store/settings-concurrency.d.ts +7 -0
- package/dist/core/store/settings-concurrency.js +2 -0
- package/dist/core/store/settings.d.ts +8 -1
- package/dist/core/store/settings.js +3 -2
- package/dist/sdk/cli-contracts/flag-contracts.js +1 -1
- package/dist/sdk/contracts.d.ts +1 -0
- package/dist/sdk/contracts.js +1 -1
- package/dist/sdk/extension/install-runtime.d.ts +1 -1
- package/dist/sdk/extension/install-runtime.js +2 -2
- package/dist/sdk/governance/health.js +1 -1
- package/dist/sdk/governance/provenance-health.d.ts +27 -0
- package/dist/sdk/governance/provenance-health.js +1 -1
- package/dist/sdk/graph/index.d.ts +1 -0
- package/dist/sdk/graph/index.js +1 -1
- package/dist/sdk/graph/query-contracts.d.ts +18 -0
- package/dist/sdk/graph/query-contracts.js +2 -0
- package/dist/sdk/graph/run.d.ts +2 -0
- package/dist/sdk/graph/run.js +1 -1
- package/dist/sdk/graph/traversal.js +1 -1
- package/dist/sdk/lifecycle-policy.js +1 -1
- package/dist/sdk/public-surface.json +1 -1
- package/docs/MCP_OPTION_CONFORMANCE.md +41 -0
- package/docs/OUTPUT_PROJECTION_CONTRACTS.md +18 -2
- package/docs/PERFORMANCE.md +37 -0
- package/docs/SDK_AGENT_SESSION_CONTEXT.md +28 -4
- package/docs/SDK_LIFECYCLE.md +16 -2
- package/docs/WORKSPACE_CONCURRENCY.md +67 -0
- package/marketplace.json +2 -2
- package/package.json +2 -2
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-digital-twin/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/packages/pm-vcs/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/dist/cli-bundle/chunks/chunk-CI2JCBN2.js +0 -237
- package/dist/cli-bundle/chunks/chunk-IPR2ICDO.js +0 -20
- package/dist/cli-bundle/focused-chunks/chunk-HRANNGHM.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-LI6IGGB3.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-QKG7JD34.js +0 -3
- 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
|
-
|
|
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
|
package/docs/PERFORMANCE.md
CHANGED
|
@@ -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
|
|
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
|
package/docs/SDK_LIFECYCLE.md
CHANGED
|
@@ -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),
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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-digital-twin",
|
|
3
|
-
"version": "2026.9.
|
|
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,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.
|
|
4
|
+
"version": "2026.9.19",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "unbrained",
|
|
7
7
|
"url": "https://github.com/unbraind/pm-cli"
|