@mgiles/perk 3.2.0 → 3.3.0

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 (202) hide show
  1. package/README.md +5 -0
  2. package/extension/authoring/gist/draft.ts +198 -0
  3. package/extension/authoring/gist/prose.ts +46 -0
  4. package/extension/authoring/gist/review.ts +133 -0
  5. package/extension/authoring/gist/save.ts +118 -0
  6. package/extension/authoring/objective/draft.ts +345 -0
  7. package/extension/{factories/objectiveDreamReport.ts → authoring/objective/dreamReportGate.ts} +74 -131
  8. package/extension/authoring/objective/planning.ts +124 -0
  9. package/extension/authoring/objective/prose.ts +103 -0
  10. package/extension/authoring/objective/review.ts +128 -0
  11. package/extension/authoring/objective/save.ts +224 -0
  12. package/extension/authoring/plan/draft.ts +84 -0
  13. package/extension/authoring/plan/prose.ts +41 -0
  14. package/extension/authoring/plan/review.ts +269 -0
  15. package/extension/authoring/plan/save.ts +256 -0
  16. package/extension/authoring/plan/source.ts +82 -0
  17. package/extension/authoring/refinement/context.ts +468 -0
  18. package/extension/authoring/refinement/draft.ts +261 -0
  19. package/extension/authoring/refinement/prose.ts +79 -0
  20. package/extension/authoring/refinement/review.ts +111 -0
  21. package/extension/authoring/refinement/save.ts +119 -0
  22. package/extension/authoring/review/approvalGate.ts +34 -0
  23. package/extension/authoring/review/draftContext.ts +68 -0
  24. package/extension/codeReview/automated.ts +352 -0
  25. package/extension/codeReview/submission.ts +229 -0
  26. package/extension/delivery/address.ts +295 -0
  27. package/extension/delivery/ci.ts +355 -0
  28. package/extension/delivery/commitCompact.ts +93 -0
  29. package/extension/delivery/conflictResolution.ts +247 -0
  30. package/extension/delivery/ready.ts +193 -0
  31. package/extension/delivery/stackConflict.ts +361 -0
  32. package/extension/delivery/stackObjective.ts +16 -0
  33. package/extension/delivery/stackReconcile.ts +165 -0
  34. package/extension/delivery/submit.ts +171 -0
  35. package/extension/index.ts +365 -380
  36. package/extension/learning/analystWave.ts +324 -0
  37. package/extension/learning/audit.ts +667 -0
  38. package/extension/learning/capture.ts +92 -0
  39. package/extension/learning/containment.ts +104 -0
  40. package/extension/{waves/dreamWave.ts → learning/dream.ts} +112 -94
  41. package/extension/learning/dreamAnalysis.ts +435 -0
  42. package/extension/{waves/dreamReducerWave.ts → learning/dreamReducer.ts} +46 -41
  43. package/extension/{waves → learning}/dreamReport.ts +35 -31
  44. package/extension/learning/harvest.ts +491 -0
  45. package/extension/learning/prose.ts +66 -0
  46. package/extension/learning/routing.ts +79 -0
  47. package/extension/pi/v1/bashScanTimeout.ts +64 -0
  48. package/extension/{doors/prReview.ts → pi/v1/codeReview/automated.ts} +215 -311
  49. package/extension/{doors/prReviewBrowser.ts → pi/v1/codeReview/browser.ts} +53 -33
  50. package/extension/{doors/hunkHandoff.ts → pi/v1/codeReview/checkout.ts} +12 -8
  51. package/extension/{doors/reviewWaveTools.ts → pi/v1/codeReview/reviewWave.ts} +146 -114
  52. package/extension/{doors/stackReviewBrowser.ts → pi/v1/codeReview/stack.ts} +62 -29
  53. package/extension/pi/v1/codeReview/submit.ts +354 -0
  54. package/extension/{doors/prReviewTerminal.ts → pi/v1/codeReview/terminal.ts} +32 -27
  55. package/extension/pi/v1/contextEvidence.ts +80 -0
  56. package/extension/pi/v1/contextInjection.ts +207 -0
  57. package/extension/{doors → pi/v1/delivery}/address.ts +154 -267
  58. package/extension/pi/v1/delivery/ci.ts +570 -0
  59. package/extension/pi/v1/delivery/commitCompact.ts +201 -0
  60. package/extension/pi/v1/delivery/conflictResolverEngine.ts +425 -0
  61. package/extension/{doors → pi/v1/delivery}/land.ts +123 -61
  62. package/extension/pi/v1/delivery/ready.ts +322 -0
  63. package/extension/pi/v1/delivery/stackConflictResolver.ts +172 -0
  64. package/extension/pi/v1/delivery/stackDrive.ts +120 -0
  65. package/extension/pi/v1/delivery/stackLand.ts +223 -0
  66. package/extension/pi/v1/delivery/stackRecover.ts +265 -0
  67. package/extension/pi/v1/delivery/stackStatus.ts +237 -0
  68. package/extension/pi/v1/delivery/stackSync.ts +658 -0
  69. package/extension/pi/v1/delivery/submit.ts +389 -0
  70. package/extension/pi/v1/delivery/submitConflict.ts +186 -0
  71. package/extension/pi/v1/draftReview.ts +431 -0
  72. package/extension/{doors → pi/v1}/draftReviewWaveTools.ts +141 -151
  73. package/extension/pi/v1/gist.ts +794 -0
  74. package/extension/pi/v1/learning/audit.ts +186 -0
  75. package/extension/pi/v1/learning/dream.ts +207 -0
  76. package/extension/{doors/learnFactory.ts → pi/v1/learning/factory.ts} +18 -65
  77. package/extension/{doors/harvestWaveTools.ts → pi/v1/learning/harvest.ts} +46 -100
  78. package/extension/pi/v1/learning/learn.ts +585 -0
  79. package/extension/pi/v1/lifecycleGates.ts +127 -0
  80. package/extension/{factories → pi/v1}/objective.ts +53 -33
  81. package/extension/pi/v1/objectiveAuthoring.ts +672 -0
  82. package/extension/pi/v1/objectiveDreamGate.ts +160 -0
  83. package/extension/{factories/objectivePlan.ts → pi/v1/objectivePlanning.ts} +328 -533
  84. package/extension/pi/v1/objectiveRefinement.ts +1320 -0
  85. package/extension/pi/v1/objectiveReview.ts +451 -0
  86. package/extension/{doors → pi/v1}/objectiveReviewBrowser.ts +259 -172
  87. package/extension/pi/v1/plan.ts +812 -0
  88. package/extension/pi/v1/planReview.ts +820 -0
  89. package/extension/{doors → pi/v1}/planReviewBrowser.ts +228 -152
  90. package/extension/{doors/annotationPush.ts → pi/v1/providers/annotations.ts} +158 -89
  91. package/extension/pi/v1/providers/plannotator.ts +487 -0
  92. package/extension/{doors → pi/v1/providers}/plannotatorHandoff.ts +73 -27
  93. package/extension/pi/v1/providers/selection.ts +43 -0
  94. package/extension/{adapters/planAdapterTombell.ts → pi/v1/providers/tombell.ts} +43 -72
  95. package/extension/pi/v1/review.ts +538 -0
  96. package/extension/pi/v1/reviewOutcome.ts +9 -0
  97. package/extension/pi/v1/scoutWave.ts +318 -0
  98. package/extension/{doors → pi/v1}/selfcheck.ts +4 -4
  99. package/extension/session/branchWorkflowSession.ts +60 -0
  100. package/extension/session/lifecycle.ts +644 -0
  101. package/extension/session/lifecycleGates.ts +64 -0
  102. package/extension/session/saveDestination.ts +87 -0
  103. package/extension/session/workflowSession.ts +971 -0
  104. package/extension/substrate/agentScratch.ts +27 -54
  105. package/extension/substrate/bashScanTimeout.ts +181 -0
  106. package/extension/substrate/bindingDelivery.ts +38 -30
  107. package/extension/substrate/bindings.ts +4 -5
  108. package/extension/substrate/cache.ts +64 -12
  109. package/extension/substrate/childRestrictions.ts +39 -0
  110. package/extension/substrate/coldDoor.ts +17 -1
  111. package/extension/substrate/config.ts +157 -21
  112. package/extension/substrate/git.ts +88 -6
  113. package/extension/substrate/modelVisible.ts +53 -0
  114. package/extension/substrate/prompts.ts +22 -0
  115. package/extension/substrate/registry.ts +2 -0
  116. package/extension/substrate/resolverLease.ts +5 -4
  117. package/extension/substrate/sessionData.ts +85 -152
  118. package/extension/substrate/toolGating.ts +263 -84
  119. package/extension/substrate/unifiedDiff.ts +1 -1
  120. package/extension/substrate/workflowState.ts +178 -163
  121. package/extension/substrate/worktreeResolverLock.ts +261 -0
  122. package/extension/surfaces/surfaces.ts +79 -27
  123. package/extension/waves/adversarialReviewWave.ts +87 -46
  124. package/extension/waves/blockedReports.ts +59 -0
  125. package/extension/waves/draftReviewWave.ts +42 -42
  126. package/extension/waves/laneIdentity.ts +77 -0
  127. package/extension/waves/objectiveExplorerWave.ts +24 -24
  128. package/extension/waves/prReviewWave.ts +89 -77
  129. package/extension/waves/reportWave.ts +438 -578
  130. package/extension/waves/reviewClassifierWave.ts +22 -22
  131. package/extension/waves/rpcAdapter.ts +100 -15
  132. package/extension/waves/scoutWave.ts +192 -0
  133. package/extension/waves/transport.ts +480 -0
  134. package/extension/worker/sdkAdapter.ts +494 -0
  135. package/extension/worker/stageExecution.ts +679 -0
  136. package/extension/workerMain.ts +18 -19
  137. package/package.json +6 -4
  138. package/prompts/_fixtures/live.yaml +43 -18
  139. package/prompts/contexts/adapters/plannotator-gist.md +6 -0
  140. package/prompts/contexts/adapters/plannotator-objective.md +6 -0
  141. package/prompts/contexts/adapters/plannotator-plan.md +8 -1
  142. package/prompts/contexts/adapters/plannotator-refinement.md +22 -0
  143. package/prompts/contexts/objective-refinement.md +17 -0
  144. package/prompts/contexts/read-only.md +1 -1
  145. package/prompts/stages/conflict-resolution-continuation.md +9 -6
  146. package/prompts/stages/conflict-resolution.md +4 -4
  147. package/prompts/stages/objective-plan/guidance.md +2 -2
  148. package/prompts/stages/objective-plan/seed.md +9 -1
  149. package/prompts/stages/objective-reconcile-ready.md +1 -1
  150. package/prompts/stages/objective-reconcile.md +1 -1
  151. package/prompts/stages/objective-refine/seed.md +18 -0
  152. package/prompts/stages/objective-review-browser.md +4 -4
  153. package/prompts/stages/objective-sync.md +1 -1
  154. package/prompts/stages/plan-review-browser.md +4 -4
  155. package/prompts/stages/pr-review-browser/active.md +3 -4
  156. package/prompts/stages/pr-review-browser/foreign.md +3 -4
  157. package/prompts/stages/pr-review-terminal/active.md +3 -3
  158. package/prompts/stages/pr-review-terminal/foreign.md +3 -3
  159. package/prompts/stages/pr-review.md +3 -3
  160. package/prompts/stages/stack-review-browser/stack.md +5 -6
  161. package/shared/README.md +8 -0
  162. package/shared/bindings.yaml +3 -3
  163. package/shared/contracts.md +2601 -506
  164. package/shared/fixtures/issues-table.json +130 -0
  165. package/shared/registry.yaml +13 -0
  166. package/shared/schemas/outputs/objective-node-engagement.schema.json +318 -0
  167. package/shared/schemas/outputs/objective-stack-status.schema.json +6 -1
  168. package/shared/schemas/outputs/pr-review-context.schema.json +54 -9
  169. package/shared/schemas/outputs/pr-review-stack-context.schema.json +196 -0
  170. package/extension/adapters/planAdapterPlannotator.ts +0 -362
  171. package/extension/doors/auditWaveTools.ts +0 -352
  172. package/extension/doors/ciExecutor.ts +0 -756
  173. package/extension/doors/commitCompact.ts +0 -251
  174. package/extension/doors/dreamWaveTools.ts +0 -489
  175. package/extension/doors/learn.ts +0 -668
  176. package/extension/doors/lifecycleGates.ts +0 -207
  177. package/extension/doors/objectiveStack.ts +0 -1543
  178. package/extension/doors/prReviewDynamic.ts +0 -276
  179. package/extension/doors/ready.ts +0 -279
  180. package/extension/doors/submit.ts +0 -373
  181. package/extension/doors/submitPrReview.ts +0 -505
  182. package/extension/factories/gistAuthor.ts +0 -94
  183. package/extension/factories/gistDraft.ts +0 -265
  184. package/extension/factories/gistSave.ts +0 -251
  185. package/extension/factories/implementHere.ts +0 -116
  186. package/extension/factories/objectiveAuthor.ts +0 -98
  187. package/extension/factories/objectiveDraft.ts +0 -466
  188. package/extension/factories/objectiveSave.ts +0 -366
  189. package/extension/factories/planDraft.ts +0 -140
  190. package/extension/factories/planMode.ts +0 -205
  191. package/extension/factories/planReview.ts +0 -1237
  192. package/extension/factories/planSave.ts +0 -604
  193. package/extension/factories/planTitle.ts +0 -141
  194. package/extension/substrate/structuredOutput.ts +0 -202
  195. package/extension/waves/auditWave.ts +0 -312
  196. package/extension/waves/harvestWave.ts +0 -399
  197. package/extension/waves/learnWave.ts +0 -155
  198. package/extension/waves/memoryAdapter.ts +0 -139
  199. package/extension/waves/prReviewDynamicWave.ts +0 -777
  200. package/extension/worker/readOnlySession.ts +0 -294
  201. package/extension/worker/worker.ts +0 -899
  202. package/prompts/stages/pr-review-dynamic.md +0 -7
@@ -0,0 +1,130 @@
1
+ {
2
+ "description": "Perk TOML documents paired with the `[issues] backend`/`team` values the TS subset reader yields (`expected`: extension/substrate/config.ts::resolveIssueDestination via parseTomlSubset — stripped, blank/non-string/absent → null) and whether that read is provably tomllib's (`provable`: resolveIssueRouting reads `keys`; otherwise the save-destination fence widens to the whole `document`). When Python's tomllib reads something else, `tomllib` carries its reading — every such case MUST be unproven. contracts.md §8.23.",
3
+ "cases": [
4
+ {
5
+ "name": "basic strings",
6
+ "toml": "[issues]\nbackend = \"linear\"\nteam = \"ENG\"\n",
7
+ "expected": { "backend": "linear", "team": "ENG" },
8
+ "provable": true
9
+ },
10
+ {
11
+ "name": "literal strings",
12
+ "toml": "[issues]\nbackend = 'linear'\nteam = 'ENG'\n",
13
+ "expected": { "backend": "linear", "team": "ENG" },
14
+ "provable": true
15
+ },
16
+ {
17
+ "name": "multi-line basic strings (unproven: the subset's escape handling is not tomllib's)",
18
+ "toml": "[issues]\nbackend = \"\"\"linear\"\"\"\nteam = \"\"\"\nENG\"\"\"\n",
19
+ "expected": { "backend": "linear", "team": "ENG" },
20
+ "provable": false
21
+ },
22
+ {
23
+ "name": "multi-line literal strings (unproven: only single-line strings are vouched for)",
24
+ "toml": "[issues]\nbackend = '''linear'''\nteam = '''\nENG'''\n",
25
+ "expected": { "backend": "linear", "team": "ENG" },
26
+ "provable": false
27
+ },
28
+ {
29
+ "name": "literal strings keep backslashes verbatim",
30
+ "toml": "[issues]\nbackend = 'github'\nteam = 'C:\\ENG'\n",
31
+ "expected": { "backend": "github", "team": "C:\\ENG" },
32
+ "provable": true
33
+ },
34
+ {
35
+ "name": "inline comments after the strings",
36
+ "toml": "[issues]\nbackend = \"linear\" # committed\nteam = 'ENG' # the team key\n",
37
+ "expected": { "backend": "linear", "team": "ENG" },
38
+ "provable": true
39
+ },
40
+ {
41
+ "name": "surrounding whitespace is stripped (StrippedStr)",
42
+ "toml": "[issues]\nbackend = \" linear \"\nteam = ' ENG'\n",
43
+ "expected": { "backend": "linear", "team": "ENG" },
44
+ "provable": true
45
+ },
46
+ {
47
+ "name": "blank strings read as absent (StrippedStr)",
48
+ "toml": "[issues]\nbackend = \"\"\nteam = ' '\n",
49
+ "expected": { "backend": null, "team": null },
50
+ "provable": true
51
+ },
52
+ {
53
+ "name": "other keys in the table and other tables around it",
54
+ "toml": "[workflow]\nbase = \"main\"\n\n[issues]\nlabel = \"perk\"\nbackend = \"github\"\n\n[models.stages.plan]\nmodel = \"x\"\n\n[[ci.checks]]\nname = \"t\"\ncommand = \"\"\"\njust test\n\"\"\"\n",
55
+ "expected": { "backend": "github", "team": null },
56
+ "provable": true
57
+ },
58
+ {
59
+ "name": "absent table",
60
+ "toml": "[workflow]\nbase = \"main\"\n",
61
+ "expected": { "backend": null, "team": null },
62
+ "provable": true
63
+ },
64
+ {
65
+ "name": "absent key",
66
+ "toml": "[issues]\nbackend = \"github\"\n",
67
+ "expected": { "backend": "github", "team": null },
68
+ "provable": true
69
+ },
70
+ {
71
+ "name": "non-string values (unproven: Python's boundary rejects them outright)",
72
+ "toml": "[issues]\nbackend = true\nteam = 42\n",
73
+ "expected": { "backend": null, "team": null },
74
+ "provable": false
75
+ },
76
+ {
77
+ "name": "empty document",
78
+ "toml": "",
79
+ "expected": { "backend": null, "team": null },
80
+ "provable": true
81
+ },
82
+ {
83
+ "name": "dotted keys (unproven: the subset reader never sees them)",
84
+ "toml": "issues.backend = \"linear\"\nissues.team = \"ENG\"\n",
85
+ "expected": { "backend": null, "team": null },
86
+ "tomllib": { "backend": "linear", "team": "ENG" },
87
+ "provable": false
88
+ },
89
+ {
90
+ "name": "inline table (unproven: the subset reader never sees it)",
91
+ "toml": "issues = { backend = \"linear\", team = \"ENG\" }\n",
92
+ "expected": { "backend": null, "team": null },
93
+ "tomllib": { "backend": "linear", "team": "ENG" },
94
+ "provable": false
95
+ },
96
+ {
97
+ "name": "quoted header (unproven: quoted segments can spell any key)",
98
+ "toml": "[\"issues\"]\nbackend = \"linear\"\nteam = \"ENG\"\n",
99
+ "expected": { "backend": null, "team": null },
100
+ "tomllib": { "backend": "linear", "team": "ENG" },
101
+ "provable": false
102
+ },
103
+ {
104
+ "name": "header with a trailing comment (unproven: the subset reader skips that header)",
105
+ "toml": "[issues] # routing\nbackend = \"linear\"\n",
106
+ "expected": { "backend": null, "team": null },
107
+ "tomllib": { "backend": "linear", "team": null },
108
+ "provable": false
109
+ },
110
+ {
111
+ "name": "unicode escape (unproven: the subset reader keeps the escape verbatim)",
112
+ "toml": "[issues]\nbackend = \"\\u0067ithub\"\n",
113
+ "expected": { "backend": "\\u0067ithub", "team": null },
114
+ "tomllib": { "backend": "github", "team": null },
115
+ "provable": false
116
+ },
117
+ {
118
+ "name": "sub-table (unproven: a super-table the subset reader keeps flat)",
119
+ "toml": "[issues.extra]\nkey = \"x\"\n",
120
+ "expected": { "backend": null, "team": null },
121
+ "provable": false
122
+ },
123
+ {
124
+ "name": "array of tables (unproven: tomllib reads a list, never the table)",
125
+ "toml": "[[issues]]\nbackend = \"linear\"\n",
126
+ "expected": { "backend": null, "team": null },
127
+ "provable": false
128
+ }
129
+ ]
130
+ }
@@ -251,6 +251,19 @@ stages:
251
251
  predecessors: [] # a deliberately isolated node — the dev-only audit component
252
252
  successors: []
253
253
 
254
+ - id: objective-refine
255
+ summary: Author an advisory refinement of a future objective node and save it as the node's marked comment (read-only).
256
+ mode: read-only
257
+ worktree: none # explores the invoking checkout as-is (dirty changes included); never provisions a predecessor checkout
258
+ doors: { warm: true, cold_local: true, cold_remote: false } # interactive local authoring (perk objective refine + /objective-refine)
259
+ run_id: { warm: keep, cold_local: mint, cold_remote: mint }
260
+ command: objective refine # dedicated seeded cold door + the warm /objective-refine command
261
+ requires: [github.objective] # an objective with a refinable future node must exist
262
+ reads: [github.objective, github.comments] # target selection + the node's existing marked refinement comment
263
+ writes: [github.comments, session.workflow-state, cache.session-data, cache.scratch] # the approved/human-authorized refinement comment upsert; the read-only `mode` append; objective_refinement_draft + the imported context artifact; run scratch
264
+ predecessors: [] # a deliberately isolated node — refinement never enters the executable plan graph (contracts.md §8.67)
265
+ successors: []
266
+
254
267
  - id: stack-review
255
268
  summary: Review a stacked PR train in the plannotator browser with judgment-routed per-PR posting.
256
269
  mode: read-write # deliberate parity with the warm /stack-review-browser door — the
@@ -0,0 +1,318 @@
1
+ {
2
+ "$defs": {
3
+ "DescriptionEditOut": {
4
+ "additionalProperties": false,
5
+ "description": "One node-issue description edit; ``diff`` is untrusted DATA (null when the backend\nexposes no inline diff).",
6
+ "properties": {
7
+ "created_at": {
8
+ "title": "Created At",
9
+ "type": "string"
10
+ },
11
+ "author": {
12
+ "$ref": "#/$defs/EngagementAuthorOut"
13
+ },
14
+ "diff": {
15
+ "anyOf": [
16
+ {
17
+ "type": "string"
18
+ },
19
+ {
20
+ "type": "null"
21
+ }
22
+ ],
23
+ "title": "Diff"
24
+ }
25
+ },
26
+ "required": [
27
+ "created_at",
28
+ "author",
29
+ "diff"
30
+ ],
31
+ "title": "DescriptionEditOut",
32
+ "type": "object"
33
+ },
34
+ "EngagementAuthorOut": {
35
+ "additionalProperties": false,
36
+ "description": "The classified author of one engagement item (``kind`` + best-available label/id).",
37
+ "properties": {
38
+ "kind": {
39
+ "enum": [
40
+ "human",
41
+ "perk",
42
+ "other_agent",
43
+ "unknown"
44
+ ],
45
+ "title": "Kind",
46
+ "type": "string"
47
+ },
48
+ "display_name": {
49
+ "anyOf": [
50
+ {
51
+ "type": "string"
52
+ },
53
+ {
54
+ "type": "null"
55
+ }
56
+ ],
57
+ "title": "Display Name"
58
+ },
59
+ "id": {
60
+ "anyOf": [
61
+ {
62
+ "type": "string"
63
+ },
64
+ {
65
+ "type": "null"
66
+ }
67
+ ],
68
+ "title": "Id"
69
+ }
70
+ },
71
+ "required": [
72
+ "kind",
73
+ "display_name",
74
+ "id"
75
+ ],
76
+ "title": "EngagementAuthorOut",
77
+ "type": "object"
78
+ },
79
+ "EngagementCommentOut": {
80
+ "additionalProperties": false,
81
+ "description": "One node-issue comment; ``body`` is untrusted DATA.",
82
+ "properties": {
83
+ "id": {
84
+ "title": "Id",
85
+ "type": "string"
86
+ },
87
+ "body": {
88
+ "title": "Body",
89
+ "type": "string"
90
+ },
91
+ "created_at": {
92
+ "title": "Created At",
93
+ "type": "string"
94
+ },
95
+ "edited_at": {
96
+ "anyOf": [
97
+ {
98
+ "type": "string"
99
+ },
100
+ {
101
+ "type": "null"
102
+ }
103
+ ],
104
+ "title": "Edited At"
105
+ },
106
+ "author": {
107
+ "$ref": "#/$defs/EngagementAuthorOut"
108
+ }
109
+ },
110
+ "required": [
111
+ "id",
112
+ "body",
113
+ "created_at",
114
+ "edited_at",
115
+ "author"
116
+ ],
117
+ "title": "EngagementCommentOut",
118
+ "type": "object"
119
+ },
120
+ "NodeContextWarningOut": {
121
+ "additionalProperties": false,
122
+ "description": "One advisory failure: the ``surface`` that failed, a stable ``code``, a human\n``message``, and the carrier comment ids the outcome rests on.",
123
+ "properties": {
124
+ "surface": {
125
+ "enum": [
126
+ "engagement",
127
+ "refinement"
128
+ ],
129
+ "title": "Surface",
130
+ "type": "string"
131
+ },
132
+ "code": {
133
+ "title": "Code",
134
+ "type": "string"
135
+ },
136
+ "message": {
137
+ "title": "Message",
138
+ "type": "string"
139
+ },
140
+ "comment_ids": {
141
+ "items": {
142
+ "type": "string"
143
+ },
144
+ "title": "Comment Ids",
145
+ "type": "array"
146
+ }
147
+ },
148
+ "required": [
149
+ "surface",
150
+ "code",
151
+ "message",
152
+ "comment_ids"
153
+ ],
154
+ "title": "NodeContextWarningOut",
155
+ "type": "object"
156
+ },
157
+ "NodeRefinementPresentOut": {
158
+ "additionalProperties": false,
159
+ "description": "A saved refinement was read, rendered and written: ``file`` points at the full dated\n``<untrusted_node_refinement>`` block under the run scratch dir.",
160
+ "properties": {
161
+ "status": {
162
+ "const": "present",
163
+ "title": "Status",
164
+ "type": "string"
165
+ },
166
+ "file": {
167
+ "$ref": "#/$defs/TextFileRefOut"
168
+ }
169
+ },
170
+ "required": [
171
+ "status",
172
+ "file"
173
+ ],
174
+ "title": "NodeRefinementPresentOut",
175
+ "type": "object"
176
+ },
177
+ "NodeRefinementStatusOut": {
178
+ "additionalProperties": false,
179
+ "description": "No refinement pointer: none is saved (``absent``), the backend has no refinement read\n(``unsupported``), or the read/snapshot failed (``unavailable`` \u2014 see ``warnings``).",
180
+ "properties": {
181
+ "status": {
182
+ "enum": [
183
+ "absent",
184
+ "unsupported",
185
+ "unavailable"
186
+ ],
187
+ "title": "Status",
188
+ "type": "string"
189
+ }
190
+ },
191
+ "required": [
192
+ "status"
193
+ ],
194
+ "title": "NodeRefinementStatusOut",
195
+ "type": "object"
196
+ },
197
+ "TextFileRefOut": {
198
+ "additionalProperties": false,
199
+ "description": "One materialized text section: its absolute ``path`` plus the sizes a reviewer pages\nagainst \u2014 ``max_line_bytes`` is the longest line's UTF-8 length (compared against Pi's\nper-line ``read`` bound to pick the byte-slice fallback).",
200
+ "properties": {
201
+ "path": {
202
+ "title": "Path",
203
+ "type": "string"
204
+ },
205
+ "bytes": {
206
+ "title": "Bytes",
207
+ "type": "integer"
208
+ },
209
+ "lines": {
210
+ "title": "Lines",
211
+ "type": "integer"
212
+ },
213
+ "max_line_bytes": {
214
+ "title": "Max Line Bytes",
215
+ "type": "integer"
216
+ }
217
+ },
218
+ "required": [
219
+ "path",
220
+ "bytes",
221
+ "lines",
222
+ "max_line_bytes"
223
+ ],
224
+ "title": "TextFileRefOut",
225
+ "type": "object"
226
+ }
227
+ },
228
+ "additionalProperties": false,
229
+ "description": "The ``--json`` serialization boundary of a snapshotted :class:`NodeContext` (field order\nload-bearing; the pre-existing keys come first). ``refinement`` is discriminated on\n``status``: ``present`` always carries a ``file`` pointer \u2014 the file is on disk.",
230
+ "properties": {
231
+ "success": {
232
+ "title": "Success",
233
+ "type": "boolean"
234
+ },
235
+ "error_type": {
236
+ "anyOf": [
237
+ {
238
+ "type": "string"
239
+ },
240
+ {
241
+ "type": "null"
242
+ }
243
+ ],
244
+ "title": "Error Type"
245
+ },
246
+ "objective": {
247
+ "title": "Objective",
248
+ "type": "string"
249
+ },
250
+ "node": {
251
+ "title": "Node",
252
+ "type": "string"
253
+ },
254
+ "comments": {
255
+ "items": {
256
+ "$ref": "#/$defs/EngagementCommentOut"
257
+ },
258
+ "title": "Comments",
259
+ "type": "array"
260
+ },
261
+ "description_edits": {
262
+ "items": {
263
+ "$ref": "#/$defs/DescriptionEditOut"
264
+ },
265
+ "title": "Description Edits",
266
+ "type": "array"
267
+ },
268
+ "engagement_status": {
269
+ "enum": [
270
+ "present",
271
+ "absent",
272
+ "unavailable"
273
+ ],
274
+ "title": "Engagement Status",
275
+ "type": "string"
276
+ },
277
+ "refinement": {
278
+ "discriminator": {
279
+ "mapping": {
280
+ "absent": "#/$defs/NodeRefinementStatusOut",
281
+ "present": "#/$defs/NodeRefinementPresentOut",
282
+ "unavailable": "#/$defs/NodeRefinementStatusOut",
283
+ "unsupported": "#/$defs/NodeRefinementStatusOut"
284
+ },
285
+ "propertyName": "status"
286
+ },
287
+ "oneOf": [
288
+ {
289
+ "$ref": "#/$defs/NodeRefinementPresentOut"
290
+ },
291
+ {
292
+ "$ref": "#/$defs/NodeRefinementStatusOut"
293
+ }
294
+ ],
295
+ "title": "Refinement"
296
+ },
297
+ "warnings": {
298
+ "items": {
299
+ "$ref": "#/$defs/NodeContextWarningOut"
300
+ },
301
+ "title": "Warnings",
302
+ "type": "array"
303
+ }
304
+ },
305
+ "required": [
306
+ "success",
307
+ "error_type",
308
+ "objective",
309
+ "node",
310
+ "comments",
311
+ "description_edits",
312
+ "engagement_status",
313
+ "refinement",
314
+ "warnings"
315
+ ],
316
+ "title": "ObjectiveNodeEngagementOut",
317
+ "type": "object"
318
+ }
@@ -2,7 +2,7 @@
2
2
  "$defs": {
3
3
  "ContinuationOut": {
4
4
  "additionalProperties": false,
5
- "description": "This lineage's pending sync-continuation manifest (contracts.md \u00a78.44/\u00a78.49) \u2014 a\nmachine-local CLI-side observation. ``parseable: false`` rows carry nulls for every\nfield the unreadable file cannot account for.",
5
+ "description": "This lineage's pending sync-continuation manifest (contracts.md \u00a78.44/\u00a78.49) \u2014 a\nmachine-local CLI-side observation. ``parseable: false`` rows carry nulls for every\nfield the unreadable file cannot account for. ``targets_contained`` is additive trailing\ngrowth (\u00a78.44/\u00a78.51): whether the manifest's named targets pass the canonical\n``continuation.validated_targets`` containment validation against the configured worktree\nroot \u2014 the warm conflict dispatch requires it ``true`` (version skew fails closed: an\nolder CLI omits the field and the warm side refuses to dispatch).",
6
6
  "properties": {
7
7
  "operation_id": {
8
8
  "anyOf": [
@@ -66,6 +66,11 @@
66
66
  "parseable": {
67
67
  "title": "Parseable",
68
68
  "type": "boolean"
69
+ },
70
+ "targets_contained": {
71
+ "default": false,
72
+ "title": "Targets Contained",
73
+ "type": "boolean"
69
74
  }
70
75
  },
71
76
  "required": [
@@ -1,6 +1,45 @@
1
1
  {
2
+ "$defs": {
3
+ "DiffSource": {
4
+ "enum": [
5
+ "github",
6
+ "local-git"
7
+ ],
8
+ "type": "string"
9
+ },
10
+ "TextFileRefOut": {
11
+ "additionalProperties": false,
12
+ "description": "One materialized text section: its absolute ``path`` plus the sizes a reviewer pages\nagainst \u2014 ``max_line_bytes`` is the longest line's UTF-8 length (compared against Pi's\nper-line ``read`` bound to pick the byte-slice fallback).",
13
+ "properties": {
14
+ "path": {
15
+ "title": "Path",
16
+ "type": "string"
17
+ },
18
+ "bytes": {
19
+ "title": "Bytes",
20
+ "type": "integer"
21
+ },
22
+ "lines": {
23
+ "title": "Lines",
24
+ "type": "integer"
25
+ },
26
+ "max_line_bytes": {
27
+ "title": "Max Line Bytes",
28
+ "type": "integer"
29
+ }
30
+ },
31
+ "required": [
32
+ "path",
33
+ "bytes",
34
+ "lines",
35
+ "max_line_bytes"
36
+ ],
37
+ "title": "TextFileRefOut",
38
+ "type": "object"
39
+ }
40
+ },
2
41
  "additionalProperties": false,
3
- "description": "The ``--json`` serialization boundary of :class:`PrReviewContextResult`\n(flat; field order load-bearing). ``pr`` maps from the domain ``pr_number``.",
42
+ "description": "The ``--json`` serialization boundary of :class:`PrReviewContextResult` \u2014 a pointer\nenvelope (field order load-bearing). ``pr`` maps from the domain ``pr_number``; ``body``,\n``diff`` and ``plan_body`` are file references into ``context_dir`` (in stack mode they\nalias the LAST ``stack[]`` member's files \u2014 the top PR's text is written once).",
4
43
  "properties": {
5
44
  "success": {
6
45
  "title": "Success",
@@ -48,24 +87,28 @@
48
87
  "title": "Title",
49
88
  "type": "string"
50
89
  },
51
- "body": {
52
- "title": "Body",
90
+ "context_dir": {
91
+ "title": "Context Dir",
53
92
  "type": "string"
54
93
  },
94
+ "body": {
95
+ "$ref": "#/$defs/TextFileRefOut"
96
+ },
55
97
  "diff": {
56
- "title": "Diff",
57
- "type": "string"
98
+ "$ref": "#/$defs/TextFileRefOut"
58
99
  },
59
100
  "plan_body": {
60
101
  "anyOf": [
61
102
  {
62
- "type": "string"
103
+ "$ref": "#/$defs/TextFileRefOut"
63
104
  },
64
105
  {
65
106
  "type": "null"
66
107
  }
67
- ],
68
- "title": "Plan Body"
108
+ ]
109
+ },
110
+ "diff_source": {
111
+ "$ref": "#/$defs/DiffSource"
69
112
  }
70
113
  },
71
114
  "required": [
@@ -77,9 +120,11 @@
77
120
  "base_ref",
78
121
  "head_ref",
79
122
  "title",
123
+ "context_dir",
80
124
  "body",
81
125
  "diff",
82
- "plan_body"
126
+ "plan_body",
127
+ "diff_source"
83
128
  ],
84
129
  "title": "PrReviewContextOut",
85
130
  "type": "object"