@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,171 @@
1
+ // The change-publication feature (the submit half of the delivery pair), Pi-free.
2
+ //
3
+ // One entry point — `submitChange` — owns the ordering and failure semantics of publishing the
4
+ // active plan's change: external publish first, session-side updates ONLY on verified success
5
+ // (the implementation pointer, the reset-on-clean), then the bounded conflict follow-up
6
+ // decision. The composable internals (`publishVerified`, `decideConflictFollowUp`) are exported
7
+ // for the sibling address feature, whose conflict-decision timing is deliberately DIFFERENT
8
+ // (structural, not stylistic): `/submit` decides immediately after publish; `finalizeAddress`
9
+ // decides only after full corroborated resolve success — a resolve failure never burns an
10
+ // attempt.
11
+ //
12
+ // Ports are action-specific (never a DeliveryBackend/Git facade): `PublishChange` has exactly
13
+ // ONE production adapter — the `perk pr submit --json` cold-door composition in
14
+ // `pi/v1/delivery/submit.ts`, which also owns the `operation.notes` warning reports at
15
+ // publish-success time. Refusals (`planning_session`, `bad_input`) are adapter shapes — they
16
+ // never enter the outcome union.
17
+
18
+ /** The published-change facts — the structured `details` surface doubles as branch-safe
19
+ * persisted state. `issue` is the opaque string id the Python boundary sends (contracts §8.21). */
20
+ export interface PublishedChange {
21
+ pr: { number: number; url: string; is_draft: boolean; existed: boolean };
22
+ branch?: string;
23
+ issue?: string;
24
+ plan_embedded?: boolean;
25
+ /** The target branch the PR merges into (the conflict-resolver rebases onto it). */
26
+ base?: string;
27
+ /** Tri-state mergeability from the Python `git merge-tree` probe: true/false/null/absent. */
28
+ mergeable?: boolean | null;
29
+ /** The conflicted paths when `mergeable === false`; `[]` otherwise (advisory). */
30
+ conflicts?: string[];
31
+ /** `"stacked"` when the submit routed through the delivery publish operation (§8.47). */
32
+ delivery?: string;
33
+ /** The native-stack facts of a stacked submit (absent for the bottom layer). */
34
+ stack?: { number: number; size: number; position: number };
35
+ /** Lenient summary of an automatic suffix synchronization. */
36
+ operation?: {
37
+ kind: string;
38
+ operation_id: string | null;
39
+ no_op: boolean;
40
+ affected_count: number;
41
+ notes: string[];
42
+ };
43
+ }
44
+
45
+ /** One external publish attempt: the verified facts, or the adapter's soft failure. */
46
+ export type PublishAttempt =
47
+ | { ok: true; change: PublishedChange }
48
+ | { ok: false; message: string; errorType: string };
49
+
50
+ /** The publish port — ONE production adapter (`createChangePublisher`). */
51
+ export type PublishChange = (opts: { runId: string | null }) => Promise<PublishAttempt>;
52
+
53
+ /**
54
+ * The bounded conflict-attempt capability. `write` returns the persistence result (strict
55
+ * read-back / equal-value short-circuit true) — callers decide whether the boolean gates.
56
+ */
57
+ export interface ConflictAttempts {
58
+ read(): number;
59
+ write(next: number): boolean;
60
+ }
61
+
62
+ /**
63
+ * The bounded conflict-resolution re-drive cap: drive the resolver at most this many times.
64
+ * The counter behind it (`conflict_resolution_attempts`) is SHARED with `/objective-sync`'s
65
+ * retained-continuation conflict drive (delivery/stackConflict.ts) — submit- and sync-episode
66
+ * attempts deliberately share one bound, reset on any clean completion of either surface.
67
+ */
68
+ export const CONFLICT_RESOLUTION_ATTEMPT_CAP = 2;
69
+
70
+ /** The budget read: room for one more attempt (carrying the next attempt number), or spent. */
71
+ export type ConflictBudget =
72
+ | { kind: "available"; next: number; cap: number }
73
+ | { kind: "exhausted"; attempts: number };
74
+
75
+ /**
76
+ * The ONE cap/read comparison both conflict surfaces share (the submit/address decision here,
77
+ * the stack dispatch pipeline in `delivery/stackConflict.ts`). Deliberately read-only — the
78
+ * stack path interleaves its resolver claim between this inspect and its strict
79
+ * `attempts.write(next)`, whose read-back boolean each consumer passes through UNSOFTENED (a
80
+ * `false` means the counter is unverifiable, and an unverifiable counter must never bypass
81
+ * the cap — both consumers withhold the dispatch on it). A throwing counter read propagates
82
+ * (the 7.2-pinned load-bearing failure arm on the submit path; the stack pipeline's total
83
+ * boundary translates it to `state_error`).
84
+ */
85
+ export function inspectConflictBudget(attempts: ConflictAttempts): ConflictBudget {
86
+ const n = attempts.read();
87
+ if (n >= CONFLICT_RESOLUTION_ATTEMPT_CAP) return { kind: "exhausted", attempts: n };
88
+ return { kind: "available", next: n + 1, cap: CONFLICT_RESOLUTION_ATTEMPT_CAP };
89
+ }
90
+
91
+ /** The bounded conflict follow-up decision (surface translation stays adapter-side). */
92
+ export type ConflictFollowUp =
93
+ | { kind: "none" }
94
+ | { kind: "drive"; base: string; attempt: number; cap: number }
95
+ | { kind: "exhausted"; base: string; attempts: number }
96
+ /** The increment could not be persisted-and-verified — the dispatch is withheld (an
97
+ * unverifiable counter must never bypass the cap; surface-uniform with the stack path). */
98
+ | { kind: "withheld"; base: string };
99
+
100
+ export interface PublishDeps {
101
+ publish: PublishChange;
102
+ /** The adapter's DIRECT run-id read, invoked at publish time — AFTER any pre-effect refusal
103
+ * (the finalize empty-batch check) but BEFORE the external call, so a throwing branch read
104
+ * still fails before publication (today's parity); `""` ⇒ `null` is the adapter's job. */
105
+ readRunId: () => string | null;
106
+ /** CONTRACT: never throws; owns its own failure reporting (production:
107
+ * `captureSessionPointer` — best-effort + non-fatal, a successful publish must stand).
108
+ * Receives the run id `readRunId` returned for this publish. */
109
+ recordImplementationPointer: (runId: string) => void;
110
+ attempts: ConflictAttempts;
111
+ }
112
+
113
+ export type SubmitChangeOutcome =
114
+ | { kind: "publish_failed"; message: string; errorType: string }
115
+ | { kind: "published"; change: PublishedChange; conflict: ConflictFollowUp };
116
+
117
+ /**
118
+ * Publish the change, then apply the verified-success session updates. A failed publish returns
119
+ * as-is with NO session-side activity (no pointer, no counter read/write). On success: the
120
+ * implementation pointer is recorded iff the run id exists (no catch — the capability contract
121
+ * is never-throws), and the shared conflict counter resets on a clean (or undetermined) submit
122
+ * so a later independent conflict starts fresh. The reset's persistence result is deliberately
123
+ * unchecked — today's posture; the seam warns loudly on a read-back miss.
124
+ */
125
+ export async function publishVerified(deps: PublishDeps): Promise<PublishAttempt> {
126
+ const runId = deps.readRunId();
127
+ const attempt = await deps.publish({ runId });
128
+ if (!attempt.ok) return attempt;
129
+ if (runId !== null) deps.recordImplementationPointer(runId);
130
+ if (attempt.change.mergeable !== false && deps.attempts.read() !== 0) {
131
+ deps.attempts.write(0);
132
+ }
133
+ return attempt;
134
+ }
135
+
136
+ /**
137
+ * The bounded conflict follow-up decision for a published change: mergeable (or undetermined) ⇒
138
+ * `none`; at the cap ⇒ `exhausted` (no write); definitively unmergeable under the cap ⇒ the
139
+ * verified increment gates the drive — a `false` commit ⇒ `withheld` (the surface-uniform
140
+ * withhold posture: an unverifiable counter must never bypass the cap; the adapter reports
141
+ * loudly, no dispatch). A THROWING counter read/write still propagates — the 7.2-pinned
142
+ * load-bearing failure arm; only the `false` return changed posture.
143
+ */
144
+ export function decideConflictFollowUp(
145
+ change: PublishedChange,
146
+ attempts: ConflictAttempts,
147
+ ): ConflictFollowUp {
148
+ if (change.mergeable !== false) return { kind: "none" };
149
+ const base = change.base ?? "";
150
+ const budget = inspectConflictBudget(attempts);
151
+ if (budget.kind === "exhausted") return { kind: "exhausted", base, attempts: budget.attempts };
152
+ if (!attempts.write(budget.next)) return { kind: "withheld", base };
153
+ return { kind: "drive", base, attempt: budget.next, cap: budget.cap };
154
+ }
155
+
156
+ /**
157
+ * The one standalone-submit operation: external publish → verified-success session updates →
158
+ * the bounded conflict decision, taken immediately after publish (the standalone surface's
159
+ * structural timing; the address finalizer defers it until corroborated resolve success).
160
+ */
161
+ export async function submitChange(deps: PublishDeps): Promise<SubmitChangeOutcome> {
162
+ const attempt = await publishVerified(deps);
163
+ if (!attempt.ok) {
164
+ return { kind: "publish_failed", message: attempt.message, errorType: attempt.errorType };
165
+ }
166
+ return {
167
+ kind: "published",
168
+ change: attempt.change,
169
+ conflict: decideConflictFollowUp(attempt.change, deps.attempts),
170
+ };
171
+ }