@unbrained/pm-cli 2026.8.10 → 2026.8.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 (243) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +153 -100
  3. package/dist/cli/commander-usage.js +113 -15
  4. package/dist/cli/error-guidance.d.ts +12 -0
  5. package/dist/cli/error-guidance.js +147 -29
  6. package/dist/cli/main.js +38 -19
  7. package/dist/cli/register-annotations.js +56 -3
  8. package/dist/cli/register-assurance.d.ts +8 -0
  9. package/dist/cli/register-assurance.js +52 -0
  10. package/dist/cli/register-files-lookup.js +14 -3
  11. package/dist/cli/register-list-query.js +10 -7
  12. package/dist/cli/register-mutation.js +30 -9
  13. package/dist/cli/register-operations.js +30 -15
  14. package/dist/cli-bundle/bundle-manifest.json +155 -155
  15. package/dist/cli-bundle/chunks/{chunk-TRWXF476.js → chunk-3PS7X6GS.js} +2 -2
  16. package/dist/cli-bundle/chunks/chunk-7KL6KMWF.js +13 -0
  17. package/dist/cli-bundle/chunks/{chunk-EBO7OUUE.js → chunk-BM5YJ2UW.js} +69 -55
  18. package/dist/cli-bundle/chunks/chunk-D55A5AEN.js +33 -0
  19. package/dist/cli-bundle/chunks/chunk-KIKDWECH.js +196 -0
  20. package/dist/cli-bundle/chunks/{chunk-ETML5C6H.js → chunk-KOQMGCTA.js} +47 -47
  21. package/dist/cli-bundle/chunks/chunk-R76342NV.js +2 -0
  22. package/dist/cli-bundle/chunks/chunk-RBTK5EZV.js +5 -0
  23. package/dist/cli-bundle/chunks/chunk-VLUQOIDT.js +2 -0
  24. package/dist/cli-bundle/chunks/chunk-WLAHPSOX.js +3 -0
  25. package/dist/cli-bundle/chunks/register-list-query-XPCJRUUD.js +10 -0
  26. package/dist/cli-bundle/chunks/register-mutation-4RJCBKRS.js +20 -0
  27. package/dist/cli-bundle/chunks/register-operations-2OGISOVR.js +2 -0
  28. package/dist/cli-bundle/chunks/{register-setup-S3KT2LTH.js → register-setup-LLHAKP2V.js} +2 -2
  29. package/dist/cli-bundle/focused-chunks/chunk-2DALMVF7.js +5 -0
  30. package/dist/cli-bundle/focused-chunks/chunk-5OQIMELN.js +155 -0
  31. package/dist/cli-bundle/focused-chunks/chunk-5TAGTDRE.js +2 -0
  32. package/dist/cli-bundle/focused-chunks/chunk-ECADZMVC.js +18 -0
  33. package/dist/cli-bundle/focused-chunks/chunk-EJGXRA6B.js +2 -0
  34. package/dist/cli-bundle/focused-chunks/chunk-FFGSZCPK.js +16 -0
  35. package/dist/cli-bundle/focused-chunks/{chunk-IW43E4XL.js → chunk-GQW4BPUT.js} +2 -2
  36. package/dist/cli-bundle/focused-chunks/chunk-ISKOBJCM.js +2 -0
  37. package/dist/cli-bundle/focused-chunks/{chunk-75774JWP.js → chunk-JAFRIWVF.js} +2 -2
  38. package/dist/cli-bundle/focused-chunks/{chunk-2COZ67XT.js → chunk-KHM2CS2C.js} +2 -2
  39. package/dist/cli-bundle/focused-chunks/{chunk-M6RPIXKC.js → chunk-KPSXVBDV.js} +2 -2
  40. package/dist/cli-bundle/focused-chunks/{chunk-34SX654S.js → chunk-KTLOKKCQ.js} +2 -2
  41. package/dist/cli-bundle/focused-chunks/chunk-LGYK3NUF.js +8 -0
  42. package/dist/cli-bundle/focused-chunks/{chunk-2EXI2DKR.js → chunk-NBLUKITQ.js} +2 -2
  43. package/dist/cli-bundle/focused-chunks/chunk-NYLOUPOB.js +2 -0
  44. package/dist/cli-bundle/focused-chunks/chunk-Q4T463SD.js +31 -0
  45. package/dist/cli-bundle/focused-chunks/chunk-QVZVY53N.js +2 -0
  46. package/dist/cli-bundle/focused-chunks/{chunk-DZGAHZZV.js → chunk-RWPAWUOT.js} +2 -2
  47. package/dist/cli-bundle/focused-chunks/chunk-UTEWXDEQ.js +17 -0
  48. package/dist/cli-bundle/focused-chunks/{chunk-7UN6BHHO.js → chunk-YIAXMC3T.js} +2 -2
  49. package/dist/cli-bundle/focused-chunks/chunk-ZMGWAYH7.js +2 -0
  50. package/dist/cli-bundle/main.js +13 -13
  51. package/dist/cli-bundle/sdk-authoring.js +1 -1
  52. package/dist/cli-bundle/sdk-contracts.js +1 -1
  53. package/dist/cli-bundle/sdk-core.js +41 -39
  54. package/dist/cli-bundle/sdk-governance.js +1 -1
  55. package/dist/cli-bundle/sdk-graph.js +1 -1
  56. package/dist/cli-bundle/sdk-merge.js +1 -1
  57. package/dist/cli-bundle/sdk-query.js +1 -1
  58. package/dist/cli-bundle/sdk-runtime.js +1 -1
  59. package/dist/cli-bundle/sdk-testing.js +1 -1
  60. package/dist/cli-bundle/sdk.js +2 -2
  61. package/dist/core/extensions/reserved-host-flags.js +3 -2
  62. package/dist/core/history/drift-scan.js +13 -8
  63. package/dist/core/history/history.d.ts +8 -0
  64. package/dist/core/history/history.js +57 -7
  65. package/dist/core/history/replay.d.ts +9 -1
  66. package/dist/core/history/replay.js +48 -13
  67. package/dist/core/output/output.d.ts +2 -0
  68. package/dist/core/output/output.js +46 -14
  69. package/dist/core/session/session-state.d.ts +47 -0
  70. package/dist/core/session/session-state.js +207 -6
  71. package/dist/core/shared/author.d.ts +7 -1
  72. package/dist/core/shared/author.js +66 -46
  73. package/dist/core/shared/command-types.d.ts +2 -0
  74. package/dist/core/shared/command-types.js +2 -2
  75. package/dist/core/shared/errors.d.ts +13 -0
  76. package/dist/core/shared/errors.js +2 -2
  77. package/dist/core/store/item-metadata-cache.d.ts +1 -1
  78. package/dist/core/store/item-metadata-cache.js +14 -7
  79. package/dist/sdk/agent/refusal-reachability.d.ts +40 -0
  80. package/dist/sdk/agent/refusal-reachability.js +72 -0
  81. package/dist/sdk/agent/subcommand-recovery.d.ts +40 -0
  82. package/dist/sdk/agent/subcommand-recovery.js +84 -0
  83. package/dist/sdk/cli-bootstrap.d.ts +10 -0
  84. package/dist/sdk/cli-bootstrap.js +11 -7
  85. package/dist/sdk/cli-contracts/completeness.js +14 -3
  86. package/dist/sdk/cli-contracts/enum-contracts.d.ts +1 -1
  87. package/dist/sdk/cli-contracts/enum-contracts.js +3 -2
  88. package/dist/sdk/cli-contracts/flag-contracts.d.ts +2 -0
  89. package/dist/sdk/cli-contracts/flag-contracts.js +20 -2
  90. package/dist/sdk/cli-contracts/registration-helpers.d.ts +20 -3
  91. package/dist/sdk/cli-contracts/registration-helpers.js +18 -12
  92. package/dist/sdk/cli-contracts/runtime-contracts.js +4 -3
  93. package/dist/sdk/cli-contracts/schemas/assurance-definition.d.ts +515 -0
  94. package/dist/sdk/cli-contracts/schemas/assurance-definition.js +252 -0
  95. package/dist/sdk/cli-contracts/tool-option-contracts.js +3 -2
  96. package/dist/sdk/cli-contracts/tool-parameter-tables.js +99 -2
  97. package/dist/sdk/cli-contracts/tool-schema.d.ts +3 -3
  98. package/dist/sdk/cli-contracts/tool-schema.js +38 -5
  99. package/dist/sdk/cli-contracts.d.ts +1 -1
  100. package/dist/sdk/cli-contracts.js +3 -3
  101. package/dist/sdk/cli-program.js +3 -2
  102. package/dist/sdk/completion.js +23 -8
  103. package/dist/sdk/config.js +9 -3
  104. package/dist/sdk/context/semantic-session-attribution.d.ts +32 -0
  105. package/dist/sdk/context/semantic-session-attribution.js +83 -0
  106. package/dist/sdk/context-intent-contracts.js +45 -4
  107. package/dist/sdk/core-governance.d.ts +3 -1
  108. package/dist/sdk/core-governance.js +5 -3
  109. package/dist/sdk/core.d.ts +2 -1
  110. package/dist/sdk/core.js +3 -2
  111. package/dist/sdk/error-code-catalog.d.ts +13 -0
  112. package/dist/sdk/error-code-catalog.js +35 -2
  113. package/dist/sdk/extension.js +18 -17
  114. package/dist/sdk/files.d.ts +11 -0
  115. package/dist/sdk/files.js +82 -24
  116. package/dist/sdk/generated/generated-error-code-catalog-part-1.d.ts +8 -0
  117. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1585 -0
  118. package/dist/sdk/generated/generated-error-code-catalog-part-2.d.ts +8 -0
  119. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1608 -0
  120. package/dist/sdk/generated-error-code-catalog.js +6 -3121
  121. package/dist/sdk/governance/assurance-action-contracts.d.ts +7 -0
  122. package/dist/sdk/governance/assurance-action-contracts.js +5 -0
  123. package/dist/sdk/governance/assurance-action.d.ts +70 -0
  124. package/dist/sdk/governance/assurance-action.js +200 -0
  125. package/dist/sdk/governance/assurance-limits.d.ts +7 -0
  126. package/dist/sdk/governance/assurance-limits.js +11 -0
  127. package/dist/sdk/governance/assurance-mutation-error.d.ts +7 -0
  128. package/dist/sdk/governance/assurance-mutation-error.js +35 -0
  129. package/dist/sdk/governance/assurance-runtime.d.ts +20 -0
  130. package/dist/sdk/governance/assurance-runtime.js +134 -0
  131. package/dist/sdk/governance/assurance.d.ts +438 -0
  132. package/dist/sdk/governance/assurance.js +804 -0
  133. package/dist/sdk/governance/health.d.ts +3 -1
  134. package/dist/sdk/governance/health.js +21 -4
  135. package/dist/sdk/governance/validate-item-reader.js +3 -3
  136. package/dist/sdk/governance/validate.d.ts +2 -0
  137. package/dist/sdk/governance/validate.js +13 -3
  138. package/dist/sdk/graph/durable-cache.d.ts +1 -1
  139. package/dist/sdk/graph/durable-cache.js +98 -29
  140. package/dist/sdk/graph/governance.d.ts +14 -0
  141. package/dist/sdk/graph/governance.js +34 -9
  142. package/dist/sdk/graph/run.js +8 -3
  143. package/dist/sdk/index.d.ts +7 -2
  144. package/dist/sdk/index.js +9 -4
  145. package/dist/sdk/lifecycle/claim.js +26 -4
  146. package/dist/sdk/lifecycle/focus.js +13 -3
  147. package/dist/sdk/lifecycle/plan.js +8 -3
  148. package/dist/sdk/merge/driver.d.ts +2 -2
  149. package/dist/sdk/merge/driver.js +3 -3
  150. package/dist/sdk/merge/receipts.d.ts +6 -4
  151. package/dist/sdk/merge/receipts.js +7 -5
  152. package/dist/sdk/merge/three-way.d.ts +2 -2
  153. package/dist/sdk/merge/three-way.js +3 -3
  154. package/dist/sdk/output-projection.d.ts +9 -1
  155. package/dist/sdk/output-projection.js +45 -9
  156. package/dist/sdk/provenance.d.ts +38 -0
  157. package/dist/sdk/provenance.js +64 -2
  158. package/dist/sdk/query/activity.d.ts +49 -2
  159. package/dist/sdk/query/activity.js +183 -37
  160. package/dist/sdk/query/context.js +19 -8
  161. package/dist/sdk/query/get.js +19 -2
  162. package/dist/sdk/read-output-contracts.d.ts +5 -1
  163. package/dist/sdk/read-output-contracts.js +17 -2
  164. package/dist/sdk/read-output-session.d.ts +2 -0
  165. package/dist/sdk/read-output-session.js +12 -5
  166. package/dist/sdk/runtime-extended-actions.js +22 -5
  167. package/dist/sdk/runtime-primitives.d.ts +5 -3
  168. package/dist/sdk/runtime-primitives.js +7 -5
  169. package/dist/sdk/runtime-stats-options.js +3 -2
  170. package/dist/sdk/runtime.d.ts +4 -0
  171. package/dist/sdk/runtime.js +34 -34
  172. package/dist/sdk/stats.d.ts +36 -3
  173. package/dist/sdk/stats.js +55 -15
  174. package/dist/sdk/telemetry.js +7 -4
  175. package/dist/sdk/test/execution.d.ts +4 -0
  176. package/dist/sdk/test/execution.js +86 -21
  177. package/dist/sdk/traceability/runtime-files-lookup.d.ts +8 -0
  178. package/dist/sdk/traceability/runtime-files-lookup.js +33 -0
  179. package/dist/sdk/traceability/source-traceability.d.ts +102 -0
  180. package/dist/sdk/traceability/source-traceability.js +293 -0
  181. package/dist/types.d.ts +10 -2
  182. package/dist/types.js +2 -2
  183. package/docs/ASSURANCE.md +137 -0
  184. package/docs/COMMANDS.md +29 -8
  185. package/docs/CONFIGURATION.md +7 -0
  186. package/docs/DEPENDENCY_KIND_CONTRACT.md +10 -8
  187. package/docs/MERGE_SAFETY.md +3 -1
  188. package/docs/OUTPUT_PROJECTION_CONTRACTS.md +26 -13
  189. package/docs/README.md +3 -0
  190. package/docs/READ_OUTPUT_CONTRACTS.md +17 -2
  191. package/docs/RELEASING.md +9 -5
  192. package/docs/SDK.md +12 -1
  193. package/docs/SDK_AGENT_SESSION_CONTEXT.md +52 -5
  194. package/docs/SDK_CONTEXT_EVIDENCE_CONTRACTS.md +53 -0
  195. package/docs/SDK_CONTEXT_INTEGRITY.md +28 -1
  196. package/docs/SDK_EVIDENCE_TRACEABILITY.md +39 -1
  197. package/docs/SDK_RUNTIME_BOUNDARIES.md +36 -1
  198. package/docs/TESTING.md +12 -9
  199. package/docs/TRUSTWORTHY_CONTEXT_EVIDENCE.md +106 -0
  200. package/docs/generated/AGENT_COMMAND_SURFACE.md +1 -0
  201. package/docs/performance/sdk-entrypoint-import-costs.md +6 -2
  202. package/marketplace.json +2 -2
  203. package/package.json +7 -7
  204. package/packages/pm-beads/package.json +1 -1
  205. package/packages/pm-calendar/package.json +1 -1
  206. package/packages/pm-command-kit/package.json +1 -1
  207. package/packages/pm-digital-twin/package.json +1 -1
  208. package/packages/pm-governance-audit/package.json +1 -1
  209. package/packages/pm-guide-shell/package.json +1 -1
  210. package/packages/pm-kanban/package.json +1 -1
  211. package/packages/pm-lifecycle-hooks/package.json +1 -1
  212. package/packages/pm-linked-test-adapters/package.json +1 -1
  213. package/packages/pm-search-advanced/package.json +1 -1
  214. package/packages/pm-templates/extensions/templates/index.ts +9 -3
  215. package/packages/pm-templates/package.json +1 -1
  216. package/packages/pm-todos/package.json +1 -1
  217. package/packages/pm-vcs/package.json +1 -1
  218. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  219. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  220. package/sdk/public-surface.json +1030 -67
  221. package/dist/cli-bundle/chunks/chunk-2QYH4QMI.js +0 -30
  222. package/dist/cli-bundle/chunks/chunk-JUDU4RO4.js +0 -194
  223. package/dist/cli-bundle/chunks/chunk-JZSNADRR.js +0 -5
  224. package/dist/cli-bundle/chunks/chunk-MENWVGJW.js +0 -2
  225. package/dist/cli-bundle/chunks/chunk-S4EITGLA.js +0 -3
  226. package/dist/cli-bundle/chunks/chunk-TIGKWVLA.js +0 -13
  227. package/dist/cli-bundle/chunks/chunk-TSLDTJLQ.js +0 -2
  228. package/dist/cli-bundle/chunks/register-list-query-OJ6ZXKV4.js +0 -10
  229. package/dist/cli-bundle/chunks/register-mutation-DKI7QC7O.js +0 -20
  230. package/dist/cli-bundle/chunks/register-operations-P5OGMT6I.js +0 -2
  231. package/dist/cli-bundle/focused-chunks/chunk-36FTZ2NT.js +0 -2
  232. package/dist/cli-bundle/focused-chunks/chunk-3CQECMKR.js +0 -16
  233. package/dist/cli-bundle/focused-chunks/chunk-CHIBMEZR.js +0 -8
  234. package/dist/cli-bundle/focused-chunks/chunk-FF4MNAYB.js +0 -153
  235. package/dist/cli-bundle/focused-chunks/chunk-GHTN2ILR.js +0 -2
  236. package/dist/cli-bundle/focused-chunks/chunk-I4YM2I7S.js +0 -2
  237. package/dist/cli-bundle/focused-chunks/chunk-IMDTEN7K.js +0 -2
  238. package/dist/cli-bundle/focused-chunks/chunk-JMVA4HKR.js +0 -5
  239. package/dist/cli-bundle/focused-chunks/chunk-KR5RVXLQ.js +0 -31
  240. package/dist/cli-bundle/focused-chunks/chunk-KSNJG4KI.js +0 -16
  241. package/dist/cli-bundle/focused-chunks/chunk-MXYSIQ56.js +0 -18
  242. package/dist/cli-bundle/focused-chunks/chunk-RIIN5V4N.js +0 -2
  243. package/dist/cli-bundle/focused-chunks/chunk-RKWSCYYN.js +0 -2
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import type { HistoryEntry } from "../types.js";
7
7
  import { type HarnessSignalDescriptor } from "../core/shared/author.js";
8
+ import type { AgentModelSource } from "../core/shared/author.js";
8
9
  /** One declared provenance dimension and the built-in harnesses that can supply it. */
9
10
  export interface AgentProvenanceDescriptorCoverage {
10
11
  /** Stable provenance dimension name. */
@@ -36,6 +37,34 @@ export interface AgentProvenanceDimensionCoverage extends AgentModelProvenanceCo
36
37
  /** Stable provenance dimension being summarized. */
37
38
  dimension: string;
38
39
  }
40
+ /** Semantic attribution coverage for one harness and role/topic dimension. */
41
+ export interface AgentSemanticAttributionCoverage {
42
+ /** Stable detected harness namespace. */
43
+ harness: string;
44
+ /** Semantic dimension being measured. */
45
+ dimension: "role" | "topic";
46
+ /** History events attributed to the harness. */
47
+ entries: number;
48
+ /** Events carrying a non-empty semantic observation. */
49
+ observed: number;
50
+ /** Observed events grouped by precedence source. */
51
+ by_source: Partial<Record<AgentModelSource, number>>;
52
+ /** Observed fraction across all harness events. */
53
+ coverage: number;
54
+ }
55
+ /** Result of applying a corpus-facing semantic coverage threshold. */
56
+ export interface AgentSemanticAttributionCoverageGate {
57
+ /** Whether every sampled harness/dimension row met the threshold. */
58
+ passed: boolean;
59
+ /** Required observed fraction. */
60
+ minimum_coverage: number;
61
+ /** Required event count before a row participates. */
62
+ minimum_entries: number;
63
+ /** Deterministically ordered coverage rows. */
64
+ rows: AgentSemanticAttributionCoverage[];
65
+ /** Harness/dimension keys that failed the threshold. */
66
+ failures: string[];
67
+ }
39
68
  /** One declared or inferred episode group with deterministically nested children. */
40
69
  export interface AgentEpisodeGroup {
41
70
  /** Stable declared or inferred group key. */
@@ -68,6 +97,15 @@ export declare function summarizeAgentModelProvenance(entries: readonly Pick<His
68
97
  * every requested provenance dimension without consulting mutable state.
69
98
  */
70
99
  export declare function summarizeAgentProvenance(entries: readonly Pick<HistoryEntry, "agent_harness" | "agent_model" | "agent_provenance">[], dimensions?: readonly string[], minimumExplicitSample?: number): AgentProvenanceDimensionCoverage[];
100
+ /**
101
+ * Measure role/topic availability by harness and precedence source, then apply
102
+ * an explicit ratchet. Empty or synthetic corpora therefore remain useful
103
+ * negative controls instead of silently passing a production coverage gate.
104
+ */
105
+ export declare function evaluateSemanticAttributionCoverage(entries: readonly Pick<HistoryEntry, "agent_harness" | "agent_provenance">[], options?: {
106
+ minimumCoverage?: number;
107
+ minimumEntries?: number;
108
+ }): AgentSemanticAttributionCoverageGate;
71
109
  /**
72
110
  * Group immutable history by declared episode keys. Legacy entries fall back
73
111
  * to their privacy-safe agent instance, or to a deterministic author cohort.
@@ -1,5 +1,5 @@
1
1
 
2
- !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]="1f6a4ff8-fc1e-5aac-8117-bae8f325b275")}catch(e){}}();
2
+ !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]="6162845d-f4b4-5d1f-a210-ddef1a5c38f6")}catch(e){}}();
3
3
  import { AGENT_PROVENANCE_DIMENSIONS, BUILTIN_HARNESS_SIGNAL_DESCRIPTORS, } from "../core/shared/author.js";
4
4
  /** Resolve the declared or deterministic legacy identity for one history event. */
5
5
  export function resolveHistoryEpisodeGroupIdentity(entry) {
@@ -144,6 +144,68 @@ export function summarizeAgentProvenance(entries, dimensions = AGENT_PROVENANCE_
144
144
  .sort((left, right) => left.harness.localeCompare(right.harness) ||
145
145
  left.dimension.localeCompare(right.dimension));
146
146
  }
147
+ /**
148
+ * Measure role/topic availability by harness and precedence source, then apply
149
+ * an explicit ratchet. Empty or synthetic corpora therefore remain useful
150
+ * negative controls instead of silently passing a production coverage gate.
151
+ */
152
+ export function evaluateSemanticAttributionCoverage(entries, options = {}) {
153
+ const minimumCoverage = options.minimumCoverage ?? 0.8;
154
+ const minimumEntries = options.minimumEntries ?? 5;
155
+ if (![
156
+ Number.isFinite(minimumCoverage),
157
+ minimumCoverage >= 0,
158
+ minimumCoverage <= 1,
159
+ ].every(Boolean)) {
160
+ throw new RangeError("Semantic attribution minimum coverage must be from 0 to 1.");
161
+ }
162
+ if (![Number.isSafeInteger(minimumEntries), minimumEntries >= 1].every(Boolean)) {
163
+ throw new RangeError("Semantic attribution minimum entries must be a positive integer.");
164
+ }
165
+ const rows = new Map();
166
+ for (const entry of entries) {
167
+ if (!entry.agent_harness)
168
+ continue;
169
+ for (const dimension of ["role", "topic"]) {
170
+ const key = `${entry.agent_harness}\0${dimension}`;
171
+ const row = rows.get(key) ?? {
172
+ harness: entry.agent_harness,
173
+ dimension,
174
+ entries: 0,
175
+ observed: 0,
176
+ by_source: {},
177
+ coverage: 0,
178
+ };
179
+ row.entries += 1;
180
+ const observation = entry.agent_provenance?.[dimension];
181
+ if (observation?.value) {
182
+ row.observed += 1;
183
+ row.by_source[observation.source] =
184
+ (row.by_source[observation.source] ?? 0) + 1;
185
+ }
186
+ rows.set(key, row);
187
+ }
188
+ }
189
+ const ordered = [...rows.values()]
190
+ .map((row) => ({
191
+ ...row,
192
+ coverage: row.observed / row.entries,
193
+ by_source: Object.fromEntries(Object.entries(row.by_source).sort(([left], [right]) => left.localeCompare(right))),
194
+ }))
195
+ .sort((left, right) => left.harness.localeCompare(right.harness) ||
196
+ left.dimension.localeCompare(right.dimension));
197
+ const eligible = ordered.filter((row) => row.entries >= minimumEntries);
198
+ const failures = eligible
199
+ .filter((row) => row.coverage < minimumCoverage)
200
+ .map((row) => `${row.harness}:${row.dimension}`);
201
+ return {
202
+ passed: eligible.length > 0 && failures.length === 0,
203
+ minimum_coverage: minimumCoverage,
204
+ minimum_entries: minimumEntries,
205
+ rows: ordered,
206
+ failures,
207
+ };
208
+ }
147
209
  /**
148
210
  * Group immutable history by declared episode keys. Legacy entries fall back
149
211
  * to their privacy-safe agent instance, or to a deterministic author cohort.
@@ -194,4 +256,4 @@ export function groupHistoryByEpisode(entries) {
194
256
  return roots;
195
257
  }
196
258
  //# sourceMappingURL=provenance.js.map
197
- //# debugId=1f6a4ff8-fc1e-5aac-8117-bae8f325b275
259
+ //# debugId=6162845d-f4b4-5d1f-a210-ddef1a5c38f6
@@ -18,6 +18,8 @@ export interface ActivityCommandOptions {
18
18
  limit?: string;
19
19
  /** Value that configures or reports compact for this contract. */
20
20
  compact?: boolean;
21
+ /** Return the legacy per-event stream instead of the item-centric digest. */
22
+ raw?: boolean;
21
23
  /** Explicitly disables the default activity bound. */
22
24
  unbounded?: boolean;
23
25
  /** Return patch-free provenance rows. */
@@ -31,6 +33,10 @@ export interface ActivityCommandOptions {
31
33
  /** Exact provenance dimension predicates (`dimension=value`). */
32
34
  provenanceFilter?: string | readonly string[];
33
35
  }
36
+ /** Normalize raw and full aliases into one explicit activity row projection. */
37
+ export declare function normalizeActivityProjectionOptions(options: ActivityCommandOptions & {
38
+ full?: unknown;
39
+ }): ActivityCommandOptions;
34
40
  /** Documents the activity entry payload exchanged by command, SDK, and package integrations. */
35
41
  export interface ActivityEntry extends HistoryEntry {
36
42
  /** Stable identifier used to reference this record across commands and storage. */
@@ -49,8 +55,29 @@ export interface CompactActivityEntry {
49
55
  /** Value that configures or reports msg for this contract. */
50
56
  msg?: string;
51
57
  }
58
+ /** One item-centric summary of every matching immutable event for that item. */
59
+ export interface ActivityDigestEntry {
60
+ /** Stable item identifier. */
61
+ id: string;
62
+ /** Current item type from the light metadata join. */
63
+ type: string;
64
+ /** Current lifecycle status from the light metadata join. */
65
+ status: string;
66
+ /** Current item title, bounded for predictable context cost. */
67
+ title: string;
68
+ /** Matching immutable events folded into this row. */
69
+ event_count: number;
70
+ /** Oldest matching event timestamp. */
71
+ first_ts: string;
72
+ /** Newest matching event timestamp. */
73
+ last_ts: string;
74
+ /** Bounded operation histogram encoded as comma-separated op:count pairs. */
75
+ operations: string;
76
+ }
52
77
  /** Documents the activity result payload exchanged by command, SDK, and package integrations. */
53
78
  export interface ActivityResult {
79
+ /** Default item-centric workspace activity rows. */
80
+ activity_digest?: ActivityDigestEntry[];
54
81
  /** Value that configures or reports activity for this contract. */
55
82
  activity?: ActivityEntry[];
56
83
  /** Value that configures or reports compact activity for this contract. */
@@ -62,9 +89,9 @@ export interface ActivityResult {
62
89
  /** Explicit active row projection. */
63
90
  projection: {
64
91
  /** Stable projection mode. */
65
- mode: "compact" | "provenance" | "full";
92
+ mode: "digest" | "compact" | "provenance" | "full";
66
93
  /** Active row collection key. */
67
- row_key: "compact_activity" | "provenance_activity" | "activity";
94
+ row_key: "activity_digest" | "compact_activity" | "provenance_activity" | "activity";
68
95
  };
69
96
  /** Constant-size disclosure of field groups withheld by the active mode. */
70
97
  omission_receipt: OutputOmissionReceipt;
@@ -84,9 +111,25 @@ export interface ActivityResult {
84
111
  source: "default" | "explicit";
85
112
  value: number | null;
86
113
  };
114
+ /** Constant-size description of the selected time window and matching corpus. */
115
+ activity_summary?: {
116
+ window: {
117
+ from: string | null;
118
+ to: string | null;
119
+ };
120
+ event_count: number;
121
+ item_count: number;
122
+ author_count: number;
123
+ operation_counts: Record<string, number>;
124
+ };
87
125
  /** Constant-size provenance completeness metrics. */
88
126
  provenance_summary?: HistoryProvenanceSummary;
89
127
  }
128
+ interface ActivityItemMetadata {
129
+ title: string;
130
+ type: string;
131
+ status: string;
132
+ }
90
133
  declare function parseNonEmptyFilter(raw: string | undefined, flagLabel: string): string | undefined;
91
134
  declare function parseRangeBound(raw: string | undefined, nowValue: string, fieldLabel: string): string | undefined;
92
135
  declare function includeByTimeWindow(entry: ActivityEntry, from: string | undefined, to: string | undefined): boolean;
@@ -95,6 +138,8 @@ declare function readActivityString(value: unknown, fallback?: string): string;
95
138
  declare function normalizeActivityEntry(id: string, entry: HistoryEntry): ActivityEntry;
96
139
  declare function sortActivity(entries: ActivityEntry[]): ActivityEntry[];
97
140
  declare function listHistoryFiles(historyDir: string): Promise<string[]>;
141
+ declare function buildActivityDigest(activity: readonly ActivityEntry[], itemsById: ReadonlyMap<string, ActivityItemMetadata>): ActivityDigestEntry[];
142
+ declare function activityOperationCounts(activity: readonly Pick<ActivityEntry, "op">[]): Record<string, number>;
98
143
  /** Public contract for test only, shared by SDK and presentation-layer consumers. */
99
144
  export declare const _testOnly: {
100
145
  parseNonEmptyFilter: typeof parseNonEmptyFilter;
@@ -105,6 +150,8 @@ export declare const _testOnly: {
105
150
  normalizeActivityEntry: typeof normalizeActivityEntry;
106
151
  sortActivity: typeof sortActivity;
107
152
  listHistoryFiles: typeof listHistoryFiles;
153
+ buildActivityDigest: typeof buildActivityDigest;
154
+ activityOperationCounts: typeof activityOperationCounts;
108
155
  };
109
156
  /** Implements run activity for the public runtime surface of this module. */
110
157
  export declare function runActivity(options: ActivityCommandOptions, global: GlobalOptions): Promise<ActivityResult>;
@@ -4,7 +4,7 @@
4
4
  * Implements the pm activity 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]="a7efa5e0-5610-51ca-8288-4f5410dbcf51")}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]="27a71d4d-f496-5d0a-9771-caa43b81e1f7")}catch(e){}}();
8
8
  import fs from "node:fs/promises";
9
9
  import path from "node:path";
10
10
  import { getActiveExtensionRegistrations, runActiveOnReadHooks, pathExists, enforceHistoryStreamPolicyForItems, resolveItemTypeRegistry, EXIT_CODE, PmCliError, compareTimestampStrings, nowIso, resolveIsoOrRelative, listAllItemMetadataLight, getSettingsPath, resolvePmRoot, readSettings, } from "../runtime-primitives.js";
@@ -14,6 +14,27 @@ import { resolveModePairedOutputOmissionReceipt, } from "../output-projection.js
14
14
  import { compileHistoryProvenanceMatcher, projectHistoryProvenance, resolveHistoryProvenanceDimensions, summarizeHistoryProvenance, } from "../history-provenance.js";
15
15
  const DEFAULT_COMPACT_ACTIVITY_LIMIT = 20;
16
16
  const DEFAULT_FULL_ACTIVITY_LIMIT = 5;
17
+ const DEFAULT_DIGEST_ACTIVITY_LIMIT = 15;
18
+ const DEFAULT_DIGEST_WINDOW = "-24h";
19
+ /** Normalize raw and full aliases into one explicit activity row projection. */
20
+ export function normalizeActivityProjectionOptions(options) {
21
+ const normalized = { ...options };
22
+ if (normalized.full === true) {
23
+ normalized.raw = true;
24
+ normalized.compact = false;
25
+ }
26
+ else if (normalized.raw === true && normalized.compact === undefined) {
27
+ normalized.compact = true;
28
+ }
29
+ delete normalized.full;
30
+ return normalized;
31
+ }
32
+ const ACTIVITY_ROW_KEY_BY_MODE = {
33
+ digest: "activity_digest",
34
+ compact: "compact_activity",
35
+ provenance: "provenance_activity",
36
+ full: "activity",
37
+ };
17
38
  function parseNonEmptyFilter(raw, flagLabel) {
18
39
  if (raw === undefined)
19
40
  return undefined;
@@ -92,10 +113,36 @@ async function listHistoryFiles(historyDir) {
92
113
  throw error;
93
114
  }
94
115
  }
95
- function resolveActivityFilters(options) {
116
+ function resolveActivityProjectionMode(options) {
117
+ if (options.raw !== true &&
118
+ options.compact !== true &&
119
+ options.provenance !== true) {
120
+ return "digest";
121
+ }
122
+ if (options.provenance === true)
123
+ return "provenance";
124
+ if (options.compact === true ||
125
+ (options.raw === true && options.compact !== false)) {
126
+ return "compact";
127
+ }
128
+ return "full";
129
+ }
130
+ function resolveActivityLimit(options, explicitLimit, projectionMode) {
131
+ if (options.unbounded === true)
132
+ return undefined;
133
+ if (explicitLimit !== undefined)
134
+ return explicitLimit;
135
+ if (projectionMode === "digest")
136
+ return DEFAULT_DIGEST_ACTIVITY_LIMIT;
137
+ if (projectionMode === "compact")
138
+ return DEFAULT_COMPACT_ACTIVITY_LIMIT;
139
+ return DEFAULT_FULL_ACTIVITY_LIMIT;
140
+ }
141
+ function resolveActivityFilters(options, projectionMode) {
96
142
  const nowValue = nowIso();
97
- const from = parseRangeBound(options.from, nowValue, "--from");
98
- const to = parseRangeBound(options.to, nowValue, "--to");
143
+ const digest = projectionMode === "digest";
144
+ const to = parseRangeBound(options.to ?? (digest ? nowValue : undefined), nowValue, "--to");
145
+ const from = parseRangeBound(options.from ?? (digest ? DEFAULT_DIGEST_WINDOW : undefined), options.from === undefined && digest ? to : nowValue, "--from");
99
146
  if (from && to && compareTimestampStrings(from, to) >= 0) {
100
147
  throw new PmCliError("Activity --from must be before --to", EXIT_CODE.USAGE);
101
148
  }
@@ -109,12 +156,7 @@ function resolveActivityFilters(options) {
109
156
  author: parseNonEmptyFilter(options.author, "Activity --author"),
110
157
  from,
111
158
  to,
112
- limit: options.unbounded === true
113
- ? undefined
114
- : (explicitLimit ??
115
- (options.compact === true
116
- ? DEFAULT_COMPACT_ACTIVITY_LIMIT
117
- : DEFAULT_FULL_ACTIVITY_LIMIT)),
159
+ limit: resolveActivityLimit(options, explicitLimit, projectionMode),
118
160
  limitSource: options.unbounded === true || explicitLimit !== undefined
119
161
  ? "explicit"
120
162
  : "default",
@@ -147,7 +189,13 @@ async function prepareActivityHistoryRead(context) {
147
189
  path: historyDir,
148
190
  scope: "project",
149
191
  });
150
- return historyDir;
192
+ return {
193
+ historyDir,
194
+ itemsById: new Map(items.map((item) => [
195
+ item.id,
196
+ { title: item.title, type: item.type, status: item.status },
197
+ ])),
198
+ };
151
199
  }
152
200
  function includeActivityEntry(entry, candidate, filters) {
153
201
  // Preserve legacy filter semantics: op/author filters compare the raw
@@ -186,6 +234,105 @@ function formatCompactActivity(activity) {
186
234
  ...(entry.message ? { msg: entry.message } : {}),
187
235
  }));
188
236
  }
237
+ function boundedOperationSummary(counts) {
238
+ const ordered = [...counts.entries()].sort(([leftOp, leftCount], [rightOp, rightCount]) => rightCount - leftCount || leftOp.localeCompare(rightOp));
239
+ const visible = ordered.slice(0, 4).map(([op, count]) => `${op}:${count}`);
240
+ if (ordered.length > visible.length) {
241
+ visible.push(`+${ordered.length - visible.length}`);
242
+ }
243
+ return visible.join(",");
244
+ }
245
+ function buildActivityDigest(activity, itemsById) {
246
+ const grouped = new Map();
247
+ for (const entry of activity) {
248
+ const current = grouped.get(entry.id);
249
+ if (current === undefined) {
250
+ grouped.set(entry.id, {
251
+ firstTs: entry.ts,
252
+ lastTs: entry.ts,
253
+ eventCount: 1,
254
+ operations: new Map([[entry.op, 1]]),
255
+ });
256
+ continue;
257
+ }
258
+ current.eventCount += 1;
259
+ if (compareTimestampStrings(entry.ts, current.firstTs) < 0) {
260
+ current.firstTs = entry.ts;
261
+ }
262
+ if (compareTimestampStrings(entry.ts, current.lastTs) > 0) {
263
+ current.lastTs = entry.ts;
264
+ }
265
+ current.operations.set(entry.op, (current.operations.get(entry.op) ?? 0) + 1);
266
+ }
267
+ return [...grouped.entries()]
268
+ .map(([id, summary]) => {
269
+ const item = itemsById.get(id);
270
+ return {
271
+ id,
272
+ type: item?.type ?? "unknown",
273
+ status: item?.status ?? "unknown",
274
+ title: (item?.title ?? "(item metadata unavailable)").slice(0, 160),
275
+ event_count: summary.eventCount,
276
+ first_ts: summary.firstTs,
277
+ last_ts: summary.lastTs,
278
+ operations: boundedOperationSummary(summary.operations),
279
+ };
280
+ })
281
+ .sort((left, right) => compareTimestampStrings(right.last_ts, left.last_ts) ||
282
+ left.id.localeCompare(right.id));
283
+ }
284
+ function activityOperationCounts(activity) {
285
+ const counts = new Map();
286
+ for (const entry of activity) {
287
+ counts.set(entry.op, (counts.get(entry.op) ?? 0) + 1);
288
+ }
289
+ const ordered = [...counts.entries()].sort((left, right) => right[1] - left[1] || left[0].localeCompare(right[0]));
290
+ const visible = ordered.slice(0, 8);
291
+ if (visible.length < ordered.length) {
292
+ visible.push([
293
+ `+${String(ordered.length - visible.length)}`,
294
+ ordered
295
+ .slice(visible.length)
296
+ .reduce((total, [, count]) => total + count, 0),
297
+ ]);
298
+ }
299
+ return Object.fromEntries(visible);
300
+ }
301
+ function projectActivityRows(projectionMode, matchingActivity, limit, itemsById, projectProvenance) {
302
+ if (projectionMode === "digest") {
303
+ const matchingDigest = buildActivityDigest(matchingActivity, itemsById);
304
+ const activityDigest = limitEntries(matchingDigest, limit);
305
+ return {
306
+ rows: { activity_digest: activityDigest },
307
+ compact: false,
308
+ totalRows: matchingDigest.length,
309
+ returnedRows: activityDigest.length,
310
+ };
311
+ }
312
+ const activity = limitEntries(matchingActivity, limit);
313
+ if (projectionMode === "compact") {
314
+ return {
315
+ rows: { compact_activity: formatCompactActivity(activity) },
316
+ compact: true,
317
+ totalRows: matchingActivity.length,
318
+ returnedRows: activity.length,
319
+ };
320
+ }
321
+ if (projectionMode === "provenance") {
322
+ return {
323
+ rows: { provenance_activity: activity.map(projectProvenance) },
324
+ compact: false,
325
+ totalRows: matchingActivity.length,
326
+ returnedRows: activity.length,
327
+ };
328
+ }
329
+ return {
330
+ rows: { activity },
331
+ compact: false,
332
+ totalRows: matchingActivity.length,
333
+ returnedRows: activity.length,
334
+ };
335
+ }
189
336
  /** Public contract for test only, shared by SDK and presentation-layer consumers. */
190
337
  export const _testOnly = {
191
338
  parseNonEmptyFilter,
@@ -196,12 +343,15 @@ export const _testOnly = {
196
343
  normalizeActivityEntry,
197
344
  sortActivity,
198
345
  listHistoryFiles,
346
+ buildActivityDigest,
347
+ activityOperationCounts,
199
348
  };
200
349
  /** Implements run activity for the public runtime surface of this module. */
201
350
  export async function runActivity(options, global) {
202
351
  const context = await resolveActivityRuntimeContext(global);
203
- const filters = resolveActivityFilters(options);
204
- const historyDir = await prepareActivityHistoryRead(context);
352
+ const projectionMode = resolveActivityProjectionMode(options);
353
+ const filters = resolveActivityFilters(options, projectionMode);
354
+ const prepared = await prepareActivityHistoryRead(context);
205
355
  const provenanceDimensions = resolveHistoryProvenanceDimensions(context.settings.agent_identity.harness_signals);
206
356
  const vocabulary = context.settings.agent_identity.identity_vocabulary;
207
357
  const matchesProvenance = compileHistoryProvenanceMatcher({
@@ -209,37 +359,33 @@ export async function runActivity(options, global) {
209
359
  agentInstance: filters.agentInstance,
210
360
  provenance: filters.provenance,
211
361
  }, vocabulary, provenanceDimensions);
212
- const matchingActivity = sortActivity(await collectActivityEntries(historyDir, filters)).filter(matchesProvenance);
213
- const activity = limitEntries(matchingActivity, filters.limit);
214
- const compact = options.compact === true;
215
- const compactActivity = compact ? formatCompactActivity(activity) : undefined;
216
- const provenanceActivity = options.provenance === true
217
- ? activity.map((entry) => projectHistoryProvenance(entry, vocabulary, { itemId: entry.id }))
218
- : undefined;
219
- const omittedCount = matchingActivity.length - activity.length;
220
- const projectionMode = options.provenance === true ? "provenance" : compact ? "compact" : "full";
221
- const rowProjection = {
222
- compact: { compact_activity: compactActivity },
223
- provenance: { provenance_activity: provenanceActivity },
224
- full: { activity },
225
- }[projectionMode];
362
+ const matchingActivity = sortActivity(await collectActivityEntries(prepared.historyDir, filters)).filter(matchesProvenance);
363
+ const projected = projectActivityRows(projectionMode, matchingActivity, filters.limit, prepared.itemsById, (entry) => projectHistoryProvenance(entry, vocabulary, { itemId: entry.id }));
364
+ const omittedCount = projected.totalRows - projected.returnedRows;
226
365
  return {
227
- ...rowProjection,
228
- compact,
366
+ ...projected.rows,
367
+ compact: projected.compact,
229
368
  projection: {
230
369
  mode: projectionMode,
231
- row_key: projectionMode === "compact"
232
- ? "compact_activity"
233
- : projectionMode === "provenance"
234
- ? "provenance_activity"
235
- : "activity",
370
+ row_key: ACTIVITY_ROW_KEY_BY_MODE[projectionMode],
236
371
  },
237
372
  omission_receipt: resolveModePairedOutputOmissionReceipt("activity", projectionMode),
238
- count: activity.length,
239
- total_count: matchingActivity.length,
373
+ count: projected.returnedRows,
374
+ total_count: projected.totalRows,
240
375
  limit: filters.limit ?? null,
241
376
  omitted_count: omittedCount,
242
377
  has_more: omittedCount > 0,
378
+ ...(projectionMode === "digest"
379
+ ? {
380
+ activity_summary: {
381
+ window: { from: filters.from, to: filters.to },
382
+ event_count: matchingActivity.length,
383
+ item_count: projected.totalRows,
384
+ author_count: new Set(matchingActivity.map((entry) => entry.author)).size,
385
+ operation_counts: activityOperationCounts(matchingActivity),
386
+ },
387
+ }
388
+ : {}),
243
389
  ...(options.provenanceSummary === true
244
390
  ? {
245
391
  provenance_summary: summarizeHistoryProvenance(matchingActivity, vocabulary, provenanceDimensions),
@@ -253,4 +399,4 @@ export async function runActivity(options, global) {
253
399
  };
254
400
  }
255
401
  //# sourceMappingURL=activity.js.map
256
- //# debugId=a7efa5e0-5610-51ca-8288-4f5410dbcf51
402
+ //# debugId=27a71d4d-f496-5d0a-9771-caa43b81e1f7
@@ -4,7 +4,7 @@
4
4
  * Implements the pm context 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]="161507f0-b1a7-59a6-9a60-d8f09806ed3f")}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]="757a0349-9fb6-579d-ab29-fabaad790ce4")}catch(e){}}();
8
8
  import { SETTINGS_DEFAULTS, EXIT_CODE, PmCliError, compareTimestampStrings, nowIso, isTerminalStatus, normalizeStatusForRegistry, normalizeStatusInput, resolveRuntimeStatusRegistry, resolvePmRoot, readSettings, resolveAuthor, discoverExtensions, } from "../runtime-primitives.js";
9
9
  import { collectDependencyBlockedIds, resolveItemBlockers, } from "../actionability.js";
10
10
  import { CONTEXT_DEPTH_VALUES, CONTEXT_SECTION_VALUES, } from "../../types/index.js";
@@ -20,6 +20,9 @@ import { packContextCandidates, } from "../context-packing.js";
20
20
  import { readContextUsageAffinity, recordContextUsageServing, } from "../context-usage.js";
21
21
  import { readWorkspaceContextSignals, } from "../context-signal-store.js";
22
22
  import { readWorkspaceMemory, selectWorkspaceMemory, } from "../workspace-memory.js";
23
+ import { detectAgentIdentity } from "../../core/shared/author.js";
24
+ import { readSessionState, semanticAttributionKey, } from "../../core/session/session-state.js";
25
+ import { semanticAttributionAffinity } from "../context/semantic-session-attribution.js";
23
26
  // ---------------------------------------------------------------------------
24
27
  // Output format
25
28
  // ---------------------------------------------------------------------------
@@ -1223,7 +1226,7 @@ function resolveContextSubtreeIds(parentScope, fullCorpus) {
1223
1226
  }
1224
1227
  return subtree.ids;
1225
1228
  }
1226
- async function resolveContextFocusGroups(listedItemMetadata, allItems, fullCorpus, blockedIds, statusRegistry, sectionsIncluded, limit, now, author, cursor, cursorFingerprint, useBoundedPage, pmRoot, tokenBudget) {
1229
+ async function resolveContextFocusGroups(listedItemMetadata, allItems, fullCorpus, blockedIds, statusRegistry, sectionsIncluded, limit, now, author, cursor, cursorFingerprint, useBoundedPage, pmRoot, tokenBudget, claimFocus) {
1227
1230
  const structural = [...listedItemMetadata].sort((left, right) => compareCriticalItems(left, right, statusRegistry));
1228
1231
  const usage = await readContextUsageAffinity({
1229
1232
  pmRoot,
@@ -1237,6 +1240,7 @@ async function resolveContextFocusGroups(listedItemMetadata, allItems, fullCorpu
1237
1240
  now,
1238
1241
  author,
1239
1242
  usageAffinity: usage.affinity,
1243
+ claimFocus,
1240
1244
  });
1241
1245
  const ranking = await scoreContextCandidatesWithActiveExtensions("context", featureStore.candidates);
1242
1246
  const ranked = ranking.ranked.map((entry) => entry.item);
@@ -1262,7 +1266,9 @@ async function resolveContextFocusGroups(listedItemMetadata, allItems, fullCorpu
1262
1266
  const packing = packRankedContextItems({
1263
1267
  ...ranking,
1264
1268
  ranked: ranking.ranked.filter((entry) => packingIds.has(entry.id)),
1265
- }, tokenBudget);
1269
+ }, tokenBudget, new Set(Object.entries(claimFocus ?? {})
1270
+ .filter(([, affinity]) => affinity >= 1)
1271
+ .map(([id]) => id)));
1266
1272
  const packedItems = packing.included.map((entry) => entry.item);
1267
1273
  const activeItems = packedItems.filter((item) => activeStatuses.has(normalizeStatusForRegistry(item.status, statusRegistry)));
1268
1274
  const blockedItems = packedItems.filter((item) => blockedIds.has(item.id.trim().toLowerCase()));
@@ -1297,9 +1303,7 @@ async function resolveContextFocusGroups(listedItemMetadata, allItems, fullCorpu
1297
1303
  highLevel,
1298
1304
  lowLevel,
1299
1305
  blockedFallback: blockedFallbackUsed
1300
- ? blockedItems
1301
- .slice(0, limit)
1302
- .map(projectFocusItem)
1306
+ ? blockedItems.slice(0, limit).map(projectFocusItem)
1303
1307
  : [],
1304
1308
  blockedFallbackUsed,
1305
1309
  ranking,
@@ -1554,6 +1558,12 @@ export async function resolveContextExtensionHealthProjection(omitted, pmRoot, s
1554
1558
  },
1555
1559
  };
1556
1560
  }
1561
+ async function resolveContextSemanticAffinity(pmRoot, author) {
1562
+ const identity = detectAgentIdentity();
1563
+ const semanticState = await readSessionState(pmRoot);
1564
+ const attributionKey = identity.instance || semanticAttributionKey(author);
1565
+ return semanticAttributionAffinity(semanticState.semantic_attribution?.[attributionKey]);
1566
+ }
1557
1567
  /** Implements run context for the public runtime surface of this module. */
1558
1568
  export async function runContext(options, global) {
1559
1569
  const pmRoot = resolvePmRoot(process.cwd(), global.path);
@@ -1566,11 +1576,12 @@ export async function runContext(options, global) {
1566
1576
  tokenBudget: resolveContextTokenBudget(options.tokenBudget, Math.max(256, scaledLimit * 160)),
1567
1577
  };
1568
1578
  const author = resolveAuthor(undefined, runtime.settings.author_default);
1579
+ const claimFocus = await resolveContextSemanticAffinity(pmRoot, author);
1569
1580
  const extensionHealthPromise = resolveContextExtensionHealthProjection(options.noExtensionHealth === true, pmRoot, runtime.settings);
1570
1581
  // Single shared edge-aware blocked classification (GH-578): resolved against
1571
1582
  // the full corpus so terminal blocker targets count as satisfied at every depth.
1572
1583
  const blockedIds = collectDependencyBlockedIds(corpus.fullCorpus, runtime.statusRegistry);
1573
- const focusGroups = await resolveContextFocusGroups(corpus.listedItemMetadata, corpus.allItems, corpus.fullCorpus, blockedIds, runtime.statusRegistry, runtime.sectionsIncluded, runtime.limit, nowIso(), author, options.after, buildContextCursorFingerprint(options), shouldPageContextFocus(options, corpus.fullCorpus.length), pmRoot, runtime.tokenBudget);
1584
+ const focusGroups = await resolveContextFocusGroups(corpus.listedItemMetadata, corpus.allItems, corpus.fullCorpus, blockedIds, runtime.statusRegistry, runtime.sectionsIncluded, runtime.limit, nowIso(), author, options.after, buildContextCursorFingerprint(options), shouldPageContextFocus(options, corpus.fullCorpus.length), pmRoot, runtime.tokenBudget, claimFocus);
1574
1585
  const agendaContext = await buildContextAgenda(global, runtime, corpus.subtreeIds, new Set([
1575
1586
  ...focusGroups.highLevel,
1576
1587
  ...focusGroups.lowLevel,
@@ -1659,4 +1670,4 @@ export async function runContext(options, global) {
1659
1670
  return result;
1660
1671
  }
1661
1672
  //# sourceMappingURL=context.js.map
1662
- //# debugId=161507f0-b1a7-59a6-9a60-d8f09806ed3f
1673
+ //# debugId=757a0349-9fb6-579d-ab29-fabaad790ce4