Changed (SDK contract)
- GH-1671: linked tests have no setup step, so every command embeds its build and --add re-runs heavy suites just to fix metadata: Linked tests had no setup phase, failure_categories had nine keys, and the highest item format was 2 → A phase=setup entry runs before the item's regular commands in the same sandbox; a failing setup reports setup_failed and every later entry is skipped; failure_categories gains setup_failed; an item with a setup entry is stored at item format 3, which pm 2026.10.10 through 2026.11.13 refuses to read. Migrate: Exhaustive consumers of LinkedTestFailureCategory or failure_categories add setup_failed; upgrade every reader, pinned SDK, CI host and Git merge driver before adding a setup entry to a shared tracker Eintrag pm-gh1671
- pm test-all prints the full 21-field execution_context, with host paths, on every passing linked-test row: Every run_results row printed the full 21-field execution_context, including four absolute host paths → Each item run is judged as pm test judges it: a quiet item's rows report only the decision fields, a context shared by every item that ran is hoisted to the top-level execution_context, and a non-quiet item keeps every full context. Migrate: Pass --check-context to keep every row's full execution context Eintrag pm-tcvccz
- A passing pm test --run row echoes the command's full stdout, including raw ANSI colour codes, so every quiet pass grows with the runner's report: A passing linked-test row printed the command's complete stdout and stderr, ANSI escape sequences included → A quiet passing run prints an escape-free tail of at most 6 lines and 480 characters per stream, adds stdout_omitted_bytes or stderr_omitted_bytes to shortened rows and names --full-output in omission_receipt; SDK and MCP results still carry the complete streams. Migrate: Pass --full-output where a script parses a passing linked test's complete CLI stdout; SDK and MCP consumers need no change Eintrag pm-v1mp64
- GH-1716: pm files and pm docs --add silently replace an existing link's note, and the receipt reports it as a plain change: An add on a link already stored with a different note replaced that note and reported a plain change → Such an add is refused with linked_artifact_note_conflict (exit 4) and keeps the stored note; --note-conflict replace overwrites it, --note-conflict append joins the notes, and mutation_receipt.link_outcomes reports what each requested link became. Migrate: Pass --note-conflict replace (SDK and MCP noteConflict) where a re-add is meant to revise the note, or append to keep both; identical and note-less repeats need no change Eintrag pm-gh1716
- GH-1706: a stale session-state lock makes pm release clear the claim and then exit 4, --force repeats the refusal, and claim only warns: A stale session-state lock made release clear the claim and exit 4, claim returned a bare attribution warning, and a stale lock kept by policy was refused untyped as an Item lock with a --force hint → The session-state lease is reclaimed past its TTL; claim and release exit 0 after a committed write and add release_semantic_attribution_unrecorded or claim_semantic_attribution_unrecorded with a suggestion when attribution fails; a kept stale lock is refused with stale_lock_requires_override naming lock_path and pm gc --scope locks. Migrate: Match stale_lock_requires_override instead of the old message text, and read suggestions beside the attribution warnings; release exit codes need no handling for the session lock Eintrag pm-gh1706
- GH-1684: pm context TOON focus tables spend 7-9% of the cold-start read on encoding metadata (empty json_columns and absent arrays plus two absent coordinates per unblocked row): Every block carried json_columns and an absent list of \[row, column\] pairs, even when empty, and decoders detected a block by the presence of both arrays → TOON omits empty json_columns and absent and groups missing fields by column in absent_rows; decodePmTableRows accepts PmRenderedTableCellEncoding and every earlier shape; encodePmTableRows still returns both arrays. Migrate: Detect a block by its reserved <collection\>\_encoding key beside the <collection\> array, treat a missing json_columns or absent as empty, and read absent_rows as column to row indexes, or decode with the current decodePmTableRows Eintrag pm-gh1684
- GH-1703: pm context spends a third of its default output on a fixed omission receipt whose restore hints are all --section <name\>: Every omitted field group rendered as one name,restore_with table row → When every restore_with is one shared prefix followed by the group name and the result is smaller, TOON lists the names inline as omitted_field_groups\[N\] and states restore_with once as a template ending in <name\>; JSON, SDK and MCP keep the per-row receipt. Migrate: TOON readers substitute each listed name for <name\> in the receipt-level restore_with; use --json for the typed per-row form Eintrag pm-gh1703
- GH-1702: pm test --run prints the full execution_context with host paths on every passing run; default to the lean projection: A passing run without --lean printed the full execution_context: sandbox and source tracker paths, item counts, seeding flags, the working directory and the trust object with its fingerprint → A passing, mismatch-free run with no failure category prints pm_context_mode, workspace_context_mode, mismatch_detected, trusted, trust_reason and a restore_with hint in every format; failures, refusals, skips and mismatches keep the full context. Migrate: Read trusted and trust_reason instead of trust.trusted and trust.reason on passing runs, or pass --check-context to keep the full context with every path, count and the trust fingerprint; SDK runTest results are unchanged Eintrag pm-gh1702
- An annotation edit accepts text copied from a strings_compacted read, so a read-modify-write round trip silently truncates the stored entry: A compacted string ended with a bare ellipsis, and an edit accepted text copied from a compacted read → A compacted string ends with the marker …\[+N chars\] naming the omitted UTF-16 code units, and an annotation --edit whose text ends with that marker is refused with annotation_text_compacted. Migrate: Detect compaction through read_output.strings_compacted or the trailing …\[+N chars\] marker instead of a bare ellipsis; re-read the full entry with --output-budget unbounded before editing it Eintrag pm-n98pir
Fixed
- GH-1710: budget compaction clips next_cursor to 240 characters, so --after rejects the cursor the page emitted and the rest of the result set is unreachable Eintrag pm-gh1710
Security
- Identity refusal table omits linked-test updated_by and plan step owner, so those identity locations still accept URL userinfo Eintrag pm-7ivxas
Other
- Exclude the generated CHANGELOG.md from the npm tarball so publication weight stops growing with release history Eintrag pm-jndg9a
Changed (SDK contract)
- GH-1707: URL credential redaction strips host and path from public URLs with @ in the path, and a stored credential-bearing identity is echoed verbatim in claim refusals: A public URL with an @ in its path lost its host and path and withheld the retry; a credential-bearing PM_AUTHOR, --author or --assignee was stored and echoed verbatim in claim refusals → Only an http(s), ws(s) or ftp URL that provably holds no userinfo is left alone, so scoped-package and blob URLs keep an executable retry; an asserted or configured identity, --assignee, a seed author or an identity runtime field carrying URL userinfo is refused with invalid_argument_value, and refusals, warnings and claim envelopes redact a stored one. Migrate: Use a plain name for PM_AUTHOR, --author, default_author, --assignee and seed author= values; rewrite a holder stored by an older version with pm update <id\> --assignee <name\> --force, or take it over with pm claim <id\> --force Eintrag pm-gh1707
- GH-1704: secret guard flags short credential values only under password keys; api_key, client_secret, token and \*\_TOKEN/\*\_SECRET keys pass: A short credential value under api_key, client_secret, token, secret_key, private_key, passwd, pwd or a compound key such as DB_PASSWORD or GITHUB_TOKEN produced no finding → Such a value produces a credential_key_assignment finding in advise mode and is refused in block mode; pm token budgets, counts, placeholders, masks, paths and prose stay clean. Migrate: Accept the credential_key_assignment rule id wherever finding rules are matched; replace the literal with a placeholder or reference, or review a force override in block mode Eintrag pm-gh1704
Security
- Identity refusal reads only top-level fields, so a runtime field mapped onto comments, notes, learnings or dependencies can store a nested author with URL userinfo Eintrag pm-ziv9yb
Changed (SDK contract)
- A time-bounded gate waiver expires straight into a release block: no notice window, and the gate's text output names neither the item nor the expiry: Reports said nothing about an approaching expiry; a waiver stayed silent until it expired and failed the gate → Reports carry waiver_notices for valid live waivers inside the declared waiver_notice_days window, and ok is unchanged. Migrate: Code that constructs BoundaryFixtureReport or DefectGateEvidenceReport adds waiver_notices: \[\]; declare waiver_notice_days in the policy or registry to receive notices Eintrag pm-xcndcu
- pm update --unset blocked_by (or --blocked-by none) deletes every blocked_by edge, not only the scalar's: clearing blocker A silently drops an independent prerequisite B: Clearing the scalar removed every blocked_by dependency edge → Clearing the scalar removes only the rows naming its own target; independent blocked_by edges keep blocking, and removed rows are named in a dependencies_removed warning. Migrate: Remove the remaining edges with --dep-remove kind=blocked_by, or one at a time with --dep-remove id=<id\>,kind=blocked_by Eintrag pm-4yxzvd
- A key repeated inside one structured entry silently replaces the earlier value, so note prose such as ', path: b.txt' relinks a different file: A key repeated inside one entry kept its last value → A repeated key is refused with structured_entry_key_repeated before anything is written. Migrate: Give each key once per entry, quote prose that contains a key-shaped word, or repeat the flag for another entry Eintrag pm-oglm0t
- files/docs --add refusal does not name the note segment it misread as a key, nor offer the standalone --note flag: Note prose misread as a key was refused with invalid_argument_value or a generic command failure → It is refused with linked_artifact_note_key_misread, naming the segment and key, with a retry that quotes the note. Migrate: Match the new code, or follow recovery.suggested_retry_args Eintrag pm-pwqiao
- GH-1700: pm test --add returns only the changed linked test, like pm comments --add: A write returned the whole stored collection, count was the stored total, and failure_categories was always present → A write returns only the entries it added or rewrote, with count (returned), total_count, mutation_receipt and omission_receipt; failure_categories appears only when tests ran. Migrate: Pass fullHistory (CLI --full-history, MCP full) to receive the whole collection after a write, read total_count for the stored total, and read failure_categories optionally Eintrag pm-gh1700
Fixed
- The release Sentry gate counts environment=test issues, so a downstream extension's CI test run blocks the daily pm-cli release Eintrag pm-usn5k2
Other
- Exclude the repository-only release runbook docs/RELEASING.md from the npm tarball to restore publication headroom Eintrag pm-pvun8c
- Exclude five repository-only docs from the npm tarball to restore publication headroom for the collection-mutation bundle Eintrag pm-tuxw1i
Security
- Telemetry and Sentry scrubbers keep URL credentials whose host has no dot: attempted_args ships https://token@localhost and user:password@registry:8080 verbatim Eintrag pm-5htunt
- Refusal recovery bundles echo URL credentials verbatim: attempted_command and normalized_args repeat a credentialed package source on stdout and in logs Eintrag pm-nhauur
- GH-1699: secret guard recognises quoted keys, nested JSON values and XML elements Eintrag pm-gh1699
Other
- Exclude the dated Codex plugin research plan from the npm tarball to restore publication headroom Eintrag pm-7ouxrr
Fixed
- Distinguish Vitest coverage-threshold exits from test assertion failures in combined runner verdicts Eintrag pm-qmb6h8
- GH-1694: recover pinned Bun and verified uploader downloads after GitHub asset gateway failures Eintrag pm-gh1694
- GH-1693: preserve complete flag tokens in bounded close-refusal headlines Eintrag pm-gh1693
- GH-1689: redact leading-slash regex sources with indexed safe refusals Eintrag pm-gh1689
- GH-1695: accept settings paths and provide bounded config-key recovery Eintrag pm-gh1695
Other
- Stabilize alias clear/prune race verification under monolithic release coverage Eintrag pm-01kwb2
- Restore publication headroom with lossless declaration delimiter compaction Eintrag pm-5aze0q
- Adopt the next mature tooling maintenance cohort after registry cooldown Eintrag pm-ogzvx6
Fixed
- MCP pm_comments lists only the newest 20 comments by default: the backward output cursor stops at that producer page and the last page reports has_more without a continuation Eintrag pm-sbqn4h
- Combining an annotation or linked-artifact mutation with a universal output control is refused untyped: code command_failed and pm --help examples instead of a stable code and a retry without the control Eintrag pm-rrwh2o
- TOON get --fields drops an empty child collection nested inside a selected object field, while JSON keeps it Eintrag pm-fkhdy8
- TOON annotation listings drop null rows while count reports them, so a malformed collection renders fewer rows than its count Eintrag pm-e3hfv8
- Release verification shares the build job's timeout and waits fifteen minutes while npm's publish-time scan can hold a version longer: 2026.11.8 was published but the job was cancelled before acceptance Eintrag pm-0jzl5t
- A malformed comments, notes or learnings entry in an item document crashes annotation reads with unknown_error (sortLogValues calls localeCompare on a missing text) Eintrag pm-30tjoh
Other
- Exclude the dated ecosystem planning review from the npm tarball to restore publication headroom Eintrag pm-1ke3mz
Fixed
- MCP annotation and linked-artifact tools silently read when add is passed at the top level: the strict schema declares add/text but dispatch only hoists ifAbsent Eintrag pm-wsqxwb
- pm comments --edit/--delete take an absolute index while a budget-truncated listing reports count as the page size and shows no row index, so 'edit the last comment' by count rewrites an older comment Eintrag pm-hka7ep
- Bare pm comments / pm notes reads keep the oldest page when output must be bounded, withholding the newest entries (GH-1605 fixed this for history only) Eintrag pm-8s53lj
- CLI argv keeps one value silently when two spellings of one extension flag differ (--status-filter a -s b), while direct callers are refused with extension_option_spelling_conflict Eintrag pm-wlxf8f
- pm comments/notes <id\> --add --file <path\> is refused as positional-and---add conflict instead of naming the swallowed --file flag, so the annotation flag-like check from pm-vcu7 loses precedence Eintrag pm-y26mvc
- GH-1667: sdk/graph does not export ProjectedGraphResult, the public return type of runGraph, and the merge conflict_resolution union has no public name, so extensions derive both Eintrag pm-gh1667
- GH-1666: per-command help and contracts for extension commands omit the inherited host flags (--json, --author, --pm-path) the command accepts and mark no flag as host- or extension-owned Eintrag pm-gh1666
- GH-1665: extension flag contracts omit the SDK option key, so PmClient.run and the extension test harness silently ignore a CLI-spelled option such as status-filter and fall back to the default Eintrag pm-gh1665
- TOON get --fields spends four lines on a complete omission receipt and drops requested empty collections, so a narrow read is two-thirds receipt and absent-vs-empty depends on that receipt Eintrag pm-sj66lm
- GH-1662: an infeasible --token-budget on context --for orient exits 0 with no context and contradictory receipts, its restore_with retry fails, and get/list intent receipts undercount the emitted envelope Eintrag pm-gh1662
- GH-1678: a scoped registerRenderer replacement bypasses --output-budget and its read_output receipt reports within_budget for the native payload, not the delivered bytes Eintrag pm-gh1678
Other
- Restore package headroom by excluding the generated refusal-closure census from the npm tarball Eintrag pm-dwy8kb
- Unknown-option refusals on extension commands with declared flags carry code unknown_option and list only the flags the command accepts Eintrag pm-1du7s3
Fixed
- GH-1677: the stale-revision refusal's next_steps and examples drop --pm-path, --no-extensions and the output mode, so the recovery reads return another tracker's item Eintrag pm-gh1677
- GH-1676: a pm close refused for missing close fields suggests a separate pm update and a retry, although pm close accepts --resolution, --expected-result and --actual-result itself Eintrag pm-gh1676
- GH-1674: pm list --fields/--compact and pm search print the verbose envelope that GH-1642 removed from the default projection, so --fields costs more than the default Eintrag pm-gh1674
- GH-1663: nested get --fields projections pad unrequested sibling collections with empty arrays (linked.files emits tests: \[\] and docs: \[\] for populated collections) and claim_state.claimed expands to the whole group Eintrag pm-gh1663
Other
- Packing ships only the declarations an exported types entry reaches, restoring the artifact headroom PR 1680 exhausted Eintrag pm-dg68kr
Fixed
- Release refuses an over-budget Sentry-injected package before tagging instead of stranding the tag Eintrag pm-ofllco
- GH-1670: pm health --full --summary silently drops --summary and emits the full projection (15.7 KB vs 636 B) with no receipt Eintrag pm-gh1670
Fixed
- GH-1660: the project telemetry block pm init writes is inert, so the wizard's telemetry decline and the project endpoint are ignored, and no supported way points opted-in tests at a local collector Eintrag pm-gh1660
- Start-blocker and revision-conflict follow-ups from the PR 1654 CodeRabbit full review Eintrag pm-mrvq8u
- Expected revisions advance from the pre-override document when an item_store_write override transforms contents Eintrag pm-thbdxu
- GH-1655: SDK placeholder and type refusals name CLI flags, and parent: null is refused, so typed callers have no documented way to clear a field Eintrag pm-gh1655