@pmelab/gtd 43.0.0 → 45.0.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 (46) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +33 -13
  3. package/dist/chunks/{reserved-COEMFEpy.mjs → reserved-ty1mtlnS.mjs} +155 -3
  4. package/dist/chunks/review-BmoH-9im.mjs +408 -0
  5. package/dist/chunks/{tail-C_xn8U7U.mjs → tail-CM3sVoAb.mjs} +3 -3
  6. package/dist/workflow-kit.mjs +22 -10
  7. package/dist/workflows/cleanup.mjs +2 -2
  8. package/dist/workflows/feature.mjs +6 -278
  9. package/dist/workflows/fix.mjs +2 -2
  10. package/dist/workflows/review.mjs +27 -7
  11. package/dist/workflows/rollout.mjs +1 -1
  12. package/dist/workflows.mjs +379 -66
  13. package/package.json +1 -1
  14. package/src/steering/FORMATS.md +4 -4
  15. package/src/workflow-kit/review.test.ts +80 -2
  16. package/src/workflow-kit/review.ts +45 -11
  17. package/src/workflows/feature/coverage.ts +1 -1
  18. package/src/workflows/feature/feature.test.ts +8 -0
  19. package/src/workflows/feature/feature.ts +2 -2
  20. package/src/workflows/feature/index.ts +1 -1
  21. package/src/workflows/feature/refactor.ts +1 -1
  22. package/src/workflows/feature/review-answers.feature +12 -3
  23. package/src/workflows/feature/seam.ts +1 -1
  24. package/src/workflows/feature/standards.feature +286 -0
  25. package/src/workflows/feature/steps.test.ts +2 -64
  26. package/src/workflows/feature/steps.ts +5 -41
  27. package/src/workflows/fix/fix.feature +20 -21
  28. package/src/workflows/index.ts +1 -1
  29. package/src/workflows/review/review-door.feature +158 -0
  30. package/src/workflows/review/review.test.ts +1 -73
  31. package/src/workflows/review/review.ts +34 -6
  32. package/src/workflows/shared/learn.test.ts +154 -0
  33. package/src/workflows/shared/learn.ts +206 -0
  34. package/src/workflows/shared/options.ts +1 -0
  35. package/src/workflows/{feature → shared}/review.test.ts +4 -8
  36. package/src/workflows/{feature → shared}/review.ts +23 -10
  37. package/src/workflows/shared/skills.test.ts +2 -0
  38. package/src/workflows/shared/skills.ts +2 -0
  39. package/src/workflows/shared/standards.test.ts +90 -0
  40. package/src/workflows/shared/standards.ts +156 -0
  41. package/src/workflows/shared/steps.test.ts +64 -2
  42. package/src/workflows/shared/steps.ts +40 -1
  43. package/src/workflows/shared/tail.ts +2 -2
  44. package/src/workflows/shared/text.test.ts +58 -1
  45. package/src/workflows/shared/text.ts +39 -1
  46. package/src/workflows/shared/vars.ts +2 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gtd",
3
- "version": "43.0.0",
3
+ "version": "45.0.0",
4
4
  "description": "Drive the gtd loop inside Claude Code: agent turns run as subagents, gtd decides every beat",
5
5
  "author": {
6
6
  "name": "Philipp Melab"
package/README.md CHANGED
@@ -564,6 +564,22 @@ noted in steps 3 and 4 below.
564
564
  `gtd judge answer` / conservative-default shape as step 3's own judged
565
565
  points.
566
566
 
567
+ **The review learns your taste.** Each won't-fix and each own answer is a
568
+ candidate standard. A judge (`build.review.standards.judge`) asks whether it
569
+ is reusable beyond this note; at `standardMinP` (`0.8`) or above it is kept
570
+ in `.gtd/STANDARDS.md` with no question asked, and the next review lists it
571
+ under `## Standards added`. Every later agent turn — the lenses, the naive
572
+ pass, the build, every fix — is handed the kept standards, so a finding you
573
+ rejected once is not raised again and a rule you wrote is followed, in this
574
+ process and every later one. One the judge does not confidently rule out
575
+ contradicting a standard already kept is not applied: it waits under
576
+ `## Undecided` and becomes a `## Standard conflict <id>` note in the review,
577
+ with its own three boxes — **keep the new one (drop the old)**, **keep the
578
+ old one (discard the new)**, or **your own wording**, which replaces both —
579
+ and the review does not sign off until it is answered. `.gtd/STANDARDS.md` is
580
+ committed and yours to edit; gtd rewrites it as one bullet per standard when
581
+ it learns.
582
+
567
583
  You never talk to it. Every exchange is a file in `.gtd/` that you edit in your
568
584
  own editor, and every answer you give is a commit. Your test suite is the gate
569
585
  throughout: a red baseline stops the process before it starts, and a red build
@@ -588,24 +604,28 @@ the agent may overturn the answer. See
588
604
  for its `ui:` settings.
589
605
 
590
606
  The bundled workflows are named `feature` (the ordinary start above), `review`
591
- and `fix`. They are independent: `review` and `fix` never plan, and they meet
592
- only in `.gtd/REVIEW.md`. Each brings its own door. This command:
607
+ and `fix`. `review` and `fix` never plan. Each brings its own door. This
608
+ command:
593
609
 
594
610
  ```bash
595
611
  gtd door review <commitish>
596
612
  ```
597
613
 
598
- starts a pure review of everything from `<commitish>` to HEAD. It goes straight
599
- to the quality lap and a review, with no planning and no building; unlike
600
- `feature`, its lap fixes every finding and a reviewer turn
601
- (`build.review.reviewing`) writes `.gtd/REVIEW.md`, risks and all. Sign off and
602
- it closes. Leave notes and the process ends with `.gtd/REVIEW.md` (and the
603
- reviewer's original, `.gtd/REVIEW.orig.md`) left for `gtd door fix`. Until `fix`
604
- consumes them, starting `feature` or `review` is refused; remove both files to
605
- abandon the hand-off. `gtd door fix` fixes those notes and every `Risk:` in one
606
- turn, then asks for your review of the fix. With no review waiting, it repairs a
607
- red baseline as its own reviewed commit instead. `gtd doors` lists the doors of
608
- the workflows your `gtd.config.ts` exports, plus any it adds.
614
+ starts a review of everything from `<commitish>` to HEAD — the same review a
615
+ `feature` process ends with, minus planning and building. A green gate, then the
616
+ quality lenses: mechanical findings are fixed, noise is dropped, and the rest
617
+ become notes in `.gtd/REVIEW.md`, one tick box each. Tick `fix as suggested` or
618
+ write your own answer and the process fixes it in place — your own answers that
619
+ ask for a change are collected into `.gtd/REQUIREMENTS.md` and built by one
620
+ `feedback.fixing` turn, with no design phase and no criteria — under the health
621
+ loop, then asks for your review again. Sign off (or tick `won't fix`) and it
622
+ closes; nothing is left behind. A note asking for new behaviour belongs in a
623
+ `feature` process: tick `won't fix` and start one. `gtd door fix` repairs a red
624
+ baseline as its own reviewed commit; a note at its review is left in
625
+ `.gtd/REVIEW.md` (beside the reviewer's original, `.gtd/REVIEW.orig.md`) for the
626
+ next `gtd door fix`, and until that runs, starting `feature` or `review` is
627
+ refused — remove both files to abandon the hand-off. `gtd doors` lists the doors
628
+ of the workflows your `gtd.config.ts` exports, plus any it adds.
609
629
  `gtd --workflow <name>` starts any workflow by name.
610
630
 
611
631
  The workflow itself is a plain async TypeScript function, and the
@@ -113,6 +113,108 @@ const requireFlag = (workflow, registryPath, name, defaultOn) => {
113
113
  if (entry.defaultOn !== defaultOn) return refuse(defaultOn ? `gtd: ${workflow}: flag "${name}" is not default-on — roll it out first` : `gtd: ${workflow}: flag "${name}" is already default-on`);
114
114
  };
115
115
  //#endregion
116
+ //#region src/workflows/shared/standards.ts
117
+ const STANDARDS = ".gtd/STANDARDS.md";
118
+ const UNDECIDED = "Undecided";
119
+ const oneLine = (text) => text.replace(/[\s\x00-\x1f\x7f-\x9f\u2028\u2029]+/g, " ").trim();
120
+ const ITEM = /^(?:[-*+]|\d+[.)])\s+(.*)$/;
121
+ const CONTRADICTS = /^\s+[-*+]\s+contradicts:\s*(.*)$/i;
122
+ const wrapped = (item, line) => {
123
+ const olds = item.olds;
124
+ if (olds !== void 0 && olds.length > 0) olds[olds.length - 1] += ` ${line.trim()}`;
125
+ else item.text += ` ${line.trim()}`;
126
+ };
127
+ /** What tells two standards apart: not the emphasis or spacing a formatter may rewrite. */
128
+ const standardKey = (text) => oneLine(text.replace(/[*_`\\]/g, "")).toLowerCase();
129
+ const toStandards = (items) => {
130
+ const seen = /* @__PURE__ */ new Set();
131
+ const fresh = (text) => {
132
+ const key = standardKey(text);
133
+ if (key === "" || seen.has(key)) return false;
134
+ seen.add(key);
135
+ return true;
136
+ };
137
+ const decided = items.filter((i) => i.olds === void 0).map((i) => oneLine(i.text));
138
+ const undecided = items.flatMap((i) => i.olds === void 0 ? [] : [{
139
+ text: oneLine(i.text),
140
+ olds: i.olds.map(oneLine).filter((o) => o !== "")
141
+ }]);
142
+ return {
143
+ decided: decided.filter(fresh),
144
+ undecided: undecided.filter((c) => fresh(c.text))
145
+ };
146
+ };
147
+ /**
148
+ * Every top-level bullet is one standard, those under `## Undecided` waiting
149
+ * on the human; a hand-edited file may group the rest under any heading.
150
+ */
151
+ const parseStandards = (text) => {
152
+ const items = [];
153
+ let pending = false;
154
+ let last;
155
+ for (const line of text.split("\n")) {
156
+ const heading = /^(#{1,6})\s+(.*)$/.exec(line);
157
+ const item = ITEM.exec(line);
158
+ const old = CONTRADICTS.exec(line);
159
+ if (heading !== null) {
160
+ pending = heading[1].length > 1 && heading[2].trim() === UNDECIDED;
161
+ last = void 0;
162
+ } else if (item !== null) {
163
+ last = pending ? {
164
+ text: item[1],
165
+ olds: []
166
+ } : { text: item[1] };
167
+ items.push(last);
168
+ } else if (old !== null && last?.olds !== void 0) last.olds.push(old[1]);
169
+ else if (/^\s+\S/.test(line) && last !== void 0) wrapped(last, line);
170
+ else if (line.trim() !== "") last = void 0;
171
+ }
172
+ return toStandards(items);
173
+ };
174
+ const renderStandards = ({ decided, undecided }) => {
175
+ return `${[
176
+ "# Standards",
177
+ "Kept from your review answers for every agent turn. One standard per bullet.",
178
+ ...decided.length === 0 ? [] : [decided.map((s) => `- ${s}`).join("\n")],
179
+ ...undecided.length === 0 ? [] : [`## ${UNDECIDED}`, undecided.map((c) => [`- ${c.text}`, ...c.olds.map((o) => ` - contradicts: ${o}`)].join("\n")).join("\n")]
180
+ ].join("\n\n")}\n`;
181
+ };
182
+ const hash = (raw) => {
183
+ const text = standardKey(raw);
184
+ let h = 2166136261;
185
+ for (let i = 0; i < text.length; i++) h = Math.imul(h ^ text.charCodeAt(i), 16777619);
186
+ return (h >>> 0).toString(16).padStart(8, "0");
187
+ };
188
+ const CONFLICT_TITLE = /^Standard conflict ([0-9a-f]{8})$/;
189
+ const conflictTitle = (c) => `Standard conflict ${hash(c.text)}`;
190
+ const conflictFor = (standards, title) => {
191
+ const id = CONFLICT_TITLE.exec(title)?.[1];
192
+ return id === void 0 ? void 0 : standards.undecided.find((c) => hash(c.text) === id);
193
+ };
194
+ const isConflictTitle = (title) => CONFLICT_TITLE.test(title);
195
+ const KEEP_NEW = "keep the new one (drop the old)";
196
+ const KEEP_OLD = "keep the old one (discard the new)";
197
+ /** A conflict's chunk body; its three boxes read as fix / won't fix / own answer by position. */
198
+ const conflictBody = (c) => [...c.olds.length === 0 ? [`A standard learned from your answers contradicted ones another answer since replaced in \`${STANDARDS}\`. Keep it, discard it, or reword it.`, `New: ${c.text}`] : [
199
+ `A standard learned from your answers contradicts ${c.olds.length === 1 ? "one" : "some"} already in \`${STANDARDS}\`. Your own answer replaces both with its wording.`,
200
+ `New: ${c.text}`,
201
+ `Old:\n\n${c.olds.map((o) => `- ${o}`).join("\n")}`
202
+ ], `${ANSWER_LEAD}\n\n- [ ] ${KEEP_NEW}\n- [ ] ${KEEP_OLD}\n- [ ] ${FREE_TEXT_PLACEHOLDER}`].join("\n\n");
203
+ /** What every agent turn is told while `.gtd/STANDARDS.md` holds decided standards. */
204
+ const standardsBlock = (text) => {
205
+ const { decided } = parseStandards(text ?? "");
206
+ if (decided.length === 0) return "";
207
+ return `## Standards
208
+
209
+ \`${STANDARDS}\` holds the standards the human set in earlier reviews.
210
+ Follow every one in what you write. Reviewing, never raise a finding a
211
+ standard rules out — a \`Won't fix:\` standard is a finding the human
212
+ rejected, so never raise it or one like it again — and raise breaking a
213
+ standard as a finding.
214
+
215
+ ${decided.map((s) => `- ${s}`).join("\n")}`;
216
+ };
217
+ //#endregion
116
218
  //#region src/workflows/shared/vars.ts
117
219
  /** The refactor guard's fixed list, and `seamAllow`'s default minus `.gtd/**`. */
118
220
  const testFileGlobs = [
@@ -132,6 +234,7 @@ const defaults = {
132
234
  reviewNoteActionable: "0.7",
133
235
  reviewSeverityMinP: "0.7",
134
236
  qualityTriageMinP: "0.7",
237
+ standardMinP: "0.8",
135
238
  refactorFlagPattern: "\\bGTD_FLAG_\\w+",
136
239
  seamAllow: [...testFileGlobs, ".gtd/**"].join(", "),
137
240
  flagMode: "true",
@@ -391,8 +494,11 @@ const withSkills = (skills, prompt) => {
391
494
  };
392
495
  /** An `agent()` step whose prompt opens with the preamble naming its scope's skills, then its restricted file access. */
393
496
  const agentWithSkills = (name, prompt, options = {}) => {
394
- const access = accessPreamble(accessFor(name, options.file));
395
- const body = access === "" ? prompt : `${access}\n\n${prompt}`;
497
+ const body = [
498
+ accessPreamble(accessFor(name, options.file)),
499
+ prompt,
500
+ standardsBlock(read(STANDARDS))
501
+ ].filter((part) => part !== "").join("\n\n");
396
502
  return agent(name, withSkills(skillsFor(name).join(", "), body), options);
397
503
  };
398
504
  const unwindFailure = (commit) => `gtd could not unwind ${commit} out of your working tree.`;
@@ -432,6 +538,7 @@ const SUMMARY_TITLES = [
432
538
  "Weakened scenarios",
433
539
  "Fixed from your notes",
434
540
  "Fixed automatically",
541
+ "Standards added",
435
542
  "Dropped as noise",
436
543
  "Nothing to note"
437
544
  ];
@@ -452,6 +559,8 @@ const composedReview = (base, report) => {
452
559
  };
453
560
  const chunk = (title, body) => `## ${title}\n\n${body.trim()}`;
454
561
  const answerBoxes = `${ANSWER_LEAD}\n\n- [ ] ${ANSWER_FIX}\n- [ ] ${ANSWER_WONT_FIX}\n- [ ] ${FREE_TEXT_PLACEHOLDER}`;
562
+ const conflicts = (report.standards?.undecided ?? []).map((c) => chunk(unique(conflictTitle(c)), conflictBody(c)));
563
+ const added = report.standards?.added ?? [];
455
564
  const notes = report.notes.map((n) => ({
456
565
  ...n,
457
566
  title: unique(n.title)
@@ -460,8 +569,10 @@ const composedReview = (base, report) => {
460
569
  const chunks = [
461
570
  ...report.nitFix === void 0 ? [] : [chunk("Fixed from your notes", `Your nits and fix-as-suggested notes were worked on in ${short(report.nitFix)}; the notes you answered are left out — check the diff.`)],
462
571
  ...weakened.length === 0 ? [] : [chunk("Weakened scenarios", `These scenarios lost an assertion the review base had:\n\n${weakened.join("\n")}`)],
572
+ ...conflicts,
463
573
  ...notes.map((n) => chunk(n.title, `${n.unresolved === true ? `_The fixer left this unresolved._\n\n${unboxed(n.body)}` : n.unclear === true ? `_A fix turn removed this while renaming another finding — check whether it was fixed._\n\n${unboxed(n.body)}` : unboxed(n.body) || "_No detail given._"}\n\n${answerBoxes}`)),
464
574
  ...report.fixed.length === 0 ? [] : [chunk("Fixed automatically", report.fixed.map((f) => `- ${f.title} (${short(f.commit)})`).join("\n"))],
575
+ ...added.length === 0 ? [] : [chunk("Standards added", `Learned from your answers and kept in \`${STANDARDS}\`:\n\n${added.map((s) => `- ${s}`).join("\n")}`)],
465
576
  ...report.noise.length === 0 ? [] : [chunk("Dropped as noise", report.noise.map((f) => `- ${f.title} (p=${f.p})`).join("\n"))]
466
577
  ];
467
578
  const body = chunks.length > 0 ? chunks : [chunk("Nothing to note", "No quality lens raised anything for you — or none ran. Review the diff yourself.")];
@@ -978,6 +1089,15 @@ ${notes.length === 0 ? "(none)\n" : notesCapture(notes)}
978
1089
  The reviewer's risks are:
979
1090
 
980
1091
  ${risks.length === 0 ? "(none)\n" : notesCapture(risks)}`;
1092
+ const reviewFeedbackFixPrompt = () => `${stateFileRules}
1093
+ - Read \`.gtd/REQUIREMENTS.md\` — the concerns the human's review asked for,
1094
+ one \`## \` heading each, in build order
1095
+ - Build every concern in this one turn; an answered question is context,
1096
+ not a concern
1097
+ - Where a change is behavioural, add a test that fails without it
1098
+ - Leave \`.gtd/REQUIREMENTS.md\` untouched — the next step removes it
1099
+ - Leave everything uncommitted and finish your turn
1100
+ `;
981
1101
  const buildReviewReviewMissingMessage = (commit) => `The review round committed no \`.gtd/REVIEW.md\` (at ${commit}), so there is
982
1102
  nothing to sign off on.
983
1103
 
@@ -1606,6 +1726,36 @@ const awaitReview = (base, message = buildReviewAwaitReviewMessage(base)) => hum
1606
1726
  base,
1607
1727
  acceptClean: true
1608
1728
  });
1729
+ /** Answer every `question` note inline in `.gtd/REVIEW.md`. */
1730
+ const answerReviewQuestions = (notes) => agentWithSkills("review.answer-review-questions", buildReviewAnswerQuestionsPrompt(notes), {
1731
+ label: "Answering your questions",
1732
+ file: REVIEW,
1733
+ mode: "review",
1734
+ model: planner(),
1735
+ system: reviewerSystem()
1736
+ });
1737
+ /** Fix every `nit` note in one turn. */
1738
+ const fixNits = (notes, access, rules) => {
1739
+ const fixing = (name) => agentWithSkills(name, buildReviewFixNitsPrompt(notes, rules), {
1740
+ label: "Fixing your nits",
1741
+ file: REVIEW,
1742
+ model: planner(),
1743
+ system: reviewerSystem()
1744
+ });
1745
+ return access === void 0 ? fixing("review.fix.nits.fixing") : scope({
1746
+ name: "review.fix.nits",
1747
+ access
1748
+ }, () => fixing("fixing"));
1749
+ };
1750
+ /** Turn the review round `capture` describes into `.gtd/REQUIREMENTS.md`, or change nothing. */
1751
+ const collecting = (capture, round) => agentWithSkills("review.collecting", buildReviewCollectingPrompt(capture, void 0, round), {
1752
+ label: "Collecting your feedback",
1753
+ file: REQUIREMENTS,
1754
+ mode: "qa",
1755
+ model: planner(),
1756
+ system: reviewerSystem(),
1757
+ allowEmpty: true
1758
+ });
1609
1759
  /** The round at commit `round` left no `.gtd/REVIEW.md`. */
1610
1760
  const reviewMissing = (round) => human("review.review-missing", {
1611
1761
  message: buildReviewReviewMissingMessage(round),
@@ -1726,6 +1876,7 @@ const ShippedOptions = Struct({
1726
1876
  reviewNoteActionable: setting,
1727
1877
  reviewSeverityMinP: setting,
1728
1878
  qualityTriageMinP: setting,
1879
+ standardMinP: setting,
1729
1880
  refactorFlagPattern: setting,
1730
1881
  seamAllow: setting,
1731
1882
  sliceMaxCriteria: setting,
@@ -1802,6 +1953,7 @@ const skills = (vars) => {
1802
1953
  return {
1803
1954
  design: ["spec-driven-development", "planning-and-task-breakdown"],
1804
1955
  notes: ["incremental-implementation", "code-simplification"],
1956
+ feedback: ["test-driven-development", "incremental-implementation"],
1805
1957
  ...build,
1806
1958
  ...Object.fromEntries(Object.entries(build).map(([name, list]) => [`refactor.${name}`, list])),
1807
1959
  refactor: ["ponytail"],
@@ -1834,4 +1986,4 @@ const steering = {
1834
1986
  [REVIEW]: "review"
1835
1987
  };
1836
1988
  //#endregion
1837
- export { naivePassPrompt as $, agentWithSkills as A, coverageQuestion as B, fixCheck as C, envDefaults as Ct, reviewMissing as D, flipProblems as Dt, planner as E, flagReferences as Et, builderSystem as F, designTriagePrompt as G, criterionLine as H, clearCriteriaMessage as I, handOffAwaitReviewMessage as J, finisherSystem as K, clearCriteriaQuestion as L, buildReviewCollectingPrompt as M, buildReviewFixNitsPrompt as N, reviewQuality as O, registryEntry as Ot, buildReviewTriageMessage as P, naiveApplyFailure as Q, composedReview as R, coder as S, defaults as St, fixRisks as T, flagMentions as Tt, designGateAnswerMessage as U, coveringPrompt as V, designSystem as W, implementBuildingPrompt as X, idleMessage as Y, implementFixPrompt as Z, REFACTOR_NOTE as _, slicingPrompt as _t, flagModeOn as a, refactorBuildingPrompt as at, SLICES as b, unwindFailedMessage as bt, baseline as c, refactorNotePrompt as ct, guarded as d, reviewEditsCapture as dt, normaliseCriteriaScript as et, healthy as f, reviewGateBlockedMessage as ft, REFACTOR as g, seamSteerMessage as gt, QUALITY as h, seamByHandMessage as ht, skills as i, qualityUnresolvedMessage as it, buildReviewAnswerQuestionsPrompt as j, reviewing as k, requireFlag as kt, escalation as l, refactorRules as lt, HANDOFF as m, reviewerSystem as mt, summary as n, qualityFindingsFile as nt, flagShipped as o, refactorDroppedRefusal as ot, FEEDBACK as p, reviewNotesCapture as pt, fixReviewNotesPrompt as q, access as r, qualityTriageMessage as rt, shipped as s, refactorFixPrompt as st, steering as t, oversizedMessage as tt, gate as u, reviewEditNotesCapture as ut, REQUIREMENTS as v, startGateBlockedMessage as vt, fixQuality as w, testFileGlobs as wt, awaitReview as x, unwindFailure as xt, REVIEW as y, uncoveredMessage as yt, coverageMessage as z };
1989
+ export { naiveApplyFailure as $, reviewMissing as A, conflictTitle as At, coverageMessage as B, requireFlag as Bt, coder as C, unwindFailure as Ct, fixQuality as D, STANDARDS as Dt, fixNits as E, testFileGlobs as Et, buildReviewTriageMessage as F, standardKey as Ft, designSystem as G, coveringPrompt as H, builderSystem as I, flagMentions as It, fixReviewNotesPrompt as J, designTriagePrompt as K, clearCriteriaMessage as L, flagReferences as Lt, reviewing as M, oneLine as Mt, agentWithSkills as N, parseStandards as Nt, fixRisks as O, conflictBody as Ot, buildReviewCollectingPrompt as P, renderStandards as Pt, implementFixPrompt as Q, clearCriteriaQuestion as R, flipProblems as Rt, awaitReview as S, unwindFailedMessage as St, fixCheck as T, envDefaults as Tt, criterionLine as U, coverageQuestion as V, designGateAnswerMessage as W, idleMessage as X, handOffAwaitReviewMessage as Y, implementBuildingPrompt as Z, REFACTOR_NOTE as _, seamByHandMessage as _t, flagModeOn as a, qualityUnresolvedMessage as at, SLICES as b, startGateBlockedMessage as bt, baseline as c, refactorFixPrompt as ct, guarded as d, reviewEditNotesCapture as dt, naivePassPrompt as et, healthy as f, reviewEditsCapture as ft, REFACTOR as g, reviewerSystem as gt, QUALITY as h, reviewNotesCapture as ht, skills as i, qualityTriageMessage as it, reviewQuality as j, isConflictTitle as jt, planner as k, conflictFor as kt, escalation as l, refactorNotePrompt as lt, HANDOFF as m, reviewGateBlockedMessage as mt, summary as n, oversizedMessage as nt, flagShipped as o, refactorBuildingPrompt as ot, FEEDBACK as p, reviewFeedbackFixPrompt as pt, finisherSystem as q, access as r, qualityFindingsFile as rt, shipped as s, refactorDroppedRefusal as st, steering as t, normaliseCriteriaScript as tt, gate as u, refactorRules as ut, REQUIREMENTS as v, seamSteerMessage as vt, collecting as w, defaults as wt, answerReviewQuestions as x, uncoveredMessage as xt, REVIEW as y, slicingPrompt as yt, composedReview as z, registryEntry as zt };