@unbrained/pm-cli 2026.8.21 → 2026.8.23

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 (228) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +44 -0
  3. package/dist/cli/error-guidance.d.ts +22 -4
  4. package/dist/cli/error-guidance.js +73 -16
  5. package/dist/cli/main.d.ts +3 -0
  6. package/dist/cli/main.js +51 -9
  7. package/dist/cli/register-mutation.js +6 -6
  8. package/dist/cli/register-operations.d.ts +73 -0
  9. package/dist/cli/register-operations.js +39 -14
  10. package/dist/cli/register-setup.js +3 -3
  11. package/dist/cli/schema-registration-helpers.d.ts +8 -1
  12. package/dist/cli/schema-registration-helpers.js +14 -5
  13. package/dist/cli-bundle/bundle-manifest.json +149 -149
  14. package/dist/cli-bundle/chunks/chunk-3ENVHX6C.js +36 -0
  15. package/dist/cli-bundle/chunks/{chunk-LOVTQ52Z.js → chunk-DW2CGEMU.js} +2 -2
  16. package/dist/cli-bundle/chunks/chunk-EG6CLDZT.js +5 -0
  17. package/dist/cli-bundle/chunks/{chunk-LARJJ3RK.js → chunk-F3AI2JFL.js} +2 -2
  18. package/dist/cli-bundle/chunks/{chunk-N3DSV4CH.js → chunk-HWZ6CELB.js} +8 -8
  19. package/dist/cli-bundle/chunks/chunk-HZBMLSZI.js +201 -0
  20. package/dist/cli-bundle/chunks/chunk-JB4KZWBF.js +3 -0
  21. package/dist/cli-bundle/chunks/chunk-KPH73XXJ.js +2 -0
  22. package/dist/cli-bundle/chunks/{chunk-BKYB45NQ.js → chunk-KXPMB2YL.js} +50 -50
  23. package/dist/cli-bundle/chunks/{chunk-BUNIEJNE.js → chunk-QDVHNHAQ.js} +2 -2
  24. package/dist/cli-bundle/chunks/chunk-TFI5V5N2.js +13 -0
  25. package/dist/cli-bundle/chunks/{register-list-query-F57EWDEF.js → register-list-query-UJB5FMV2.js} +2 -2
  26. package/dist/cli-bundle/chunks/register-mutation-NX5XE4VX.js +20 -0
  27. package/dist/cli-bundle/chunks/register-operations-RXIJIYXC.js +2 -0
  28. package/dist/cli-bundle/chunks/{register-setup-HXU7IZZD.js → register-setup-GFUZEKRE.js} +2 -2
  29. package/dist/cli-bundle/focused-chunks/{chunk-F4YEW5I2.js → chunk-37Z4OEAP.js} +2 -2
  30. package/dist/cli-bundle/focused-chunks/chunk-3UPTYG44.js +8 -0
  31. package/dist/cli-bundle/focused-chunks/chunk-5S7E72FY.js +16 -0
  32. package/dist/cli-bundle/focused-chunks/{chunk-4ERLO7QD.js → chunk-AUFH5H35.js} +2 -2
  33. package/dist/cli-bundle/focused-chunks/chunk-E7X25GC3.js +2 -0
  34. package/dist/cli-bundle/focused-chunks/chunk-FQCSTBWE.js +4 -0
  35. package/dist/cli-bundle/focused-chunks/{chunk-FH6DYED3.js → chunk-FZS4H32O.js} +2 -2
  36. package/dist/cli-bundle/focused-chunks/chunk-IFLWKY2R.js +156 -0
  37. package/dist/cli-bundle/focused-chunks/{chunk-YKBKIEAJ.js → chunk-JOWDB2MH.js} +2 -2
  38. package/dist/cli-bundle/focused-chunks/chunk-LYVSW5VM.js +2 -0
  39. package/dist/cli-bundle/focused-chunks/chunk-MRCNF3U6.js +2 -0
  40. package/dist/cli-bundle/focused-chunks/{chunk-UZE7XUZK.js → chunk-OFVUGTLJ.js} +2 -2
  41. package/dist/cli-bundle/focused-chunks/{chunk-FJ22HNRP.js → chunk-OGLQBL46.js} +2 -2
  42. package/dist/cli-bundle/focused-chunks/chunk-OY7QAV4Y.js +51 -0
  43. package/dist/cli-bundle/focused-chunks/chunk-QGFNI65N.js +26 -0
  44. package/dist/cli-bundle/focused-chunks/{chunk-KDNG7TKQ.js → chunk-R27IDGHD.js} +2 -2
  45. package/dist/cli-bundle/focused-chunks/chunk-UYRFYCDQ.js +5 -0
  46. package/dist/cli-bundle/focused-chunks/{chunk-2NIY5NKG.js → chunk-ZHVA42R5.js} +9 -9
  47. package/dist/cli-bundle/main.js +13 -13
  48. package/dist/cli-bundle/sdk-authoring.js +1 -1
  49. package/dist/cli-bundle/sdk-contracts.js +2 -2
  50. package/dist/cli-bundle/sdk-core.js +40 -40
  51. package/dist/cli-bundle/sdk-governance.js +1 -1
  52. package/dist/cli-bundle/sdk-graph.js +1 -1
  53. package/dist/cli-bundle/sdk-merge.js +33 -32
  54. package/dist/cli-bundle/sdk-query.js +1 -1
  55. package/dist/cli-bundle/sdk-runtime.js +1 -1
  56. package/dist/cli-bundle/sdk-testing.js +1 -1
  57. package/dist/cli-bundle/sdk.js +5 -5
  58. package/dist/core/config/nested-settings.js +8 -2
  59. package/dist/core/config/positional-value.d.ts +1 -1
  60. package/dist/core/config/positional-value.js +5 -2
  61. package/dist/core/extensions/extension-hook-runtime.js +22 -20
  62. package/dist/core/extensions/extension-types.d.ts +8 -1
  63. package/dist/core/extensions/extension-types.js +2 -2
  64. package/dist/core/extensions/loader.js +7 -3
  65. package/dist/core/extensions/service-ownership.d.ts +8 -0
  66. package/dist/core/extensions/service-ownership.js +20 -0
  67. package/dist/core/history/history.js +3 -3
  68. package/dist/core/item/id.js +20 -5
  69. package/dist/core/item/item-format.js +81 -2
  70. package/dist/core/reproducibility/context.d.ts +4 -0
  71. package/dist/core/reproducibility/context.js +14 -8
  72. package/dist/core/shared/author.d.ts +55 -1
  73. package/dist/core/shared/author.js +333 -16
  74. package/dist/core/shared/constants.js +3 -2
  75. package/dist/core/shared/errors.d.ts +4 -0
  76. package/dist/core/shared/errors.js +2 -2
  77. package/dist/core/store/settings-validator.d.ts +1 -0
  78. package/dist/core/store/settings-validator.js +6 -3
  79. package/dist/core/store/settings.js +5 -2
  80. package/dist/mcp/server.d.ts +1 -1
  81. package/dist/mcp/server.js +30 -9
  82. package/dist/sdk/agent/identity-config.d.ts +63 -0
  83. package/dist/sdk/agent/identity-config.js +107 -0
  84. package/dist/sdk/agent/refusal-corpus-contracts.d.ts +76 -0
  85. package/dist/sdk/agent/refusal-corpus-contracts.js +194 -0
  86. package/dist/sdk/agent/refusal-reachability.d.ts +1 -1
  87. package/dist/sdk/authoring.d.ts +1 -1
  88. package/dist/sdk/authoring.js +2 -2
  89. package/dist/sdk/cli-contracts/agent-output-contracts.d.ts +77 -0
  90. package/dist/sdk/cli-contracts/agent-output-contracts.js +326 -2
  91. package/dist/sdk/cli-contracts/commander-mutation-options.js +3 -3
  92. package/dist/sdk/cli-contracts/enum-contracts.d.ts +4 -0
  93. package/dist/sdk/cli-contracts/enum-contracts.js +9 -2
  94. package/dist/sdk/cli-contracts/flag-contracts.js +9 -2
  95. package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +4 -4
  96. package/dist/sdk/cli-contracts/registration-helpers.js +5 -2
  97. package/dist/sdk/cli-contracts/runtime-contracts.d.ts +3 -1
  98. package/dist/sdk/cli-contracts/runtime-contracts.js +4 -3
  99. package/dist/sdk/cli-contracts/tool-parameter-tables.js +22 -2
  100. package/dist/sdk/cli-contracts/tool-schema.d.ts +1 -1
  101. package/dist/sdk/cli-contracts/tool-schema.js +14 -3
  102. package/dist/sdk/cli-contracts.d.ts +4 -4
  103. package/dist/sdk/cli-contracts.js +5 -5
  104. package/dist/sdk/config.d.ts +6 -1
  105. package/dist/sdk/config.js +119 -14
  106. package/dist/sdk/context-intent-contracts.js +4 -2
  107. package/dist/sdk/core-governance.d.ts +1 -1
  108. package/dist/sdk/core-governance.js +3 -3
  109. package/dist/sdk/extension/install-sources.d.ts +1 -1
  110. package/dist/sdk/extension/install-sources.js +6 -3
  111. package/dist/sdk/extension/output-ownership.d.ts +1 -0
  112. package/dist/sdk/extension/output-ownership.js +3 -2
  113. package/dist/sdk/extension/scaffold.js +11 -5
  114. package/dist/sdk/flag-invocation-contracts.js +4 -2
  115. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +74 -2
  116. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +87 -26
  117. package/dist/sdk/governance/assurance-action.js +30 -10
  118. package/dist/sdk/governance/health.d.ts +3 -0
  119. package/dist/sdk/governance/health.js +39 -7
  120. package/dist/sdk/governance/hierarchy-validation.d.ts +29 -0
  121. package/dist/sdk/governance/hierarchy-validation.js +109 -0
  122. package/dist/sdk/governance/validate.d.ts +3 -9
  123. package/dist/sdk/governance/validate.js +84 -111
  124. package/dist/sdk/graph/assembly.d.ts +6 -1
  125. package/dist/sdk/graph/assembly.js +16 -22
  126. package/dist/sdk/graph/governance-contracts.d.ts +1 -1
  127. package/dist/sdk/graph/governance-contracts.js +8 -2
  128. package/dist/sdk/graph/governance.js +46 -2
  129. package/dist/sdk/graph/hierarchy-integrity.d.ts +94 -0
  130. package/dist/sdk/graph/hierarchy-integrity.js +311 -0
  131. package/dist/sdk/graph/index.d.ts +2 -1
  132. package/dist/sdk/graph/index.js +3 -2
  133. package/dist/sdk/graph/remediation.js +32 -2
  134. package/dist/sdk/graph/run.d.ts +31 -2
  135. package/dist/sdk/graph/run.js +80 -31
  136. package/dist/sdk/graph/workspace-relationship-kind-registry.d.ts +8 -0
  137. package/dist/sdk/graph/workspace-relationship-kind-registry.js +28 -0
  138. package/dist/sdk/index.d.ts +8 -3
  139. package/dist/sdk/index.js +9 -4
  140. package/dist/sdk/item-children.js +21 -8
  141. package/dist/sdk/lifecycle/create.js +129 -97
  142. package/dist/sdk/lifecycle/hierarchy-mutation-lock.d.ts +15 -0
  143. package/dist/sdk/lifecycle/hierarchy-mutation-lock.js +25 -0
  144. package/dist/sdk/lifecycle/update.d.ts +2 -0
  145. package/dist/sdk/lifecycle/update.js +174 -84
  146. package/dist/sdk/merge/three-way.js +105 -26
  147. package/dist/sdk/query/complete-list.d.ts +3 -3
  148. package/dist/sdk/query/complete-list.js +46 -3
  149. package/dist/sdk/query/list.d.ts +4 -3
  150. package/dist/sdk/query/list.js +89 -49
  151. package/dist/sdk/read-output-budget.d.ts +21 -0
  152. package/dist/sdk/read-output-budget.js +39 -2
  153. package/dist/sdk/read-output-contracts.d.ts +10 -4
  154. package/dist/sdk/read-output-contracts.js +105 -32
  155. package/dist/sdk/relationship-context.js +3 -4
  156. package/dist/sdk/relationships.js +17 -10
  157. package/dist/sdk/reproducibility/process.d.ts +19 -0
  158. package/dist/sdk/reproducibility/process.js +88 -0
  159. package/dist/sdk/runtime-primitives.d.ts +1 -1
  160. package/dist/sdk/runtime-primitives.js +3 -3
  161. package/dist/sdk/runtime.d.ts +3 -2
  162. package/dist/sdk/runtime.js +7 -5
  163. package/dist/sdk/test/batch.d.ts +6 -0
  164. package/dist/sdk/test/batch.js +26 -6
  165. package/dist/sdk/test/entry.d.ts +1 -1
  166. package/dist/sdk/test/entry.js +3 -2
  167. package/dist/sdk/test/execution.d.ts +28 -3
  168. package/dist/sdk/test/execution.js +201 -34
  169. package/dist/sdk/test/parsers.d.ts +6 -0
  170. package/dist/sdk/test/parsers.js +21 -2
  171. package/dist/sdk/test/trust.d.ts +33 -0
  172. package/dist/sdk/test/trust.js +207 -0
  173. package/dist/types.d.ts +34 -0
  174. package/dist/types.js +2 -2
  175. package/docs/AGENT_PROVENANCE_ADR.md +41 -5
  176. package/docs/AGENT_UX_CONTRACTS.md +20 -4
  177. package/docs/COMMANDS.md +29 -14
  178. package/docs/CONFIGURATION.md +4 -0
  179. package/docs/DEPENDENCY_KIND_CONTRACT.md +31 -3
  180. package/docs/DIAGNOSTIC_OUTPUT_CONTRACTS.md +115 -0
  181. package/docs/EXTENSIONS.md +2 -1
  182. package/docs/MERGE_SAFETY.md +15 -1
  183. package/docs/README.md +1 -0
  184. package/docs/READ_OUTPUT_CONTRACTS.md +19 -2
  185. package/docs/RELATIONSHIP_GRAPH.md +6 -3
  186. package/docs/REPRODUCIBLE_WORKSPACES.md +42 -8
  187. package/docs/SDK.md +9 -0
  188. package/docs/SDK_AGENT_SESSION_CONTEXT.md +6 -4
  189. package/docs/SDK_EVIDENCE_TRACEABILITY.md +1 -1
  190. package/docs/TESTING.md +83 -1
  191. package/docs/agent-task-token-baseline.json +2 -2
  192. package/docs/generated/FLAG_LEXICON_BUDGETS.md +2 -2
  193. package/marketplace.json +2 -2
  194. package/package.json +2 -2
  195. package/packages/pm-beads/package.json +1 -1
  196. package/packages/pm-calendar/package.json +1 -1
  197. package/packages/pm-command-kit/package.json +1 -1
  198. package/packages/pm-digital-twin/package.json +1 -1
  199. package/packages/pm-governance-audit/package.json +1 -1
  200. package/packages/pm-guide-shell/package.json +1 -1
  201. package/packages/pm-kanban/package.json +1 -1
  202. package/packages/pm-lifecycle-hooks/package.json +1 -1
  203. package/packages/pm-linked-test-adapters/package.json +1 -1
  204. package/packages/pm-search-advanced/package.json +1 -1
  205. package/packages/pm-templates/package.json +1 -1
  206. package/packages/pm-todos/package.json +1 -1
  207. package/packages/pm-vcs/package.json +1 -1
  208. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  209. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  210. package/sdk/public-surface.json +1021 -53
  211. package/dist/cli-bundle/chunks/chunk-2MA6ZQVZ.js +0 -197
  212. package/dist/cli-bundle/chunks/chunk-3AFAUHUE.js +0 -2
  213. package/dist/cli-bundle/chunks/chunk-7VHZS727.js +0 -5
  214. package/dist/cli-bundle/chunks/chunk-JSLOFXGA.js +0 -3
  215. package/dist/cli-bundle/chunks/chunk-OCLPLFAY.js +0 -35
  216. package/dist/cli-bundle/chunks/chunk-S4IRYKBU.js +0 -13
  217. package/dist/cli-bundle/chunks/register-mutation-7IY2D5KO.js +0 -20
  218. package/dist/cli-bundle/chunks/register-operations-FALL3YTU.js +0 -2
  219. package/dist/cli-bundle/focused-chunks/chunk-7WZRLCYF.js +0 -50
  220. package/dist/cli-bundle/focused-chunks/chunk-CKKQSJNN.js +0 -2
  221. package/dist/cli-bundle/focused-chunks/chunk-EEFKYMDR.js +0 -16
  222. package/dist/cli-bundle/focused-chunks/chunk-F2A56DHV.js +0 -8
  223. package/dist/cli-bundle/focused-chunks/chunk-FV5ACOK7.js +0 -2
  224. package/dist/cli-bundle/focused-chunks/chunk-JEAVFOWM.js +0 -2
  225. package/dist/cli-bundle/focused-chunks/chunk-NJ63LOP6.js +0 -155
  226. package/dist/cli-bundle/focused-chunks/chunk-NXRTQ7HI.js +0 -2
  227. package/dist/cli-bundle/focused-chunks/chunk-TJ7EMJ46.js +0 -4
  228. package/dist/cli-bundle/focused-chunks/chunk-ZOSEELYJ.js +0 -26
@@ -4,18 +4,22 @@
4
4
  * Implements the pm create command surface and its agent-facing runtime behavior.
5
5
  */
6
6
 
7
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a10348fe-746d-5dc7-8cd4-30453c602a3f")}catch(e){}}();
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="f8c8e154-737b-58db-9a8b-7f4399342e83")}catch(e){}}();
8
8
  import { assertInitializedTracker } from "../environment/tracker-preflight.js";
9
- import { removeFileIfExists, writeFileAtomic, appendHistoryEntry, createHistoryEntry, generateItemId, normalizeItemId, canonicalDocument, normalizeItemMetadata, serializeItemDocument, assertParentReferenceIsNotSelf, isPlaceholderReferenceToken, normalizeParentReferenceValue, validateMissingParentReference, validateSprintOrReleaseValue, assertNoUnknownCsvKeys, createStdinTokenResolver, looksLikeGenericKeyValueEntry, mergeAdditiveTags, parseCsvKv, parseOptionalNonNegativeInteger, parseOptionalNumber, parseTags, resolvePriority, getFocusedItem, normalizeStatusInput, canonicalizeCommandOptionKey, commandOptionFlagLabel, resolveItemTypeRegistry, resolveCommandOptionPolicyState, resolveTypeDefinition, resolveTypeName, validateTypeOptions, acquireLock, printError, buildInvalidTypeError, resolveTypeSynonym, collectRuntimeCreateFieldValues, resolveItemTypesFilePath, resolveRuntimeFieldRegistry, resolveRuntimeStatusRegistry, EXIT_CODE, ITEM_METADATA_KEY_ORDER, PmCliError, nowIso, resolveIsoOrRelative, getActiveExtensionRegistrations, projectAfterCommandItemSnapshot, recordAfterCommandAffectedItem, runActiveCommandHandler, runActiveBeforeMutationHooks, runActiveOnWriteHooks, collectRegisteredItemFieldNames, applyRegisteredItemFieldDefaultsAndValidation, parseRegisteredItemFieldAssignments, listAllItemMetadataLight, locateItem, createMutationGuardSdk, getHistoryPath, getItemPath, resolvePmRoot, readSettings, resolveAuthor, } from "../runtime-primitives.js";
9
+ import { removeFileIfExists, writeFileAtomic, appendHistoryEntry, createHistoryEntry, generateItemId, normalizeItemId, canonicalDocument, normalizeItemMetadata, serializeItemDocument, assertParentReferenceIsNotSelf, isPlaceholderReferenceToken, normalizeParentReferenceValue, validateMissingParentReference, validateSprintOrReleaseValue, assertNoUnknownCsvKeys, createStdinTokenResolver, looksLikeGenericKeyValueEntry, mergeAdditiveTags, parseCsvKv, parseOptionalNonNegativeInteger, parseOptionalNumber, parseTags, resolvePriority, getFocusedItem, normalizeStatusInput, isTerminalStatus, canonicalizeCommandOptionKey, commandOptionFlagLabel, resolveItemTypeRegistry, resolveCommandOptionPolicyState, resolveTypeDefinition, resolveTypeName, validateTypeOptions, acquireLock, printError, buildInvalidTypeError, resolveTypeSynonym, collectRuntimeCreateFieldValues, resolveItemTypesFilePath, resolveRuntimeFieldRegistry, resolveRuntimeStatusRegistry, EXIT_CODE, ITEM_METADATA_KEY_ORDER, PmCliError, nowIso, resolveIsoOrRelative, getActiveExtensionRegistrations, projectAfterCommandItemSnapshot, recordAfterCommandAffectedItem, runActiveCommandHandler, runActiveBeforeMutationHooks, runActiveOnWriteHooks, collectRegisteredItemFieldNames, applyRegisteredItemFieldDefaultsAndValidation, parseRegisteredItemFieldAssignments, listAllItemMetadataLight, locateItem, createMutationGuardSdk, getHistoryPath, getItemPath, resolvePmRoot, readSettings, resolveAuthor, } from "../runtime-primitives.js";
10
10
  import { requireTerminalReasonWithRecovery } from "../lifecycle-policy.js";
11
11
  import { evaluateSimilarityGovernance, similarityAdvisoryWarnings, } from "../similarity.js";
12
12
  import { acquireItemMetadataDerivedIndexLock, refreshItemMetadataDerivedIndex, } from "../item-metadata-index.js";
13
13
  import { collectNewOrderingCycleWarnings } from "../graph/mutation-advisory.js";
14
+ import { assertHierarchyMutationAllowed } from "../graph/hierarchy-integrity.js";
15
+ import { resolveWorkspaceRelationshipKindRegistry } from "../graph/assembly.js";
16
+ import { acquireHierarchyMutationLock } from "./hierarchy-mutation-lock.js";
14
17
  import { normalizeRiskInput, normalizeSeverityInput, parseConfidenceInput, parseRegressionInput, } from "./metadata-normalizers.js";
15
18
  import { applyLegacyNoneCollectionNormalizers, createLegacyNoneCollectionNormalizers, assertNoLegacyNoneToken, assertNoLegacyNoneTokens, isLegacyNoneToken, } from "./legacy-none-tokens.js";
16
19
  import { suggestNextLifecycleTransition, } from "./lifecycle-transitions.js";
17
- import { parseLinkedTestAssertionEqualsMap, parseLinkedTestAssertionGteMap, parseLinkedTestBoolean, parseLinkedTestContextMode, parseLinkedTestEnvClear, parseLinkedTestEnvSet, parseLinkedTestMinLines, parseLinkedTestRegexList, parseLinkedTestStringList, } from "../test/parsers.js";
20
+ import { parseLinkedTestAssertionEqualsMap, parseLinkedTestAssertionGteMap, parseLinkedTestBoolean, parseLinkedTestContextMode, parseLinkedTestEnvClear, parseLinkedTestEnvSet, parseLinkedTestMinLines, parseLinkedTestRegexList, parseLinkedTestStringList, parseLinkedTestWorkspaceContextMode, } from "../test/parsers.js";
18
21
  import { looksLikeStructuredLinkedTestEntry, normalizeStructuredLinkedTestEntry, } from "../test/entry.js";
22
+ import { attachLinkedTestMutationProvenance } from "../test/trust.js";
19
23
  import { COMMON_UNSET_FIELD_DEFINITIONS_AFTER_AUTHOR, COMMON_UNSET_FIELD_DEFINITIONS_BEFORE_AUTHOR, parseCommandUnsetTargets, resolveRuntimeUnsetFieldDefinition, } from "./shared-unset-fields.js";
20
24
  import { ensureEnumValue } from "./recurrence-parsers.js";
21
25
  import { assertDependencyEdgesAllowed, assertDependencyTargetsResolvable, assertValidBareDependencyFlagValue, } from "../dependency-flag-validation.js";
@@ -324,6 +328,7 @@ export function parseTests(raw) {
324
328
  ? parseOptionalNumber(timeoutRaw, "timeout_seconds")
325
329
  : undefined,
326
330
  pm_context_mode: parseLinkedTestContextMode(kv.pm_context_mode, "--test"),
331
+ workspace_context_mode: parseLinkedTestWorkspaceContextMode(kv.workspace_context_mode, "--test"),
327
332
  env_set: parseLinkedTestEnvSet(kv.env_set, "--test"),
328
333
  env_clear: parseLinkedTestEnvClear(kv.env_clear, "--test"),
329
334
  shared_host_safe: parseLinkedTestBoolean(kv.shared_host_safe, "--test", "shared_host_safe"),
@@ -1440,114 +1445,140 @@ async function writeCreatedItem(params) {
1440
1445
  const { pmRoot, type, id, settings, typeRegistry, author, extensionFieldNames, afterDocument, beforeDocument, historyMessage, changedFields, nowValue, similarityCandidate, allowDuplicate, } = params;
1441
1446
  const itemPath = getItemPath(pmRoot, type, id, settings.item_format, typeRegistry.type_to_folder);
1442
1447
  const historyPath = getHistoryPath(pmRoot, id);
1443
- const lockRelease = await acquireLock(pmRoot, id, settings.locks.ttl_seconds, author, false, settings.governance.force_required_for_stale_lock, settings.locks.wait_ms);
1448
+ const relationshipRegistry = resolveWorkspaceRelationshipKindRegistry();
1449
+ const hierarchyMutationRequired = afterDocument.metadata.parent !== undefined ||
1450
+ (afterDocument.metadata.dependencies ?? []).some((dependency) => relationshipRegistry.resolve(dependency.kind)?.hierarchy);
1451
+ const hierarchyLockRelease = await acquireHierarchyMutationLock({
1452
+ pmRoot,
1453
+ author,
1454
+ ttlSeconds: settings.locks.ttl_seconds,
1455
+ waitMs: settings.locks.wait_ms,
1456
+ required: hierarchyMutationRequired,
1457
+ });
1458
+ let hierarchyLockHeld = hierarchyMutationRequired;
1444
1459
  let hookWarnings = [];
1445
1460
  try {
1446
- const graphBeforeCreate = afterDocument.metadata.dependencies &&
1447
- afterDocument.metadata.dependencies.length > 0
1448
- ? await listAllItemMetadataLight(pmRoot, settings.item_format, typeRegistry.type_to_folder, undefined, settings.schema)
1449
- : undefined;
1450
- const existing = await locateItem(pmRoot, id, settings.id_prefix, settings.item_format, typeRegistry.type_to_folder);
1451
- if (existing) {
1452
- throw new PmCliError(`Item "${id}" already exists`, EXIT_CODE.CONFLICT);
1453
- }
1454
- await runActiveBeforeMutationHooks({
1455
- pm_root: pmRoot,
1456
- operation: "create",
1457
- before: null,
1458
- after: afterDocument,
1459
- changed_fields: changedFields,
1460
- sdk: createMutationGuardSdk({
1461
- pmRoot,
1462
- settings,
1463
- typeToFolder: typeRegistry.type_to_folder,
1464
- }),
1465
- });
1466
- const releaseDerivedIndexLock = await acquireItemMetadataDerivedIndexLock(pmRoot, author, {
1467
- required: settings.governance.duplicate_detection_mode === "strict" &&
1468
- allowDuplicate !== true,
1469
- });
1470
- let derivedIndexWarnings = [];
1461
+ const lockRelease = await acquireLock(pmRoot, id, settings.locks.ttl_seconds, author, false, settings.governance.force_required_for_stale_lock, settings.locks.wait_ms);
1471
1462
  try {
1472
- if (settings.governance.duplicate_detection_mode === "strict" &&
1473
- allowDuplicate !== true) {
1474
- await evaluateSimilarityGovernance(similarityCandidate, {
1463
+ const graphBeforeCreate = afterDocument.metadata.parent !== undefined ||
1464
+ (afterDocument.metadata.dependencies !== undefined &&
1465
+ afterDocument.metadata.dependencies.length > 0)
1466
+ ? await listAllItemMetadataLight(pmRoot, settings.item_format, typeRegistry.type_to_folder, undefined, settings.schema)
1467
+ : undefined;
1468
+ const existing = await locateItem(pmRoot, id, settings.id_prefix, settings.item_format, typeRegistry.type_to_folder);
1469
+ if (existing) {
1470
+ throw new PmCliError(`Item "${id}" already exists`, EXIT_CODE.CONFLICT);
1471
+ }
1472
+ if (graphBeforeCreate) {
1473
+ const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);
1474
+ assertHierarchyMutationAllowed(graphBeforeCreate, [...graphBeforeCreate, afterDocument.metadata], id, (status) => isTerminalStatus(status, statusRegistry), relationshipRegistry);
1475
+ }
1476
+ await runActiveBeforeMutationHooks({
1477
+ pm_root: pmRoot,
1478
+ operation: "create",
1479
+ before: null,
1480
+ after: afterDocument,
1481
+ changed_fields: changedFields,
1482
+ sdk: createMutationGuardSdk({
1475
1483
  pmRoot,
1476
- mode: "strict",
1477
- threshold: settings.governance.duplicate_detection_threshold,
1478
- limit: settings.governance.duplicate_detection_limit,
1479
- allowDuplicate: false,
1484
+ settings,
1485
+ typeToFolder: typeRegistry.type_to_folder,
1486
+ }),
1487
+ });
1488
+ const releaseDerivedIndexLock = await acquireItemMetadataDerivedIndexLock(pmRoot, author, {
1489
+ required: settings.governance.duplicate_detection_mode === "strict" &&
1490
+ allowDuplicate !== true,
1491
+ });
1492
+ let derivedIndexWarnings = [];
1493
+ try {
1494
+ if (settings.governance.duplicate_detection_mode === "strict" &&
1495
+ allowDuplicate !== true) {
1496
+ await evaluateSimilarityGovernance(similarityCandidate, {
1497
+ pmRoot,
1498
+ mode: "strict",
1499
+ threshold: settings.governance.duplicate_detection_threshold,
1500
+ limit: settings.governance.duplicate_detection_limit,
1501
+ allowDuplicate: false,
1502
+ });
1503
+ }
1504
+ await writeFileAtomic(itemPath, serializeItemDocument(afterDocument, {
1505
+ format: settings.item_format,
1506
+ schema: settings.schema,
1507
+ extensionFieldNames,
1508
+ }));
1509
+ try {
1510
+ const entry = createHistoryEntry({
1511
+ nowIso: nowValue,
1512
+ author,
1513
+ op: "create",
1514
+ before: beforeDocument,
1515
+ after: afterDocument,
1516
+ message: historyMessage,
1517
+ });
1518
+ await appendHistoryEntry(historyPath, entry);
1519
+ }
1520
+ catch (error) {
1521
+ await removeFileIfExists(itemPath);
1522
+ throw error;
1523
+ }
1524
+ if (hierarchyLockHeld) {
1525
+ await hierarchyLockRelease();
1526
+ hierarchyLockHeld = false;
1527
+ }
1528
+ derivedIndexWarnings = await refreshItemMetadataDerivedIndex({
1529
+ pmRoot,
1530
+ preferredFormat: settings.item_format,
1531
+ typeToFolder: typeRegistry.type_to_folder,
1532
+ schema: settings.schema,
1533
+ itemPath,
1534
+ document: afterDocument,
1480
1535
  });
1481
1536
  }
1482
- await writeFileAtomic(itemPath, serializeItemDocument(afterDocument, {
1483
- format: settings.item_format,
1484
- schema: settings.schema,
1485
- extensionFieldNames,
1486
- }));
1487
- try {
1488
- const entry = createHistoryEntry({
1489
- nowIso: nowValue,
1490
- author,
1537
+ finally {
1538
+ await releaseDerivedIndexLock();
1539
+ }
1540
+ hookWarnings = [
1541
+ ...(graphBeforeCreate
1542
+ ? collectNewOrderingCycleWarnings(graphBeforeCreate, [...graphBeforeCreate, afterDocument.metadata], id)
1543
+ : []),
1544
+ ...derivedIndexWarnings,
1545
+ ...(await runActiveOnWriteHooks({
1546
+ path: itemPath,
1547
+ scope: "project",
1491
1548
  op: "create",
1549
+ item_id: afterDocument.metadata.id,
1550
+ item_type: afterDocument.metadata.type,
1492
1551
  before: beforeDocument,
1493
1552
  after: afterDocument,
1494
- message: historyMessage,
1495
- });
1496
- await appendHistoryEntry(historyPath, entry);
1497
- }
1498
- catch (error) {
1499
- await removeFileIfExists(itemPath);
1500
- throw error;
1501
- }
1502
- derivedIndexWarnings = await refreshItemMetadataDerivedIndex({
1503
- pmRoot,
1504
- preferredFormat: settings.item_format,
1505
- typeToFolder: typeRegistry.type_to_folder,
1506
- schema: settings.schema,
1507
- itemPath,
1508
- document: afterDocument,
1553
+ changed_fields: changedFields,
1554
+ })),
1555
+ ...(await runActiveOnWriteHooks({
1556
+ path: historyPath,
1557
+ scope: "project",
1558
+ op: "create:history",
1559
+ item_id: afterDocument.metadata.id,
1560
+ item_type: afterDocument.metadata.type,
1561
+ before: beforeDocument,
1562
+ after: afterDocument,
1563
+ changed_fields: changedFields,
1564
+ })),
1565
+ ];
1566
+ recordAfterCommandAffectedItem({
1567
+ id: afterDocument.metadata.id,
1568
+ op: "create",
1569
+ item_type: afterDocument.metadata.type,
1570
+ status: afterDocument.metadata.status,
1571
+ current: projectAfterCommandItemSnapshot(afterDocument.metadata, changedFields),
1572
+ changed_fields: changedFields,
1509
1573
  });
1510
1574
  }
1511
1575
  finally {
1512
- await releaseDerivedIndexLock();
1576
+ await lockRelease();
1513
1577
  }
1514
- hookWarnings = [
1515
- ...(graphBeforeCreate
1516
- ? collectNewOrderingCycleWarnings(graphBeforeCreate, [...graphBeforeCreate, afterDocument.metadata], id)
1517
- : []),
1518
- ...derivedIndexWarnings,
1519
- ...(await runActiveOnWriteHooks({
1520
- path: itemPath,
1521
- scope: "project",
1522
- op: "create",
1523
- item_id: afterDocument.metadata.id,
1524
- item_type: afterDocument.metadata.type,
1525
- before: beforeDocument,
1526
- after: afterDocument,
1527
- changed_fields: changedFields,
1528
- })),
1529
- ...(await runActiveOnWriteHooks({
1530
- path: historyPath,
1531
- scope: "project",
1532
- op: "create:history",
1533
- item_id: afterDocument.metadata.id,
1534
- item_type: afterDocument.metadata.type,
1535
- before: beforeDocument,
1536
- after: afterDocument,
1537
- changed_fields: changedFields,
1538
- })),
1539
- ];
1540
- recordAfterCommandAffectedItem({
1541
- id: afterDocument.metadata.id,
1542
- op: "create",
1543
- item_type: afterDocument.metadata.type,
1544
- status: afterDocument.metadata.status,
1545
- current: projectAfterCommandItemSnapshot(afterDocument.metadata, changedFields),
1546
- changed_fields: changedFields,
1547
- });
1548
1578
  }
1549
1579
  finally {
1550
- await lockRelease();
1580
+ if (hierarchyLockHeld)
1581
+ await hierarchyLockRelease();
1551
1582
  }
1552
1583
  return hookWarnings;
1553
1584
  }
@@ -1576,6 +1607,7 @@ export async function runCreate(options, global) {
1576
1607
  const learnings = parseLogSeed("--learning", resolvedOptions.learning, nowValue, author);
1577
1608
  const files = parseFiles(resolvedOptions.file);
1578
1609
  const tests = parseTests(resolvedOptions.test);
1610
+ tests.values = await attachLinkedTestMutationProvenance(tests.values, author, nowValue);
1579
1611
  const docs = parseDocs(resolvedOptions.doc);
1580
1612
  const reminders = parseReminders(resolvedOptions.reminder, nowValue);
1581
1613
  const events = parseEvents(resolvedOptions.event, nowValue);
@@ -1886,4 +1918,4 @@ export const _testOnlyCreateCommand = {
1886
1918
  typeOptionExampleValue,
1887
1919
  };
1888
1920
  //# sourceMappingURL=create.js.map
1889
- //# debugId=a10348fe-746d-5dc7-8cd4-30453c602a3f
1921
+ //# debugId=f8c8e154-737b-58db-9a8b-7f4399342e83
@@ -0,0 +1,15 @@
1
+ /** Inputs for the internal workspace-wide hierarchy mutation lock. */
2
+ export interface HierarchyMutationLockOptions {
3
+ /** Tracker root whose hierarchy is being changed. */
4
+ pmRoot: string;
5
+ /** Principal recorded as the lock owner. */
6
+ author: string;
7
+ /** Tracker-configured stale-lock lifetime. */
8
+ ttlSeconds: number;
9
+ /** Tracker-configured bounded lock wait. */
10
+ waitMs: number;
11
+ /** Whether this mutation can add hierarchy evidence. */
12
+ required: boolean;
13
+ }
14
+ /** Acquire the shared hierarchy writer lock, or return a no-op release. */
15
+ export declare function acquireHierarchyMutationLock(options: HierarchyMutationLockOptions): Promise<() => Promise<void>>;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @module sdk/lifecycle/hierarchy-mutation-lock
3
+ *
4
+ * Serializes hierarchy-affecting create and update transactions so each
5
+ * before/after integrity decision is made from a fresh workspace snapshot.
6
+ */
7
+
8
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="39a36d42-29b1-5f0f-a8b2-f3bfc0ef78c2")}catch(e){}}();
9
+ import { acquireLock } from "../../core/lock/lock.js";
10
+ const HIERARCHY_MUTATION_LOCK_ID = "hierarchy-integrity";
11
+ /** Acquire the shared hierarchy writer lock, or return a no-op release. */
12
+ export async function acquireHierarchyMutationLock(options) {
13
+ const release = options.required
14
+ ? await acquireLock(options.pmRoot, HIERARCHY_MUTATION_LOCK_ID, options.ttlSeconds, options.author, false, false, options.waitMs)
15
+ : async () => { };
16
+ let released = false;
17
+ return async () => {
18
+ if (released)
19
+ return;
20
+ released = true;
21
+ await release();
22
+ };
23
+ }
24
+ //# sourceMappingURL=hierarchy-mutation-lock.js.map
25
+ //# debugId=39a36d42-29b1-5f0f-a8b2-f3bfc0ef78c2
@@ -121,6 +121,8 @@ interface DependencyRemovalSelector {
121
121
  id: string;
122
122
  kind?: (typeof DEPENDENCY_KIND_VALUES)[number];
123
123
  source_kind?: string;
124
+ author?: string;
125
+ created_at?: string;
124
126
  }
125
127
  /** Parse dependency additions into their canonical storage representation. */
126
128
  export declare function parseDependencyAdditions(raw: string[] | undefined, prefix: string, nowIso: string, fallbackAuthor: string): ParsedDependencyUpdates;