@unbrained/pm-cli 2026.10.11 → 2026.10.12

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 (130) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +18 -0
  3. package/dist/cli/commander-usage.d.ts +5 -5
  4. package/dist/cli/commander-usage.js +3 -3
  5. package/dist/cli/error-guidance.d.ts +2 -0
  6. package/dist/cli/error-guidance.js +2 -2
  7. package/dist/cli/help-json-payload.js +1 -1
  8. package/dist/cli/main.d.ts +1 -0
  9. package/dist/cli/main.js +4 -4
  10. package/dist/cli/register-operations.d.ts +9 -4
  11. package/dist/cli/register-operations.js +1 -1
  12. package/dist/cli-bundle/bundle-manifest.json +1 -1
  13. package/dist/cli-bundle/chunks/{chunk-2JYTSTQP.js → chunk-3LQTJN4J.js} +2 -2
  14. package/dist/cli-bundle/chunks/{chunk-YMLF6QT7.js → chunk-6PZPUJW3.js} +28 -28
  15. package/dist/cli-bundle/chunks/{chunk-RUT3CCAG.js → chunk-B465HPS5.js} +2 -2
  16. package/dist/cli-bundle/chunks/{chunk-ESRACL6K.js → chunk-DT3KUUKY.js} +2 -2
  17. package/dist/cli-bundle/chunks/{chunk-SSY4OSJR.js → chunk-GUVKPOY6.js} +2 -2
  18. package/dist/cli-bundle/chunks/chunk-ILQEZ4Y6.js +2 -0
  19. package/dist/cli-bundle/chunks/{chunk-RBPOO46D.js → chunk-JRRXWH5B.js} +2 -2
  20. package/dist/cli-bundle/chunks/{chunk-MEWBSWE3.js → chunk-LH5QDBMN.js} +2 -2
  21. package/dist/cli-bundle/chunks/{chunk-KNW3RSLS.js → chunk-M5NDSW6E.js} +30 -30
  22. package/dist/cli-bundle/chunks/{chunk-K2UTE75T.js → chunk-MHPU2LDF.js} +2 -2
  23. package/dist/cli-bundle/chunks/{chunk-OBLO45UM.js → chunk-QM3M7GB5.js} +2 -2
  24. package/dist/cli-bundle/chunks/{chunk-S445XEYT.js → chunk-UABZJXIS.js} +2 -2
  25. package/dist/cli-bundle/chunks/{chunk-ZWRLAOA4.js → chunk-X2I2EEAS.js} +2 -2
  26. package/dist/cli-bundle/chunks/{register-list-query-T6BOR67M.js → register-list-query-OR33UEML.js} +2 -2
  27. package/dist/cli-bundle/chunks/{register-mutation-6NXR7SAJ.js → register-mutation-R34EJ3NH.js} +2 -2
  28. package/dist/cli-bundle/chunks/register-operations-UHSMEHSF.js +2 -0
  29. package/dist/cli-bundle/chunks/{register-setup-MAYFPKBX.js → register-setup-5E3PT22L.js} +2 -2
  30. package/dist/cli-bundle/focused-chunks/{chunk-SIEGIPNT.js → chunk-7QIZB2F2.js} +7 -7
  31. package/dist/cli-bundle/focused-chunks/{chunk-PLTTMQAW.js → chunk-AJG3DBXR.js} +2 -2
  32. package/dist/cli-bundle/focused-chunks/chunk-AXBO53EQ.js +2 -0
  33. package/dist/cli-bundle/focused-chunks/{chunk-W5AE7GKZ.js → chunk-CYEZLKLL.js} +2 -2
  34. package/dist/cli-bundle/focused-chunks/{chunk-PBCYGO7X.js → chunk-FXRWJEQ5.js} +2 -2
  35. package/dist/cli-bundle/focused-chunks/{chunk-GVGFUD52.js → chunk-IKJFAU32.js} +2 -2
  36. package/dist/cli-bundle/focused-chunks/{chunk-DMSADMEU.js → chunk-OGOLIS5R.js} +2 -2
  37. package/dist/cli-bundle/focused-chunks/chunk-PPH5N26M.js +2 -0
  38. package/dist/cli-bundle/focused-chunks/{chunk-WAOXID5J.js → chunk-RNAWRTQV.js} +2 -2
  39. package/dist/cli-bundle/focused-chunks/{chunk-B3YW6H2I.js → chunk-RZVNGUT7.js} +2 -2
  40. package/dist/cli-bundle/focused-chunks/{chunk-52UJEHEV.js → chunk-SV6YYZLR.js} +2 -2
  41. package/dist/cli-bundle/focused-chunks/{chunk-EIOQNLBQ.js → chunk-TS46OZD5.js} +2 -2
  42. package/dist/cli-bundle/focused-chunks/{chunk-KNJR2WUO.js → chunk-VBTLX5SN.js} +62 -62
  43. package/dist/cli-bundle/focused-chunks/{chunk-JGFSSR3G.js → chunk-YCOJLIDI.js} +3 -3
  44. package/dist/cli-bundle/focused-chunks/chunk-YDJT33JU.js +2 -0
  45. package/dist/cli-bundle/focused-chunks/{chunk-AU6VJGTY.js → chunk-Z4T3637Y.js} +2 -2
  46. package/dist/cli-bundle/main.js +22 -22
  47. package/dist/cli-bundle/sdk-authoring.js +1 -1
  48. package/dist/cli-bundle/sdk-contracts.js +1 -1
  49. package/dist/cli-bundle/sdk-core.js +31 -31
  50. package/dist/cli-bundle/sdk-governance.js +1 -1
  51. package/dist/cli-bundle/sdk-graph.js +1 -1
  52. package/dist/cli-bundle/sdk-merge.js +24 -24
  53. package/dist/cli-bundle/sdk-query.js +1 -1
  54. package/dist/cli-bundle/sdk-runtime.js +1 -1
  55. package/dist/cli-bundle/sdk-testing.js +1 -1
  56. package/dist/cli-bundle/sdk.js +8 -8
  57. package/dist/core/history/event-classification.d.ts +1 -1
  58. package/dist/core/history/event-classification.js +1 -1
  59. package/dist/core/item/item-format.d.ts +2 -0
  60. package/dist/core/item/item-format.js +2 -2
  61. package/dist/core/telemetry/runtime.d.ts +1 -1
  62. package/dist/core/telemetry/runtime.js +2 -2
  63. package/dist/core/test/background-runs.d.ts +1 -0
  64. package/dist/core/test/background-runs.js +2 -2
  65. package/dist/sdk/agent/command-suggestions.d.ts +2 -0
  66. package/dist/sdk/agent/command-suggestions.js +1 -1
  67. package/dist/sdk/cli-contracts/flag-contracts.js +1 -1
  68. package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +1 -1
  69. package/dist/sdk/cli-contracts/grammar-contracts.js +1 -1
  70. package/dist/sdk/cli-contracts/registration-helpers.d.ts +1 -4
  71. package/dist/sdk/cli-contracts/registration-helpers.js +1 -1
  72. package/dist/sdk/cli-contracts/tool-parameter-tables.js +1 -1
  73. package/dist/sdk/cli-contracts/tool-schema.d.ts +1 -1
  74. package/dist/sdk/cli-contracts/tool-schema.js +1 -1
  75. package/dist/sdk/core.d.ts +1 -0
  76. package/dist/sdk/core.js +1 -1
  77. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -1
  78. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1 -1
  79. package/dist/sdk/governance/artifact-ledgers.js +1 -1
  80. package/dist/sdk/index.d.ts +2 -0
  81. package/dist/sdk/index.js +1 -1
  82. package/dist/sdk/public-surface.json +1 -1
  83. package/dist/sdk/test/batch.js +1 -1
  84. package/dist/sdk/test/command-args.d.ts +4 -0
  85. package/dist/sdk/test/command-args.js +2 -0
  86. package/dist/sdk/test/entry.d.ts +3 -0
  87. package/dist/sdk/test/entry.js +1 -1
  88. package/dist/sdk/test/execution.d.ts +15 -4
  89. package/dist/sdk/test/execution.js +2 -2
  90. package/dist/sdk/test/prerequisites.d.ts +6 -0
  91. package/dist/sdk/test/prerequisites.js +2 -0
  92. package/dist/sdk/test/trust.js +1 -1
  93. package/dist/sdk/test/update.d.ts +55 -0
  94. package/dist/sdk/test/update.js +2 -0
  95. package/dist/types.d.ts +4 -0
  96. package/dist/types.js +1 -1
  97. package/docs/LINKED_TEST_EDITS.md +79 -0
  98. package/docs/RELEASING.md +19 -8
  99. package/docs/SDK.md +178 -636
  100. package/docs/SDK_EVIDENCE_TRACEABILITY.md +4 -0
  101. package/docs/TESTING.md +13 -0
  102. package/docs/generated/FLAG_LEXICON_BUDGETS.md +2 -2
  103. package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +8 -3
  104. package/docs/performance/runner-qualification.md +36 -0
  105. package/marketplace.json +1 -1
  106. package/package.json +1 -1
  107. package/packages/pm-beads/package.json +1 -1
  108. package/packages/pm-calendar/package.json +1 -1
  109. package/packages/pm-command-kit/package.json +1 -1
  110. package/packages/pm-digital-twin/package.json +1 -1
  111. package/packages/pm-governance-audit/package.json +1 -1
  112. package/packages/pm-guide-shell/package.json +1 -1
  113. package/packages/pm-kanban/package.json +1 -1
  114. package/packages/pm-lifecycle-hooks/package.json +1 -1
  115. package/packages/pm-linked-test-adapters/package.json +1 -1
  116. package/packages/pm-search-advanced/package.json +1 -1
  117. package/packages/pm-templates/package.json +1 -1
  118. package/packages/pm-todos/package.json +1 -1
  119. package/packages/pm-vcs/package.json +1 -1
  120. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  121. package/plugins/pm-claude/package.json +1 -1
  122. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  123. package/plugins/pm-codex/package.json +1 -1
  124. package/plugins/pm-codex/plugin.json +1 -1
  125. package/runtime-dependencies.json +1 -1
  126. package/dist/cli-bundle/chunks/chunk-BXSXT5Z6.js +0 -2
  127. package/dist/cli-bundle/chunks/register-operations-PDOBQZUJ.js +0 -2
  128. package/dist/cli-bundle/focused-chunks/chunk-2CJWTLQG.js +0 -2
  129. package/dist/cli-bundle/focused-chunks/chunk-MJQ253F3.js +0 -2
  130. package/dist/cli-bundle/focused-chunks/chunk-WOEZJUA2.js +0 -2
@@ -0,0 +1,55 @@
1
+ import type { GlobalOptions } from "../../core/shared/command-types.js";
2
+ import type { LinkedTest } from "../../types/index.js";
3
+ import type { TestCommandOptions } from "./execution.js";
4
+ /** Unambiguous selector evaluated against the current locked collection. */
5
+ export type LinkedTestUpdateSelector = {
6
+ index: number;
7
+ } | {
8
+ command: string;
9
+ } | {
10
+ path: string;
11
+ };
12
+ /** Explicit metadata values; null removes an optional value without replacing other fields. */
13
+ export type LinkedTestMetadataPatch = {
14
+ [K in keyof Omit<LinkedTest, "command" | "provenance" | "provenance_invalid" | "updated_by" | "updated_at">]?: K extends "scope" ? LinkedTest[K] : LinkedTest[K] | null;
15
+ };
16
+ /** One metadata revision with ordinary mutation ownership and history controls. */
17
+ export interface UpdateLinkedTestOptions {
18
+ /** Current entry identity or one-based list position. */
19
+ selector: LinkedTestUpdateSelector;
20
+ /** Fields to change; command and provenance cannot be replaced. */
21
+ patch: LinkedTestMetadataPatch;
22
+ /** Explicit author override, otherwise the configured or detected identity. */
23
+ author?: string;
24
+ /** Explanation retained on the single history event. */
25
+ message?: string;
26
+ /** Explicit ownership override. */
27
+ force?: boolean;
28
+ }
29
+ /** Receipt identifying the edited entry and semantically changed metadata. */
30
+ export interface UpdateLinkedTestResult {
31
+ /** Successful mutation or unchanged retry. */
32
+ ok: true;
33
+ /** Owning item ID. */
34
+ id: string;
35
+ /** Current ordered linked-test collection. */
36
+ tests: LinkedTest[];
37
+ /** Whether authoritative state changed. */
38
+ changed: boolean;
39
+ /** Current collection size. */
40
+ count: number;
41
+ /** One-based position of the selected entry. */
42
+ updated_index: number;
43
+ /** Explicit metadata keys whose normalized values changed. */
44
+ updated_fields: string[];
45
+ }
46
+ /** Resolve transport edit flags without accepting ambiguous selectors or implicit replacement. */
47
+ export declare function parseLinkedTestUpdateOptions(options: {
48
+ update?: string;
49
+ updateIndex?: string | number;
50
+ setJson?: string;
51
+ }): Pick<UpdateLinkedTestOptions, "selector" | "patch"> | undefined;
52
+ /** Keep metadata editing a separate atomic operation from execution or other collection changes. */
53
+ export declare function assertLinkedTestEditUsage(options: TestCommandOptions): void;
54
+ /** Patch one linked-test entry atomically, keeping ordering and original command provenance. */
55
+ export declare function updateLinkedTest(id: string, options: UpdateLinkedTestOptions, global?: GlobalOptions): Promise<UpdateLinkedTestResult>;
@@ -0,0 +1,2 @@
1
+ (function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="cfcc5f4f-caf0-5a2e-8a9d-219c3afb5d2d")}catch{}})();import{getActiveExtensionRegistrations}from"../../core/extensions/index.js";import{resolveItemTypeRegistry}from"../../core/item/type-registry.js";import{normalizeLinkedTest}from"../../core/item/item-format.js";import{parseOnlyIndexValue}from"../../core/test/run-selectors.js";import{resolveAuthor}from"../../core/shared/author.js";import{EXIT_CODE}from"../../core/shared/constants.js";import{PmCliError}from"../../core/shared/errors.js";import{stableValueEquals}from"../../core/shared/serialization.js";import{nowIso}from"../../core/shared/time.js";import{mutateItemWithHistoryContextResolver}from"../../core/store/item-store.js";import{resolvePmRoot}from"../../core/store/paths.js";import{readSettings}from"../../core/store/settings.js";import{assertInitializedTracker}from"../environment/tracker-preflight.js";import{assertLinkedTestContext,STRUCTURED_LINKED_TEST_KEYS}from"./entry.js";import{parseLinkedTestJsonEntries}from"./parsers.js";function parseLinkedTestUpdateOptions(options){if(options.update===void 0&&options.updateIndex===void 0&&options.setJson===void 0)return;if(options.update===void 0==(options.updateIndex===void 0)||options.setJson===void 0)throw new PmCliError("Use exactly one --update or --update-index with --set-json",EXIT_CODE.USAGE);let patch;try{patch=JSON.parse(options.setJson)}catch{throw new PmCliError("--set-json must contain a JSON object with explicit linked-test metadata fields",EXIT_CODE.USAGE)}if(options.updateIndex!==void 0)return{selector:{index:parseOnlyIndexValue(options.updateIndex,"--update-index")},patch};const value=options.update,prefix=/^(command|path)=/u.exec(value);return{selector:prefix?.[1]==="path"?{path:value.slice(prefix[0].length)}:{command:prefix?value.slice(prefix[0].length):value},patch}}function assertLinkedTestEditUsage(options){if([options.list,options.run,options.progress,options.timeout!==void 0,options.acknowledgeLinkedTests,options.metricBelow!==void 0,options.metricDiff!==void 0,(options.add?.length??0)>0,(options.addJson?.length??0)>0,(options.remove?.length??0)>0,(options.removeIndex?.length??0)>0].some(Boolean))throw new PmCliError("Edit linked-test metadata separately from listing, additions, removals, execution options, metric filters and trust acknowledgement",EXIT_CODE.USAGE)}function selectIndex(tests,selector){if(typeof selector!="object"||selector===null||Array.isArray(selector))throw new PmCliError("Select one linked test by index, command, or path",EXIT_CODE.USAGE);const keys=Object.keys(selector);if(keys.length!==1||!["index","command","path"].includes(keys[0]))throw new PmCliError("Select one linked test by index, command, or path",EXIT_CODE.USAGE);if("index"in selector){const index=parseOnlyIndexValue(selector.index,"--update-index");if(index<=tests.length)return index-1}else{const key="command"in selector?"command":"path",value="command"in selector?selector.command:selector.path;if(typeof value!="string"||value.trim().length===0)throw new PmCliError("Linked-test selector must be a non-empty command or path",EXIT_CODE.USAGE);const matches=tests.flatMap((test,index)=>test[key]===value?[index]:[]);if(matches.length===1)return matches[0];if(matches.length>1)throw new PmCliError(`Linked-test selector is ambiguous; matching indexes: ${matches.map(index=>index+1).join(", ")}`,EXIT_CODE.USAGE,{code:"linked_test_update_ambiguous",required:"List linked tests and select one current --update-index."})}throw new PmCliError("No linked test matched the update selector",EXIT_CODE.NOT_FOUND,{code:"linked_test_update_no_match",required:"List linked tests and select a current command, path, or --update-index."})}function applyPatch(test,patch){if(typeof patch!="object"||patch===null||Array.isArray(patch))throw new PmCliError("Linked-test metadata patch must be a JSON object",EXIT_CODE.USAGE);const keys=Object.keys(patch);if(keys.length===0||keys.some(key=>!STRUCTURED_LINKED_TEST_KEYS.includes(key)||["command","cmd","timeout"].includes(key)))throw new PmCliError("Patch explicit linked-test metadata fields; command, aliases and provenance cannot be edited",EXIT_CODE.USAGE);if(patch.scope===null)throw new PmCliError("scope is required and cannot be cleared",EXIT_CODE.USAGE);const metadata=Object.fromEntries(Object.entries(test).filter(([key])=>STRUCTURED_LINKED_TEST_KEYS.includes(key))),parsed=normalizeLinkedTest(parseLinkedTestJsonEntries(JSON.stringify({...metadata,command:test.command??"legacy-path-only",...Object.fromEntries(Object.entries(patch).map(([key,value])=>[key,value===null?void 0:value]))}),"--set-json")[0]);assertLinkedTestContext(parsed);const fields=keys.filter(key=>!stableValueEquals(test[key],parsed[key])),next={...test};for(const key of fields){const value=parsed[key];Object.assign(next,{[key]:value}),value===void 0&&delete next[key]}if(!next.command?.trim()&&!next.path?.trim())throw new PmCliError("Linked-test entry must retain a command or path",EXIT_CODE.USAGE);return{test:next,fields}}async function updateLinkedTest(id,options,global2={}){const pmRoot=resolvePmRoot(process.cwd(),global2.path);await assertInitializedTracker(pmRoot);const settings=await readSettings(pmRoot),author=resolveAuthor(options.author,settings.author_default),typeRegistry=resolveItemTypeRegistry(settings,getActiveExtensionRegistrations());let updatedIndex=0,updatedFields=[];const result=await mutateItemWithHistoryContextResolver({pmRoot,settings,id,author,op:"tests_update",message:options.message,force:options.force,skipNoop:!0,typeToFolder:typeRegistry.type_to_folder,resolveHistoryContext:()=>({linked_test_update:{index:updatedIndex,fields:updatedFields}}),mutate(document){const tests2=document.metadata.tests??[],index=selectIndex(tests2,options.selector),patch=applyPatch(tests2[index],options.patch);return updatedIndex=index+1,updatedFields=patch.fields,patch.fields.length===0?{changedFields:[]}:(document.metadata.tests=tests2.map((test,position)=>position===index?{...patch.test,updated_by:author,updated_at:nowIso()}:test),{changedFields:["tests"]})}}),tests=result.item.tests;return{ok:!0,id:result.item.id,tests,count:tests.length,changed:result.changedFields.length>0,updated_index:updatedIndex,updated_fields:updatedFields}}export{assertLinkedTestEditUsage,parseLinkedTestUpdateOptions,updateLinkedTest};
2
+ //# sourceMappingURL=update.js.map
package/dist/types.d.ts CHANGED
@@ -195,6 +195,10 @@ export interface LinkedTest {
195
195
  provenance?: LinkedTestProvenance;
196
196
  /** Explicit fail-closed marker retained when stored provenance is malformed. */
197
197
  provenance_invalid?: true;
198
+ /** Author of the most recent explicit metadata edit; creation provenance is retained. */
199
+ updated_by?: string;
200
+ /** ISO timestamp of the most recent explicit metadata edit. */
201
+ updated_at?: string;
198
202
  /** Value that configures or reports env set for this contract. */
199
203
  env_set?: Record<string, string>;
200
204
  /** Value that configures or reports env clear for this contract. */
package/dist/types.js CHANGED
@@ -1,2 +1,2 @@
1
- (function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="e6847fdd-b2c1-5503-b510-56fdfdcf933f")}catch{}})();const BUILTIN_ITEM_TYPE_VALUES=["Epic","Feature","Task","Chore","Issue","Decision","Event","Reminder","Milestone","Meeting","Plan"],ITEM_TYPE_VALUES=BUILTIN_ITEM_TYPE_VALUES,STATUS_VALUES=["draft","open","in_progress","blocked","closed","canceled"],RUNTIME_STATUS_ROLE_VALUES=["draft","active","blocked","terminal","terminal_done","terminal_canceled","default_open","default_close","default_cancel"],RUNTIME_FIELD_TYPE_VALUES=["string","number","boolean","string_array","array","object"],RUNTIME_FIELD_COMMAND_VALUES=["create","update","update_many","list","search","calendar","context"],RUNTIME_UNKNOWN_FIELD_POLICY_VALUES=["allow","warn","reject"],DEPENDENCY_KIND_VALUES=["blocks","parent","child","parent_child","child_of","related","related_to","discovered_from","blocked_by","incident_from","epic","implements","recurs_from","supersedes","task","verifies"],SCOPE_VALUES=["project","global"],RISK_VALUES=["low","medium","high","critical"],ISSUE_SEVERITY_VALUES=["low","medium","high","critical"],CONFIDENCE_TEXT_VALUES=["low","medium","high"],ITEM_FORMAT_VALUES=["toon","json_markdown"],SPRINT_RELEASE_FORMAT_POLICY_VALUES=["warn","strict_error"],PARENT_REFERENCE_POLICY_VALUES=["warn","strict_error"],VALIDATE_METADATA_PROFILE_VALUES=["core","strict","custom"],GOVERNANCE_PRESET_VALUES=["minimal","default","strict","custom"],GOVERNANCE_OWNERSHIP_ENFORCEMENT_VALUES=["none","warn","strict"],GOVERNANCE_CREATE_MODE_DEFAULT_VALUES=["progressive","strict"],GOVERNANCE_CLOSE_VALIDATION_DEFAULT_VALUES=["off","warn","strict"],GOVERNANCE_WORKFLOW_ENFORCEMENT_VALUES=["off","warn","strict"],GOVERNANCE_DUPLICATE_DETECTION_MODE_VALUES=["off","advisory","strict"],VALIDATE_METADATA_REQUIRED_FIELD_VALUES=["author","acceptance_criteria","estimated_minutes","close_reason","reviewer","risk","confidence","sprint","release"],RECURRENCE_FREQUENCY_VALUES=["daily","weekly","monthly","yearly"],RECURRENCE_WEEKDAY_VALUES=["mon","tue","wed","thu","fri","sat","sun"];function weekdayOrderIndex(value){return RECURRENCE_WEEKDAY_VALUES.indexOf(value)}const PLAN_MODE_VALUES=["draft","research","review","approved","executing","paused","completed","superseded"],PLAN_STEP_STATUS_VALUES=["pending","in_progress","completed","blocked","skipped","superseded"],PLAN_HARNESS_VALUES=["codex","claude-code","cursor","generic"],PLAN_STEP_LINK_KIND_VALUES=["related","blocks","blocked_by","depends_on","discovered_from","implements","recurs_from","verifies","supersedes"],CONTEXT_DEPTH_VALUES=["brief","standard","deep","full"],CONTEXT_SECTION_VALUES=["hierarchy","activity","progress","recently_created","unparented","blockers","files","workload","staleness","tests"];export{BUILTIN_ITEM_TYPE_VALUES,CONFIDENCE_TEXT_VALUES,CONTEXT_DEPTH_VALUES,CONTEXT_SECTION_VALUES,DEPENDENCY_KIND_VALUES,GOVERNANCE_CLOSE_VALIDATION_DEFAULT_VALUES,GOVERNANCE_CREATE_MODE_DEFAULT_VALUES,GOVERNANCE_DUPLICATE_DETECTION_MODE_VALUES,GOVERNANCE_OWNERSHIP_ENFORCEMENT_VALUES,GOVERNANCE_PRESET_VALUES,GOVERNANCE_WORKFLOW_ENFORCEMENT_VALUES,ISSUE_SEVERITY_VALUES,ITEM_FORMAT_VALUES,ITEM_TYPE_VALUES,PARENT_REFERENCE_POLICY_VALUES,PLAN_HARNESS_VALUES,PLAN_MODE_VALUES,PLAN_STEP_LINK_KIND_VALUES,PLAN_STEP_STATUS_VALUES,RECURRENCE_FREQUENCY_VALUES,RECURRENCE_WEEKDAY_VALUES,RISK_VALUES,RUNTIME_FIELD_COMMAND_VALUES,RUNTIME_FIELD_TYPE_VALUES,RUNTIME_STATUS_ROLE_VALUES,RUNTIME_UNKNOWN_FIELD_POLICY_VALUES,SCOPE_VALUES,SPRINT_RELEASE_FORMAT_POLICY_VALUES,STATUS_VALUES,VALIDATE_METADATA_PROFILE_VALUES,VALIDATE_METADATA_REQUIRED_FIELD_VALUES,weekdayOrderIndex};
1
+ (function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="d293b107-03ce-51f2-8ade-8a9f0ec0b4db")}catch{}})();const BUILTIN_ITEM_TYPE_VALUES=["Epic","Feature","Task","Chore","Issue","Decision","Event","Reminder","Milestone","Meeting","Plan"],ITEM_TYPE_VALUES=BUILTIN_ITEM_TYPE_VALUES,STATUS_VALUES=["draft","open","in_progress","blocked","closed","canceled"],RUNTIME_STATUS_ROLE_VALUES=["draft","active","blocked","terminal","terminal_done","terminal_canceled","default_open","default_close","default_cancel"],RUNTIME_FIELD_TYPE_VALUES=["string","number","boolean","string_array","array","object"],RUNTIME_FIELD_COMMAND_VALUES=["create","update","update_many","list","search","calendar","context"],RUNTIME_UNKNOWN_FIELD_POLICY_VALUES=["allow","warn","reject"],DEPENDENCY_KIND_VALUES=["blocks","parent","child","parent_child","child_of","related","related_to","discovered_from","blocked_by","incident_from","epic","implements","recurs_from","supersedes","task","verifies"],SCOPE_VALUES=["project","global"],RISK_VALUES=["low","medium","high","critical"],ISSUE_SEVERITY_VALUES=["low","medium","high","critical"],CONFIDENCE_TEXT_VALUES=["low","medium","high"],ITEM_FORMAT_VALUES=["toon","json_markdown"],SPRINT_RELEASE_FORMAT_POLICY_VALUES=["warn","strict_error"],PARENT_REFERENCE_POLICY_VALUES=["warn","strict_error"],VALIDATE_METADATA_PROFILE_VALUES=["core","strict","custom"],GOVERNANCE_PRESET_VALUES=["minimal","default","strict","custom"],GOVERNANCE_OWNERSHIP_ENFORCEMENT_VALUES=["none","warn","strict"],GOVERNANCE_CREATE_MODE_DEFAULT_VALUES=["progressive","strict"],GOVERNANCE_CLOSE_VALIDATION_DEFAULT_VALUES=["off","warn","strict"],GOVERNANCE_WORKFLOW_ENFORCEMENT_VALUES=["off","warn","strict"],GOVERNANCE_DUPLICATE_DETECTION_MODE_VALUES=["off","advisory","strict"],VALIDATE_METADATA_REQUIRED_FIELD_VALUES=["author","acceptance_criteria","estimated_minutes","close_reason","reviewer","risk","confidence","sprint","release"],RECURRENCE_FREQUENCY_VALUES=["daily","weekly","monthly","yearly"],RECURRENCE_WEEKDAY_VALUES=["mon","tue","wed","thu","fri","sat","sun"];function weekdayOrderIndex(value){return RECURRENCE_WEEKDAY_VALUES.indexOf(value)}const PLAN_MODE_VALUES=["draft","research","review","approved","executing","paused","completed","superseded"],PLAN_STEP_STATUS_VALUES=["pending","in_progress","completed","blocked","skipped","superseded"],PLAN_HARNESS_VALUES=["codex","claude-code","cursor","generic"],PLAN_STEP_LINK_KIND_VALUES=["related","blocks","blocked_by","depends_on","discovered_from","implements","recurs_from","verifies","supersedes"],CONTEXT_DEPTH_VALUES=["brief","standard","deep","full"],CONTEXT_SECTION_VALUES=["hierarchy","activity","progress","recently_created","unparented","blockers","files","workload","staleness","tests"];export{BUILTIN_ITEM_TYPE_VALUES,CONFIDENCE_TEXT_VALUES,CONTEXT_DEPTH_VALUES,CONTEXT_SECTION_VALUES,DEPENDENCY_KIND_VALUES,GOVERNANCE_CLOSE_VALIDATION_DEFAULT_VALUES,GOVERNANCE_CREATE_MODE_DEFAULT_VALUES,GOVERNANCE_DUPLICATE_DETECTION_MODE_VALUES,GOVERNANCE_OWNERSHIP_ENFORCEMENT_VALUES,GOVERNANCE_PRESET_VALUES,GOVERNANCE_WORKFLOW_ENFORCEMENT_VALUES,ISSUE_SEVERITY_VALUES,ITEM_FORMAT_VALUES,ITEM_TYPE_VALUES,PARENT_REFERENCE_POLICY_VALUES,PLAN_HARNESS_VALUES,PLAN_MODE_VALUES,PLAN_STEP_LINK_KIND_VALUES,PLAN_STEP_STATUS_VALUES,RECURRENCE_FREQUENCY_VALUES,RECURRENCE_WEEKDAY_VALUES,RISK_VALUES,RUNTIME_FIELD_COMMAND_VALUES,RUNTIME_FIELD_TYPE_VALUES,RUNTIME_STATUS_ROLE_VALUES,RUNTIME_UNKNOWN_FIELD_POLICY_VALUES,SCOPE_VALUES,SPRINT_RELEASE_FORMAT_POLICY_VALUES,STATUS_VALUES,VALIDATE_METADATA_PROFILE_VALUES,VALIDATE_METADATA_REQUIRED_FIELD_VALUES,weekdayOrderIndex};
2
2
  //# sourceMappingURL=types.js.map
@@ -0,0 +1,79 @@
1
+ # Linked-test metadata edits and configuration refusals
2
+
3
+ Trackers: [pm-9djr6d](../.agents/pm/tasks/pm-9djr6d.toon),
4
+ [pm-gh1440](../.agents/pm/issues/pm-gh1440.toon).
5
+
6
+ Correct a linked test without removing and re-adding it:
7
+
8
+ ```bash
9
+ pm test <item-id> --list
10
+ pm test <item-id> --update-index 1 --set-json '{"note":"Verified coverage gate","timeout_seconds":900}'
11
+ pm test <item-id> --update 'command=node scripts/check.mjs' --set-json '{"note":"Updated evidence"}'
12
+ pm test <item-id> --update 'path=tests/check.mjs' --set-json '{"note":null}'
13
+ ```
14
+
15
+ Each edit patches only explicit metadata fields. The entry keeps its position,
16
+ command and original `provenance`; changed entries gain `updated_by` and
17
+ `updated_at`. An unchanged normalized retry writes no item or history bytes.
18
+ One `tests_update` history event carries field-level patches plus the edited
19
+ index and metadata field names in `context.linked_test_update`.
20
+
21
+ Use `null` to clear an optional field, such as a note, path or timeout. Scope is
22
+ required and cannot be cleared. Every entry must retain a nonblank command or path:
23
+ replace a path-only entry's path rather than clearing its last identity.
24
+ Unknown fields, command changes, provenance
25
+ changes and editor-stamp overrides are refused. To change the command, remove
26
+ and add it through the ordinary provenance-recording workflow. Editing context
27
+ or environment controls changes the clone-local trust fingerprint, so any prior
28
+ acknowledgment must be reviewed again.
29
+
30
+ Exactly one selector must match the current collection under the item lock.
31
+ Absent selectors and ambiguous command/path matches refuse the whole edit and
32
+ retain authoritative bytes; ambiguity names matching indexes. An index addresses
33
+ the current list position. Durable metadata-fragment references remain tracked
34
+ separately by [pm-gh1381](../.agents/pm/features/pm-gh1381.toon).
35
+ Apply edits separately from listing, additions, removals, execution options,
36
+ measurements, metric filters and trust acknowledgment. Run-level `--timeout`
37
+ and `--progress` are refused on edits; change stored `timeout_seconds` in the
38
+ metadata patch when needed. `--list` remains a separate read-only operation.
39
+
40
+ The public SDK owns the same operation:
41
+
42
+ ```typescript
43
+ import { updateLinkedTest } from "@unbrained/pm-cli/sdk/core";
44
+
45
+ const receipt = await updateLinkedTest(itemId, {
46
+ selector: { command: "node scripts/check.mjs" },
47
+ patch: { note: "Verified coverage gate", timeout_seconds: 900 },
48
+ }, { path: trackerRoot });
49
+ ```
50
+
51
+ The aggregate SDK exports the same function. `PmClient.run("test", ...)` and the MCP `test`
52
+ action accept `update` or `updateIndex` with `setJson`, matching CLI flags. The
53
+ receipt exposes `updated_index`, `updated_fields`, and `changed`.
54
+ For extension-owned item types, fields or mutation hooks, wrap a direct primitive
55
+ with `runWithActiveExtensions({ cwd: projectRoot }, callback)` as described in
56
+ [SDK transaction composition](SDK.md#schema-evolution-and-workspace-history).
57
+ The `PmClient` action dispatcher owns this scope automatically.
58
+
59
+ Linked-test mutations through `test`, `create`, `update` and the SDK refuse
60
+ `pm_context_mode=none` unless the stored `workspace_context_mode` is `isolated`
61
+ or `snapshot`. For example:
62
+
63
+ ```bash
64
+ pm test <item-id> --add-json '{"command":"node scripts/self-isolated-check.mjs","pm_context_mode":"none","workspace_context_mode":"isolated"}'
65
+ ```
66
+
67
+ The refusal code is `linked_test_context_invalid` and includes a concrete recovery
68
+ example. Legacy invalid records remain readable. Running such a record returns
69
+ `status: refused`, `failure_category: config_refusal`, and `exit_code: null`;
70
+ the command never runs. The item, aggregate and background run remain unsuccessful.
71
+ Actual child-process failures retain their observed exit code and ordinary
72
+ execution failure category.
73
+
74
+ SDK consumers with exhaustive `TestRunResult.status` or failure-category switches
75
+ must handle `refused` and `config_refusal`. Treat a refusal as an unsuccessful
76
+ gate, and display its recovery message; `exit_code: null` means no subprocess ran.
77
+ Context mismatches and a missing required PM assertion also use this result.
78
+ The `TestRunResult.exit_code` type now allows null, and `TestCommandOptions` and
79
+ `TestResult` include the optional editor flags and receipt fields described above.
package/docs/RELEASING.md CHANGED
@@ -148,8 +148,13 @@ configuration belong in private operator documentation.
148
148
  - protected-branch pushes require `RELEASE_PAT`; Auto Release fails fast before the expensive release gates when `push=true`, `dry_run=false`, and that secret is not configured
149
149
  - release reliability gating requires `SENTRY_PERSONAL_ADMIN_TOKEN` for issue-threshold checks; Auto Release fails before creating the version commit/tag when the token is missing and `push=true`, while sourcemap upload remains optional through `SENTRY_AUTH_TOKEN`
150
150
  - after creating and pushing a new tag, auto-release waits for the tag-push `.github/workflows/release.yml` run to finish instead of dispatching a second publish workflow
151
- - scheduled failure issues include the preflight state (`push`, `dry_run`, `release_pat_configured`, and `sentry_personal_admin_token_configured`) plus a detected cause so agents can distinguish missing release secrets from Sentry gate failures without scanning the full workflow log first
152
- - when scheduled failures continue across multiple UTC days, auto-release supersedes a stale open blocker with a fresh current-day blocker so same-day retry detection follows the latest scheduled failure
151
+ - native scheduled and declared morning-dispatcher failures open or update the
152
+ same daily blocker with trigger origin, preflight state (`push`, `dry_run`,
153
+ `release_pat_configured`, and `sentry_personal_admin_token_configured`) and
154
+ detected cause. Successful automatic recovery closes it only after exact
155
+ publication verification; operator dispatch does not manage this lifecycle.
156
+ This behavior is tracked by [pm-automatic-release-alerts](../.agents/pm/tasks/pm-automatic-release-alerts.toon).
157
+ - when either automatic origin fails across multiple UTC days, auto-release supersedes a stale open blocker with a fresh current-day blocker so same-day retry detection follows the latest automatic failure
153
158
  - closing the exact bot-created `Auto Release blocked: scheduled run failed`
154
159
  issue as a maintainer or agent records a same-day retry marker, then either
155
160
  retries preparation when no tag exists or watches an active exact-tag Release
@@ -592,12 +597,18 @@ Use the npm registry package for maintainer global updates. Do not use `npm inst
592
597
  ordinal recovery version. Rerun `.github/workflows/release.yml` with
593
598
  `workflow_dispatch` and `tag=v<version>` (or close the current bot-created
594
599
  blocker once to trigger the guarded exact-run recovery). The workflow skips
595
- duplicate npm publication for an anonymously visible version. Before
596
- installing or running gates, dispatch performs an isolated anonymous
597
- exact-version probe. An
598
- existing version keeps the reviewed dispatch-time `main` source and cannot
599
- be republished. A definitive missing-version response pins the checkout to
600
- the existing immutable tag, reapplies the version guard, installs the managed
600
+ npm publication for a version visible to its isolated anonymous probe, keeping
601
+ reviewed dispatch-time `main`. A definitive missing-version response can pin
602
+ source to the immutable tag only after admission reads complete workflow and
603
+ job inventories, validates totals and unique identities, and checks matching
604
+ attempts. Prior successful `Publish to npm` evidence refuses
605
+ publication while metadata is unavailable: acceptance can precede visibility.
606
+ Unavailable, malformed, incomplete or inconsistent evidence also refuses it.
607
+ Only the executing attempt is excluded; its earlier attempts remain checked.
608
+ This admission check also runs before first publication, using reviewed
609
+ controls retained outside recovery checkout. Push and dispatch publishers
610
+ share exact-tag concurrency. See [pm-publication-acceptance-fence](../.agents/pm/issues/pm-publication-acceptance-fence.toon).
611
+ A never-published tag then reapplies the version guard, installs the managed
601
612
  changelog extension, regenerates the package changelog with the tagged
602
613
  checkout's canonical policy under a tracked-path mutation guard, and permits
603
614
  first publication only from that tagged source. Ordinary tag-push releases