@pmelab/gtd 56.0.0 → 57.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 +20 -27
  3. package/dist/chunks/{reserved-B8EC-WE8.mjs → reserved-X2RkNHin.mjs} +34 -116
  4. package/dist/chunks/{review-HdrX0FJ7.mjs → review-v7sh5GF4.mjs} +2 -2
  5. package/dist/chunks/{tail-BSLah2mA.mjs → tail-S04KEewi.mjs} +1 -1
  6. package/dist/workflows/cleanup.mjs +2 -2
  7. package/dist/workflows/feature.mjs +52 -162
  8. package/dist/workflows/fix.mjs +2 -2
  9. package/dist/workflows/review.mjs +3 -3
  10. package/dist/workflows/rollout.mjs +1 -1
  11. package/dist/workflows.mjs +81 -274
  12. package/package.json +1 -1
  13. package/src/workflows/feature/criteria-coverage.feature +0 -1
  14. package/src/workflows/feature/criteria.test.ts +1 -41
  15. package/src/workflows/feature/criteria.ts +2 -14
  16. package/src/workflows/feature/fast-path.feature +0 -1
  17. package/src/workflows/feature/feature.ts +5 -6
  18. package/src/workflows/feature/flag-mode.feature +1 -1
  19. package/src/workflows/feature/lens-models.feature +0 -1
  20. package/src/workflows/feature/lens-review.feature +0 -1
  21. package/src/workflows/feature/naive-test.feature +258 -0
  22. package/src/workflows/feature/one-step-land.feature +0 -1
  23. package/src/workflows/feature/refactor-absorbs.feature +0 -1
  24. package/src/workflows/feature/refactor-first.feature +0 -1
  25. package/src/workflows/feature/refactor-rebuild.feature +0 -1
  26. package/src/workflows/feature/refactor-review.feature +0 -1
  27. package/src/workflows/feature/review-gate.feature +1 -2
  28. package/src/workflows/feature/reviewer-walkthrough.feature +0 -1
  29. package/src/workflows/feature/seam-rejection.feature +0 -1
  30. package/src/workflows/feature/seam.feature +0 -1
  31. package/src/workflows/feature/seam.test.ts +1 -2
  32. package/src/workflows/feature/seam.ts +56 -10
  33. package/src/workflows/feature/standards.feature +0 -1
  34. package/src/workflows/shared/options.ts +9 -1
  35. package/src/workflows/shared/prose.ts +0 -6
  36. package/src/workflows/shared/skills.test.ts +0 -4
  37. package/src/workflows/shared/skills.ts +0 -5
  38. package/src/workflows/shared/steps.ts +1 -1
  39. package/src/workflows/shared/text.test.ts +22 -41
  40. package/src/workflows/shared/text.ts +42 -142
  41. package/src/workflows/shared/vars.ts +2 -3
  42. package/src/workflows/feature/hands-on-skip.feature +0 -316
  43. package/src/workflows/feature/prototype-rounds.feature +0 -156
  44. package/src/workflows/feature/prototype.feature +0 -428
  45. package/src/workflows/feature/prototype.test.ts +0 -43
  46. package/src/workflows/feature/prototype.ts +0 -198
@@ -1,8 +1,8 @@
1
- import { agent, answered, applyScript, changes, changesSince, check, codeChanges, env, hasThreadFor, head, human, judge, judgeDiffShape, kept, mark, matches, quote, read, refuse, removeScript, requireAnswers, requireProgress, requireReplies, requireThreadsClosed, revertScript, run, scope, start, vars, wrote } from "../flows.mjs";
1
+ import { agent, answered, applyScript, changes, changesSince, check, codeChanges, env, hasThreadFor, head, human, judge, judgeDiffShape, kept, mark, matches, quote, read, refuse, removeScript, requireAnswers, requireProgress, requireReplies, requireThreadsClosed, restoreScript, revertScript, run, scope, start, vars, wrote } from "../flows.mjs";
2
2
  import { lensEntriesOf } from "../workflow-kit.mjs";
3
- import { $ as normaliseCriteriaScript, B as designSystem, Ct as unwindFailedMessage, D as planner, Dt as defaults, F as clearCriteriaMessage, I as clearCriteriaQuestion, J as implementBuildingPrompt, L as criterionLine, M as buildReviewCollectingPrompt, Ot as envDefaults, P as builderSystem, R as designGateAnswerMessage, S as collecting, St as testerSystem, V as designTriagePrompt, X as naiveApplyFailure, Y as implementFixPrompt, Z as naivePassPrompt, _ as REQUIREMENTS, a as flagModeOn, at as prototypeUnguidedMessage, bt as seamSteerMessage, ct as refactorBuildingPrompt, d as healthy, dt as refactorNotePrompt, et as observableMessage, f as FEEDBACK, ft as refactorRules, g as REFACTOR_NOTE, h as REFACTOR, i as skills, it as prototypeTestingPrompt, j as agentWithSkills, kt as testFileGlobs, l as gate, lt as refactorDroppedRefusal, n as summary, nt as prototypeFixingPrompt, p as PROTOTYPE, q as idleMessage, r as access, rt as prototypeOpenMessage, s as shipped, t as steering, tt as observableQuestion, ut as refactorFixPrompt, vt as reviewerSystem, w as fixNits, wt as unwindFailure, x as coder, xt as startGateBlockedMessage, y as answerReviewQuestions, yt as seamByHandMessage, z as designImpactPrompt } from "../chunks/reserved-B8EC-WE8.mjs";
4
- import { a as refusePendingHandOff } from "../chunks/tail-BSLah2mA.mjs";
5
- import { n as isCode$1, r as reUnwind, t as buildTail } from "../chunks/review-HdrX0FJ7.mjs";
3
+ import { $ as naiveTryMessage, B as designImpactPrompt, C as collecting, Ct as envDefaults, F as builderSystem, H as designTriagePrompt, I as clearCriteriaMessage, J as idleMessage, L as clearCriteriaQuestion, M as agentWithSkills, N as buildReviewCollectingPrompt, O as planner, Q as naivePassPrompt, R as criterionLine, S as coder, St as defaults, T as fixNits, V as designSystem, X as implementFixPrompt, Y as implementBuildingPrompt, Z as naiveApplyFailure, _ as REFACTOR_NOTE, _t as startGateBlockedMessage, a as flagModeOn, at as refactorDroppedRefusal, b as answerReviewQuestions, c as shipped, ct as refactorRules, f as healthy, g as REFACTOR, gt as seamSteerMessage, ht as seamByHandMessage, i as skills, it as refactorBuildingPrompt, m as NAIVE_TEST, mt as reviewerSystem, n as summary, ot as refactorFixPrompt, p as FEEDBACK, r as access, s as naiveTestOn, st as refactorNotePrompt, t as steering, tt as normaliseCriteriaScript, u as gate, v as REQUIREMENTS, vt as unwindFailedMessage, wt as testFileGlobs, yt as unwindFailure, z as designGateAnswerMessage } from "../chunks/reserved-X2RkNHin.mjs";
4
+ import { a as refusePendingHandOff } from "../chunks/tail-S04KEewi.mjs";
5
+ import { n as isCode$1, r as reUnwind, t as buildTail } from "../chunks/review-v7sh5GF4.mjs";
6
6
  import { posix } from "node:path";
7
7
  //#region src/workflows/shared/fences.ts
8
8
  const markFenced = (text) => {
@@ -26,11 +26,10 @@ const ITEM = /^ ?(?:[-*+]|\d+[.)])\s+(?:\[[ xX]\]\s+)?(.*)$/;
26
26
  //#region src/workflows/feature/criteria.ts
27
27
  /** Below this the judge's `yes` is not trusted: a wrong skip builds against criteria nobody can check. */
28
28
  const CLEAR_MIN_P = .8;
29
- const ID = /^(AC-\d+)(\s*\(no hands-on\))?:\s*(.*)$/;
29
+ const ID = /^(AC-\d+):\s*(.*)$/;
30
30
  const criterion = (id, as = id[1]) => ({
31
31
  id: as,
32
- text: id[3],
33
- ...id[2] === void 0 ? {} : { noHandsOn: true }
32
+ text: id[2]
34
33
  });
35
34
  /** The list items under the first heading `title` matches (at `level` when given), up to the next heading; wrapped lines joined, fenced lines ignored. */
36
35
  const listUnder = (text, title, level) => {
@@ -67,11 +66,6 @@ const criteriaOf = (text) => listUnder(text, /^acceptance criteria$/i, 2)?.map((
67
66
  });
68
67
  /** The ID'd criteria of `text`. */
69
68
  const criterionIds = (text) => (criteriaOf(text) ?? []).map((c) => c.id).filter((id) => id !== "");
70
- /** The ID'd criteria of `text` a person can try by hand: none tagged `(no hands-on)`. */
71
- const handsOnIds = (text) => {
72
- const tagged = (criteriaOf(text) ?? []).filter((c) => c.noHandsOn).map((c) => c.id);
73
- return criterionIds(text).filter((id) => !tagged.includes(id));
74
- };
75
69
  /** Items numbered `AC-1`…, unless every one already carries its own distinct ID. */
76
70
  const numbered = (items) => {
77
71
  const ids = items.map((item) => ID.exec(item));
@@ -314,147 +308,6 @@ const green = () => healthy(() => agentWithSkills("fix.suite.fixing", implementF
314
308
  guardRests: false
315
309
  });
316
310
  //#endregion
317
- //#region src/workflows/feature/prototype.ts
318
- /** Only a `no` at this or above skips a criterion: no verdict, or an unsure one, sends it to the hands-on test. */
319
- const UNOBSERVABLE_MIN_P = .5;
320
- /** The `prototypeRounds` setting. Anything but a non-negative integer fails rather than guess a cap. */
321
- const prototypeRounds = () => {
322
- const value = vars.prototypeRounds ?? defaults.prototypeRounds;
323
- if (!/^(0|[1-9]\d*)$/.test(value)) refuse(`gtd: prototypeRounds must be a non-negative integer, got ${JSON.stringify(value)}`);
324
- return Number(value);
325
- };
326
- const CHUNK = /^(AC-\d+|Problem\b.*?)\s*:\s*(pass|fail|blocked)$/i;
327
- const UNGUIDED = /^no testing instructions$/i;
328
- /** The `## ` chunks of a prototype report; a heading in neither shape is prose, not an item. */
329
- const reportOf = (text) => {
330
- let unguided = false;
331
- const items = [];
332
- const malformed = [];
333
- for (const { line, fenced } of markFenced(text)) {
334
- const heading = fenced ? null : HEADING.exec(line);
335
- if (heading?.[1] !== "##") continue;
336
- if (UNGUIDED.test(heading[2])) unguided = true;
337
- const chunk = CHUNK.exec(heading[2]);
338
- if (chunk === null && /^(ac-\d|problem)/i.test(heading[2])) malformed.push(heading[2]);
339
- if (chunk !== null) items.push({
340
- subject: /^ac-/i.test(chunk[1]) ? chunk[1].toUpperCase() : chunk[1],
341
- verdict: chunk[2].toLowerCase()
342
- });
343
- }
344
- return {
345
- unguided,
346
- items,
347
- malformed
348
- };
349
- };
350
- /**
351
- * The report the testing turn left, refused unless it is the only change and
352
- * names each of `ids` once, with its open items: any other criterion is not
353
- * this test's to fix.
354
- */
355
- const requireReport = (ids, retest) => {
356
- const others = changes().map((c) => c.path).filter((path) => path !== PROTOTYPE);
357
- if (others.length > 0) refuse(`gtd land: prototype-report: test in a disposable place and change nothing but ${PROTOTYPE} — revert these:\n${others.map((path) => ` - ${path}`).join("\n")}`);
358
- const text = read(PROTOTYPE);
359
- if (text === void 0) return refuse(`gtd land: prototype-report: write ${PROTOTYPE}`);
360
- const report = reportOf(text);
361
- if (report.malformed.length > 0) refuse(`gtd land: prototype-report: head each chunk \`## <ID>: pass|fail|blocked\` or \`## Problem <title>: pass|fail|blocked\` — these miss it:\n${report.malformed.map((h) => ` - ${h}`).join("\n")}`);
362
- if (report.unguided && report.items.length === 0 && !retest) return {
363
- unguided: true,
364
- open: []
365
- };
366
- const elsewhere = criterionIds(read(".gtd/REQUIREMENTS.md") ?? "").filter((id) => !ids.includes(id));
367
- const count = (id) => report.items.filter((i) => i.subject === id).length;
368
- const wrong = ids.filter((id) => count(id) !== 1);
369
- if (wrong.length > 0) refuse(`gtd land: prototype-report: ${PROTOTYPE} needs exactly one chunk headed \`## <ID>: pass|fail|blocked\` for ${wrong.join(", ")}`);
370
- return {
371
- unguided: false,
372
- open: report.items.filter((i) => i.verdict !== "pass" && !elsewhere.includes(i.subject))
373
- };
374
- };
375
- /**
376
- * The criteria a person can observe by using the change, by the judge: those
377
- * tagged `(no hands-on)` are never asked about.
378
- */
379
- const observable = async () => {
380
- const requirements = read(".gtd/REQUIREMENTS.md") ?? "";
381
- const own = handsOnIds(requirements);
382
- const criteria = (criteriaOf(requirements) ?? []).filter((c) => own.includes(c.id));
383
- if (criteria.length === 0) return [];
384
- const { answers } = await judge("observable", {
385
- questions: criteria.map(observableQuestion),
386
- evidence: { requirements },
387
- message: observableMessage(),
388
- label: "Judging which criteria to test by hand"
389
- });
390
- return own.filter((id) => !answered(answers[id], "no", UNOBSERVABLE_MIN_P));
391
- };
392
- const frozen = () => requireCriteriaFrozen(REQUIREMENTS);
393
- const testing = async (ids, retest) => {
394
- await agentWithSkills("testing", prototypeTestingPrompt(criterionIds(read(".gtd/REQUIREMENTS.md") ?? "").filter((id) => !ids.includes(id)), retest), {
395
- label: retest ? "Re-testing the change by hand" : "Testing the change by hand",
396
- file: PROTOTYPE,
397
- model: coder(),
398
- system: testerSystem(),
399
- allowEmpty: true
400
- });
401
- return requireReport(ids, retest);
402
- };
403
- const fixing = async () => {
404
- await scope("fix", () => agentWithSkills("fixing", prototypeFixingPrompt(), {
405
- label: "Fixing what the hands-on test found",
406
- file: PROTOTYPE,
407
- model: coder(),
408
- system: builderSystem(),
409
- allowEmpty: true
410
- }));
411
- if (changes().some((c) => c.path === ".gtd/PROTOTYPE.md")) refuse(`gtd land: prototype-fix: leave ${PROTOTYPE} as it is — the next round re-tests from it`);
412
- frozen();
413
- };
414
- /** A person's rest; resolves `true` when they changed something to test again, `false` on a clean overrule. */
415
- const askPerson = async (name, message, label) => {
416
- await human(name, {
417
- message,
418
- label,
419
- file: PROTOTYPE,
420
- acceptClean: true
421
- });
422
- if (!changes().some((c) => c.path !== ".gtd/PROTOTYPE.md")) return false;
423
- frozen();
424
- return true;
425
- };
426
- /**
427
- * Use the change by hand: a testing turn reports on every criterion a person
428
- * can observe, a fix turn takes each failure, and the change is tested again —
429
- * until the report is clean, or `prototypeRounds` fixes are spent and a person
430
- * decides. A change with no such criterion is not tested by hand.
431
- */
432
- const prototypeTest = async () => {
433
- const cap = prototypeRounds();
434
- if (cap === 0) return;
435
- await scope("prototype", async () => {
436
- const ids = await observable();
437
- if (ids.length === 0) return;
438
- let fixes = 0;
439
- let retest = false;
440
- for (;;) {
441
- const { unguided, open } = await testing(ids, retest);
442
- retest = !unguided;
443
- if (unguided) {
444
- if (!await askPerson("unguided", prototypeUnguidedMessage(), "No way to test by hand")) return;
445
- } else if (open.length === 0) return;
446
- else if (fixes < cap && open.some((i) => i.verdict === "fail")) {
447
- fixes++;
448
- await fixing();
449
- } else {
450
- if (!await askPerson("open", prototypeOpenMessage(open, fixes), "Hands-on test still failing")) return;
451
- fixes = 0;
452
- }
453
- await green();
454
- }
455
- });
456
- };
457
- //#endregion
458
311
  //#region src/workflows/feature/refactor.ts
459
312
  const REFACTOR_PACKAGE = REFACTOR;
460
313
  const isCode = (path) => path !== ".gtd" && !path.startsWith(".gtd/");
@@ -825,13 +678,8 @@ const implementing = (options) => scope("implement", async () => {
825
678
  if (options.naive === void 0 || !await applied(options.naive)) await build(options);
826
679
  else requireCriteriaFrozen(REQUIREMENTS);
827
680
  await green();
828
- await prototypeTest();
829
681
  const ids = criterionIds(read(".gtd/REQUIREMENTS.md") ?? "");
830
- await run("closing", removeScript([
831
- REQUIREMENTS,
832
- REFACTOR_NOTE,
833
- PROTOTYPE
834
- ]), { label: "Closing out the implementation" });
682
+ await run("closing", removeScript([REQUIREMENTS, REFACTOR_NOTE]), { label: "Closing out the implementation" });
835
683
  return ids;
836
684
  });
837
685
  /** Resolves `true` when the human steered (edited), `false` on a clean overrule. */
@@ -899,6 +747,39 @@ const ruled = async (tip, again) => {
899
747
  tip
900
748
  } : next;
901
749
  };
750
+ /** Back to `before`: every code path, and the notes file. `.gtd/` edits (the requirements) stay. */
751
+ const untryScript = (before) => {
752
+ const code = changesSince(before).filter((c) => isCode$1(c.path));
753
+ return restoreScript(head(), {
754
+ restore: code.filter((c) => c.status !== "added").map((c) => c.path),
755
+ remove: [...code.filter((c) => c.status === "added").map((c) => c.path), NAIVE_TEST]
756
+ }, before);
757
+ };
758
+ /**
759
+ * A person tries the green pass `tip` in the working tree. Resolves
760
+ * `undefined` on a clean landing (signed off), else what they sent back;
761
+ * either way the pass, their code edits and the notes file leave the tree.
762
+ */
763
+ const tried = async (tip) => {
764
+ const before = head();
765
+ await run("applying", applyScript(tip.hash, FEEDBACK, naiveApplyFailure(tip.hash), [".gtd"]), { label: "Applying the naive pass to try it" });
766
+ await human("try", {
767
+ message: naiveTryMessage(flagModeOn()),
768
+ label: "Try the naive pass",
769
+ file: NAIVE_TEST,
770
+ acceptClean: true
771
+ });
772
+ const landed = changes();
773
+ const edits = landed.some((c) => isCode$1(c.path)) ? head() : void 0;
774
+ const notes = read(".gtd/NAIVE-TEST.md")?.trim() || void 0;
775
+ if (landed.some((c) => c.path === ".gtd/REQUIREMENTS.md")) requireCriteria(REQUIREMENTS);
776
+ await run("restoring", untryScript(before), { label: "Taking the naive pass out again" });
777
+ return landed.length === 0 ? void 0 : {
778
+ tested: tip.hash,
779
+ notes,
780
+ edits
781
+ };
782
+ };
902
783
  const decide = () => scope("seam", async () => {
903
784
  const vetting = {
904
785
  again: budget(),
@@ -908,7 +789,16 @@ const decide = () => scope("seam", async () => {
908
789
  for (;;) {
909
790
  await naivePass(retry);
910
791
  const tip = kept("naive");
911
- const outcome = await vetted(tip, vetting) ?? (flagModeOn() ? await ruled(tip, vetting.again) : {
792
+ const verdict = await vetted(tip, vetting);
793
+ if (verdict === void 0 && naiveTestOn()) {
794
+ const sentBack = await tried(tip);
795
+ if (sentBack !== void 0) {
796
+ vetting.again = budget();
797
+ retry = sentBack;
798
+ continue;
799
+ }
800
+ }
801
+ const outcome = verdict ?? (flagModeOn() ? await ruled(tip, vetting.again) : {
912
802
  reference: tip.hash,
913
803
  tip
914
804
  });
@@ -1070,7 +960,7 @@ const ordinaryStart = async () => {
1070
960
  });
1071
961
  refusePendingHandOff();
1072
962
  flagModeOn();
1073
- prototypeRounds();
963
+ naiveTestOn();
1074
964
  const stated = statedCriteria(changes(), head());
1075
965
  await unwind();
1076
966
  if (changes(".gtd/FEEDBACK.md").some((c) => c.status !== "deleted")) await human("unwind-failed", {
@@ -1086,4 +976,4 @@ const feature = shipped(ordinaryStart);
1086
976
  //#region src/workflows/feature/index.ts
1087
977
  var feature_default = feature;
1088
978
  //#endregion
1089
- export { COMMENT, REFACTOR_PACKAGE, acceptanceFault, access, afterTail, answerProductQuestions, answerReviewQuestions, buildFeature, buildTail, collecting, criteriaOf, criterionIds, feature_default as default, defaults, design, envDefaults, feature, fixNits, handsOnIds, hasImpact, holdsCallSites, implement, implementing, isTestFile, judgeSeam, naiveAcceptance, naivePass, ordinaryStart, planAndBuild, reUnwind, refactorCollecting, refactorFirst, refactorNote, refactorStrays, requireCriteria, requireCriteriaFrozen, requireImpact, requireImpactOnly, requireNoNewFlags, requireNoTestFiles, requireStableIds, requireTestCallSitesOnly, requireWithin, reviewedRefactor, seamBuild, skills, skipDesign, statedCriteria, steering, summary, triage, unstableIds, unwind };
979
+ export { COMMENT, REFACTOR_PACKAGE, acceptanceFault, access, afterTail, answerProductQuestions, answerReviewQuestions, buildFeature, buildTail, collecting, criteriaOf, criterionIds, feature_default as default, defaults, design, envDefaults, feature, fixNits, hasImpact, holdsCallSites, implement, implementing, isTestFile, judgeSeam, naiveAcceptance, naivePass, ordinaryStart, planAndBuild, reUnwind, refactorCollecting, refactorFirst, refactorNote, refactorStrays, requireCriteria, requireCriteriaFrozen, requireImpact, requireImpactOnly, requireNoNewFlags, requireNoTestFiles, requireStableIds, requireTestCallSitesOnly, requireWithin, reviewedRefactor, seamBuild, skills, skipDesign, statedCriteria, steering, summary, triage, unstableIds, unwind };
@@ -1,7 +1,7 @@
1
1
  import { read, refuse, removeScript, run, scope, start } from "../flows.mjs";
2
2
  import { b as reviewNotes, x as reviewRisks } from "../chunks/steering-CCNvngSH.mjs";
3
- import { Dt as defaults, G as fixReviewNotesPrompt, Ot as envDefaults, W as finisherSystem, c as baseline, i as skills, j as agentWithSkills, n as summary, r as access, s as shipped, t as steering, v as REVIEW, x as coder } from "../chunks/reserved-B8EC-WE8.mjs";
4
- import { r as handOffTail, t as REVIEW_ORIG } from "../chunks/tail-BSLah2mA.mjs";
3
+ import { Ct as envDefaults, G as finisherSystem, K as fixReviewNotesPrompt, M as agentWithSkills, S as coder, St as defaults, c as shipped, i as skills, l as baseline, n as summary, r as access, t as steering, y as REVIEW } from "../chunks/reserved-X2RkNHin.mjs";
4
+ import { r as handOffTail, t as REVIEW_ORIG } from "../chunks/tail-S04KEewi.mjs";
5
5
  //#region src/workflows/fix/fix.ts
6
6
  /**
7
7
  * Fix every note a human left in a handed-off `.gtd/REVIEW.md` and every
@@ -1,7 +1,7 @@
1
1
  import { read, refuse, removeScript, run, start } from "../flows.mjs";
2
- import { Dt as defaults, Ot as envDefaults, W as finisherSystem, _ as REQUIREMENTS, gt as reviewGateBlockedMessage, ht as reviewFeedbackFixPrompt, i as skills, j as agentWithSkills, l as gate, n as summary, r as access, s as shipped, t as steering, x as coder } from "../chunks/reserved-B8EC-WE8.mjs";
3
- import { a as refusePendingHandOff } from "../chunks/tail-BSLah2mA.mjs";
4
- import { r as reUnwind, t as buildTail } from "../chunks/review-HdrX0FJ7.mjs";
2
+ import { Ct as envDefaults, G as finisherSystem, M as agentWithSkills, S as coder, St as defaults, c as shipped, dt as reviewFeedbackFixPrompt, ft as reviewGateBlockedMessage, i as skills, n as summary, r as access, t as steering, u as gate, v as REQUIREMENTS } from "../chunks/reserved-X2RkNHin.mjs";
3
+ import { a as refusePendingHandOff } from "../chunks/tail-S04KEewi.mjs";
4
+ import { r as reUnwind, t as buildTail } from "../chunks/review-v7sh5GF4.mjs";
5
5
  //#region src/workflows/review/review.ts
6
6
  const fixFeedback = async () => {
7
7
  await agentWithSkills("feedback.fixing", reviewFeedbackFixPrompt(), {
@@ -1,5 +1,5 @@
1
1
  import { agent, changesSince, glob, head, mark, read, refuse, removeScript, run, scope, vars } from "../flows.mjs";
2
- import { Dt as defaults, Ot as envDefaults, Ut as requireFlag, Vt as flipProblems, f as FEEDBACK, i as skills, l as gate, n as summary, o as flagShipped, r as access, t as steering, x as coder, zt as flagMentions } from "../chunks/reserved-B8EC-WE8.mjs";
2
+ import { Ct as envDefaults, It as flipProblems, Pt as flagMentions, Rt as requireFlag, S as coder, St as defaults, i as skills, n as summary, o as flagShipped, p as FEEDBACK, r as access, t as steering, u as gate } from "../chunks/reserved-X2RkNHin.mjs";
3
3
  //#region src/workflows/rollout/rollout.ts
4
4
  const flippingPrompt = (name, registry) => `Roll out the release flag "${name}": in ${registry}, set \`defaultOn: true\` on its entry. Change nothing else — no other entry, no other field, no other file, no comments.`;
5
5
  const suiteBlockedMessage = () => "The suite is red after the rollout. Fix it by hand — a rollout may only touch the flag's registry entry — then land.";