@pmelab/gtd 29.3.1 → 30.1.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 (54) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +64 -63
  3. package/claude/hooks/register.tsx +5 -0
  4. package/dist/chunks/{reserved-Dmpg6dAp.mjs → reserved-DDiiAZ8U.mjs} +35 -239
  5. package/dist/chunks/{tail-CLyE5VFR.mjs → tail-ILPlELuy.mjs} +1 -1
  6. package/dist/gtd.bundle.mjs +0 -5
  7. package/dist/testkit.mjs +0 -5
  8. package/dist/workflows/cleanup.mjs +2 -2
  9. package/dist/workflows/feature.mjs +17 -182
  10. package/dist/workflows/fix.mjs +2 -2
  11. package/dist/workflows/review.mjs +2 -2
  12. package/dist/workflows/rollout.mjs +1 -1
  13. package/dist/workflows.mjs +47 -416
  14. package/package.json +1 -1
  15. package/skills/authoring/SKILL.md +15 -27
  16. package/src/cli/Cli.test.ts +6 -6
  17. package/src/edge/Edge.test.ts +7 -7
  18. package/src/flags/index.test.ts +0 -4
  19. package/src/flags/index.ts +0 -1
  20. package/src/workflow/load.test.ts +1 -1
  21. package/src/workflows/feature/fast-path.feature +1 -2
  22. package/src/workflows/feature/feature.test.ts +115 -63
  23. package/src/workflows/feature/feature.ts +21 -38
  24. package/src/workflows/feature/flag-mode.feature +157 -0
  25. package/src/workflows/feature/index.ts +0 -1
  26. package/src/workflows/feature/one-step-land.feature +4 -6
  27. package/src/workflows/feature/planning.ts +2 -27
  28. package/src/workflows/feature/refactor-absorbs.feature +1 -2
  29. package/src/workflows/feature/refactor-first.feature +1 -3
  30. package/src/workflows/feature/refactor-review.feature +0 -1
  31. package/src/workflows/feature/risk-tier.feature +2 -3
  32. package/src/workflows/feature/seam-rejection.feature +1 -3
  33. package/src/workflows/feature/seam.feature +4 -6
  34. package/src/workflows/feature/seam.ts +2 -0
  35. package/src/workflows/feature/steps.test.ts +0 -20
  36. package/src/workflows/feature/steps.ts +1 -49
  37. package/src/workflows/feature/{seam-pin.feature → tier-pin.feature} +17 -11
  38. package/src/workflows/feature/tier.test.ts +3 -5
  39. package/src/workflows/feature/tier.ts +2 -2
  40. package/src/workflows/index.ts +0 -1
  41. package/src/workflows/shared/access.test.ts +0 -2
  42. package/src/workflows/shared/access.ts +0 -2
  43. package/src/workflows/shared/options.test.ts +14 -3
  44. package/src/workflows/shared/options.ts +17 -2
  45. package/src/workflows/shared/prose.ts +4 -11
  46. package/src/workflows/shared/reserved.ts +2 -2
  47. package/src/workflows/shared/skills.test.ts +0 -11
  48. package/src/workflows/shared/skills.ts +2 -9
  49. package/src/workflows/shared/steps.ts +0 -1
  50. package/src/workflows/shared/text.test.ts +20 -104
  51. package/src/workflows/shared/text.ts +28 -229
  52. package/src/workflows/shared/vars.ts +2 -3
  53. package/src/workflows/feature/packages.test.ts +0 -368
  54. package/src/workflows/feature/packages.ts +0 -173
@@ -1,7 +1,7 @@
1
- import { answered, changes, changesSince, glob, hasThreadFor, head, human, judge, judgeDiffShape, kept, mark, matches, numeric, quote, read, refuse, removeScript, requireAnswers, requireProgress, requireReplies, requireRevert, requireThreadsClosed, restoreScript, revertScript, run, scope, slice, start, vars } from "../flows.mjs";
1
+ import { answered, changes, changesSince, hasThreadFor, head, human, judge, judgeDiffShape, kept, mark, matches, numeric, quote, read, refuse, removeScript, requireAnswers, requireProgress, requireReplies, requireRevert, requireThreadsClosed, restoreScript, revertScript, run, scope, slice, start, vars } from "../flows.mjs";
2
2
  import { lensesOf, review as review$1 } from "../workflow-kit.mjs";
3
- import { $ as refactorFixPrompt, A as architectureDecomposePrompt, B as designSystem, C as planner, D as agentWithSkills, E as reviewing, F as buildReviewFixNitsPrompt, G as idleMessage, I as buildReviewTriageMessage, J as naivePassPrompt, K as implementBuildingPrompt, L as builderSystem, M as buildReviewAnswerQuestionsPrompt, N as buildReviewAwaitAfterDeferMessage, O as architectSystem, P as buildReviewCollectingPrompt, Q as refactorDroppedRefusal, R as deferNotesScript, S as fixRisks, V as designTriagePrompt, X as packagesItemFixSuitePrompt, Y as packagesItemBuildingPrompt, Z as refactorBuildingPrompt, _ as REVIEW, at as reviewerSystem, b as fixCheck, ct as startGateBlockedMessage, d as healthy, dt as defaults, et as refactorRules, f as ARCHITECTURE, ft as envDefaults, g as REQUIREMENTS, h as REFACTOR, i as skills, it as reviewNotesCapture, j as architectureGateAnswerMessage, k as architectureAuthorPrompt, l as gate, lt as unwindFailedMessage, n as summary, nt as reviewEditsCapture, o as shipped, ot as seamByHandMessage, p as FEEDBACK, pt as testFileGlobs, q as implementFixPrompt, r as access, st as seamSteerMessage, t as steering, tt as reviewEditNotesCapture, u as guarded, ut as unwindFailure, v as awaitReview, w as reviewMissing, y as coder, z as designGateAnswerMessage } from "../chunks/reserved-Dmpg6dAp.mjs";
4
- import { a as refusePendingHandOff, i as isOptionalObject, n as closeReview, o as tail } from "../chunks/tail-CLyE5VFR.mjs";
3
+ import { $ as reviewerSystem, A as buildReviewCollectingPrompt, C as planner, D as agentWithSkills, E as reviewing, F as designGateAnswerMessage, G as refactorBuildingPrompt, H as implementBuildingPrompt, I as designSystem, J as refactorRules, K as refactorDroppedRefusal, L as designTriagePrompt, M as buildReviewTriageMessage, N as builderSystem, O as buildReviewAnswerQuestionsPrompt, P as deferNotesScript, Q as reviewNotesCapture, S as fixRisks, U as implementFixPrompt, V as idleMessage, W as naivePassPrompt, X as reviewEditsCapture, Y as reviewEditNotesCapture, _ as REVIEW, a as flagModeOn, at as defaults, b as fixCheck, d as guarded, et as seamByHandMessage, f as healthy, g as REQUIREMENTS, h as REFACTOR, i as skills, it as unwindFailure, j as buildReviewFixNitsPrompt, k as buildReviewAwaitAfterDeferMessage, n as summary, nt as startGateBlockedMessage, ot as envDefaults, p as FEEDBACK, q as refactorFixPrompt, r as access, rt as unwindFailedMessage, s as shipped, st as testFileGlobs, t as steering, tt as seamSteerMessage, u as gate, v as awaitReview, w as reviewMissing, y as coder } from "../chunks/reserved-DDiiAZ8U.mjs";
4
+ import { a as refusePendingHandOff, i as isOptionalObject, n as closeReview, o as tail } from "../chunks/tail-ILPlELuy.mjs";
5
5
  //#region src/workflows/shared/fences.ts
6
6
  const markFenced = (text) => {
7
7
  let fence;
@@ -18,8 +18,8 @@ const markFenced = (text) => {
18
18
  };
19
19
  //#endregion
20
20
  //#region src/workflows/feature/tier.ts
21
- /** GTD_FLAG_NAIVE_PASS, GTD_FLAG_RISK_TIER: both pinned at process start, so a mid-process flip never moves a process. */
22
- const riskTierOn = () => vars.flag_naive_pass === "1" && vars.flag_risk_tier === "1";
21
+ /** GTD_FLAG_RISK_TIER: pinned at process start, so a mid-process flip never moves a process. */
22
+ const riskTierOn = () => vars.flag_risk_tier === "1";
23
23
  const sectionLines = (text, title) => {
24
24
  if (text === void 0) return [];
25
25
  const heading = new RegExp(`^##[ \\t]+${title}[ \\t]*$`, "i");
@@ -63,18 +63,6 @@ const triage = (base) => agentWithSkills("triage", designTriagePrompt(base, risk
63
63
  model: planner(),
64
64
  system: designSystem()
65
65
  });
66
- const author = () => agentWithSkills("author", architectureAuthorPrompt(), {
67
- label: "Refining the technical plan",
68
- file: ARCHITECTURE,
69
- mode: "qa",
70
- model: planner(),
71
- system: architectSystem()
72
- });
73
- const decompose = () => agentWithSkills("decompose.decomposing", architectureDecomposePrompt(), {
74
- label: "Decomposing into packages",
75
- model: planner(),
76
- system: architectSystem()
77
- });
78
66
  const answerProductQuestions = () => human("gate.answer", {
79
67
  message: designGateAnswerMessage(riskTierOn()),
80
68
  label: "Awaiting your product answers",
@@ -82,24 +70,6 @@ const answerProductQuestions = () => human("gate.answer", {
82
70
  mode: "qa",
83
71
  acceptClean: true
84
72
  });
85
- const answerTechnicalQuestions = () => human("gate.answer", {
86
- message: architectureGateAnswerMessage(),
87
- label: "Awaiting your technical answers",
88
- file: ARCHITECTURE,
89
- mode: "qa",
90
- acceptClean: true
91
- });
92
- const build = (pkg) => agentWithSkills("building", packagesItemBuildingPrompt(pkg), {
93
- label: "Building",
94
- model: coder(),
95
- system: builderSystem()
96
- });
97
- const fixSuite = () => agentWithSkills("fix.suite.fixing", packagesItemFixSuitePrompt(), {
98
- label: "Fixing the check",
99
- file: FEEDBACK,
100
- model: coder(),
101
- system: builderSystem()
102
- });
103
73
  /** Answer every `question` note inline in `.gtd/REVIEW.md`. */
104
74
  const answerReviewQuestions = (notes) => agentWithSkills("review.answer-review-questions", buildReviewAnswerQuestionsPrompt(notes), {
105
75
  label: "Answering your questions",
@@ -147,113 +117,6 @@ const deferNotes = (notes, round) => run("review.defer", deferNotesScript(notes,
147
117
  file: ".gtd/TODO.md"
148
118
  });
149
119
  //#endregion
150
- //#region src/workflows/feature/packages.ts
151
- const TEST_LINE = /^-\s+(unit|e2e):\s+`([^`]+)`(.*)$/;
152
- const MARKER = /^[ \t]+\(unchanged\)(?=\s|$)/i;
153
- const ITEM = /^\s*-\s/;
154
- /** The `## Tests` entries of a package file; malformed entries are ignored. */
155
- const declaredTests = (packageText) => {
156
- const found = [];
157
- let inTests = false;
158
- let entry;
159
- const flush = () => {
160
- const match = entry === void 0 ? null : TEST_LINE.exec(entry);
161
- if (match) found.push({
162
- level: match[1],
163
- path: match[2],
164
- unchanged: MARKER.test(match[3])
165
- });
166
- entry = void 0;
167
- };
168
- for (const line of packageText.replace(/\r\n?/g, "\n").split("\n")) if (/^##\s/.test(line)) {
169
- flush();
170
- inTests = /^##\s+Tests\s*$/.test(line);
171
- } else if (!inTests) continue;
172
- else if (ITEM.test(line)) {
173
- flush();
174
- entry = line.trim();
175
- } else if (entry !== void 0 && /^\s/.test(line) && line.trim() !== "") entry = `${entry} ${line.trim()}`;
176
- else flush();
177
- flush();
178
- return found;
179
- };
180
- const diffBucket = (test, status, turn, satisfied) => {
181
- if (test.unchanged) {
182
- if (turn !== "build") return void 0;
183
- if (status === "modified") return "modifiedMarked";
184
- return status === "added" ? "addedMarked" : void 0;
185
- }
186
- return !satisfied && (status === void 0 || status === "deleted") ? "notInDiff" : void 0;
187
- };
188
- const treeBucket = (test, status) => {
189
- if (read(test.path) !== void 0) return void 0;
190
- return test.unchanged && status === "deleted" ? "deletedMarked" : "notInTree";
191
- };
192
- const unmetBucket = (test, change, turn, satisfied) => diffBucket(test, change?.status, turn, satisfied) ?? treeBucket(test, change?.status);
193
- /**
194
- * Refuse a build or fix turn unless every test `pkg` declares exists and is in the
195
- * diff since `since`. The package text is read as of `since`, so a builder
196
- * editing its own `## Tests` (or adding `(unchanged)`) cannot dodge the guard;
197
- * with `.gtd/SATISFIED.md` written, or the line marked, existing suffices. The
198
- * build turn must neither modify nor add a marked test; a fix turn may edit it.
199
- */
200
- const requireDeclaredTests = (pkg, since, turn = "fix") => {
201
- const range = changesSince(since);
202
- const text = range.get(pkg)?.before ?? read(pkg) ?? "";
203
- const satisfied = read(".gtd/SATISFIED.md") !== void 0;
204
- const buckets = {
205
- notInDiff: [],
206
- modifiedMarked: [],
207
- addedMarked: [],
208
- deletedMarked: [],
209
- notInTree: []
210
- };
211
- const entries = declaredTests(text);
212
- const seen = /* @__PURE__ */ new Set();
213
- for (const test of entries) {
214
- if (test.unchanged && entries.some((e) => !e.unchanged && e.path === test.path)) continue;
215
- const bucket = unmetBucket(test, range.get(test.path), turn, satisfied);
216
- if (bucket && !seen.has(test.path)) {
217
- seen.add(test.path);
218
- buckets[bucket].push(test.path);
219
- }
220
- }
221
- const { notInDiff, modifiedMarked, addedMarked, deletedMarked, notInTree } = buckets;
222
- const reasons = [
223
- ["not in the package's diff — write them", notInDiff],
224
- ["marked (unchanged) but modified — revert them", modifiedMarked],
225
- ["marked (unchanged) but added by this turn — the marker promises an existing test; stop and leave it to a person", addedMarked],
226
- ["marked (unchanged) but deleted — restore them", deletedMarked],
227
- ["missing from the tree", notInTree]
228
- ].filter(([, paths]) => paths.length > 0);
229
- if (reasons.length === 0) return;
230
- refuse(`gtd land: declared-tests: ${pkg} declares tests this turn left unmet:\n${reasons.map(([reason, paths]) => `${reason}:\n${paths.map((path) => ` - ${path}`).join("\n")}`).join("\n")}`);
231
- };
232
- /**
233
- * Build `pkg`, check its declared tests, keep the full suite green, and close
234
- * it out, which removes it — and `.gtd/ARCHITECTURE.md` with the last one.
235
- */
236
- const packageItem = async (pkg) => {
237
- const from = head();
238
- const declared = (turn, kind) => async () => {
239
- await turn();
240
- requireDeclaredTests(pkg, from, kind);
241
- };
242
- await declared(() => build(pkg), "build")();
243
- await healthy(declared(fixSuite, "fix"));
244
- await run("closing", removeScript([
245
- pkg,
246
- ".gtd/SATISFIED.md",
247
- ...glob(".gtd/packages/*.md").length === 1 ? [ARCHITECTURE] : []
248
- ]), { label: "Closing out the package" });
249
- };
250
- /** The first queued package — the one a package step works on. */
251
- const nextPackage = () => [...glob(".gtd/packages/*.md")].sort()[0];
252
- /** Build every package file under `.gtd/packages/`, in name order. */
253
- const packages = () => scope("packages", async () => {
254
- for (let pkg = nextPackage(); pkg !== void 0; pkg = nextPackage()) await scope("item", () => packageItem(pkg));
255
- });
256
- //#endregion
257
120
  //#region src/workflows/feature/planning.ts
258
121
  /**
259
122
  * Always stop for the human. Resolves `true` when the round changed anything
@@ -276,16 +139,6 @@ const design = (base) => scope("design", async () => {
276
139
  requireReplies(REQUIREMENTS);
277
140
  } while (await noteGate(REQUIREMENTS, answerProductQuestions));
278
141
  });
279
- /** Work out the technical plan, then decompose it into package files. */
280
- const architecture = () => scope("architecture", async () => {
281
- do {
282
- await author();
283
- requireReplies(ARCHITECTURE);
284
- } while (await noteGate(ARCHITECTURE, answerTechnicalQuestions));
285
- await decompose();
286
- if (changes(".gtd/packages/**").length === 0) refuse("gtd land: decompose: write at least one package under .gtd/packages/");
287
- if (changes(".gtd/ARCHITECTURE.md").some((c) => c.status === "deleted")) refuse("gtd land: decompose: keep .gtd/ARCHITECTURE.md — the packages are built from it; it is removed with the last package");
288
- });
289
142
  //#endregion
290
143
  //#region src/workflows/feature/review.ts
291
144
  const VERDICTS = [
@@ -772,7 +625,7 @@ function implement(first, tier, amend) {
772
625
  amend
773
626
  };
774
627
  return scope("implement", async () => {
775
- await agentWithSkills("building", implementBuildingPrompt(options.reference, options.tier, options.amend, options.afterRefactor), {
628
+ await agentWithSkills("building", implementBuildingPrompt(options.reference, options.tier, options.amend, options.afterRefactor, flagModeOn()), {
776
629
  label: "Implementing",
777
630
  model: coder(),
778
631
  system: builderSystem(),
@@ -853,29 +706,10 @@ const unwind = () => {
853
706
  const commit = head();
854
707
  return run("unwind", revertScript(commit, FEEDBACK, unwindFailure(commit)), { label: "Unwinding your input" });
855
708
  };
856
- /** Plan, build and review until a review round signs off; feedback re-plans from scratch. */
857
- const planAndBuild = async (firstBase, firstLap = "first") => {
858
- if (vars.flag_naive_pass === "1") return naivePlanAndBuild(firstBase);
859
- let base = firstBase;
860
- let lap = firstLap;
861
- for (;;) {
862
- await design(base);
863
- await architecture();
864
- await packages();
865
- const outcome = await buildTail(base, {
866
- green: true,
867
- lap
868
- });
869
- if (outcome.verdict === "signoff") return;
870
- await reUnwind(outcome);
871
- base = outcome.base;
872
- lap = "feedback";
873
- }
874
- };
875
- const naivePlanAndBuild = async (firstBase) => {
876
- await design(firstBase);
709
+ /** A judged naive pass (none with `flagMode` off), then implement and review until a review round signs off; design must have run since `firstBase`. */
710
+ const buildFeature = async (firstBase) => {
877
711
  const tier = riskTierOn() ? recordRisk() : void 0;
878
- const seam = await seamBuild(firstBase);
712
+ const seam = flagModeOn() ? await seamBuild(firstBase) : { base: firstBase };
879
713
  await slice("feature", async () => {
880
714
  await implement({
881
715
  reference: seam.reference,
@@ -889,6 +723,11 @@ const naivePlanAndBuild = async (firstBase) => {
889
723
  }), base);
890
724
  });
891
725
  };
726
+ /** Design, then `buildFeature`. */
727
+ const planAndBuild = async (firstBase) => {
728
+ await design(firstBase);
729
+ await buildFeature(firstBase);
730
+ };
892
731
  const featureFeedback = async (first, lensBase) => {
893
732
  let outcome = first;
894
733
  while (outcome.verdict === "feedback") {
@@ -906,12 +745,7 @@ const featureFeedback = async (first, lensBase) => {
906
745
  }
907
746
  };
908
747
  /** After a tail that skipped planning: stop on sign-off, re-plan on feedback. Opens no slice: slices cannot nest. */
909
- const afterTail = async (outcome) => {
910
- if (outcome.verdict === "signoff") return;
911
- if (vars.flag_naive_pass === "1") return featureFeedback(outcome);
912
- await reUnwind(outcome);
913
- await planAndBuild(outcome.base, "feedback");
914
- };
748
+ const afterTail = (outcome) => featureFeedback(outcome);
915
749
  /** An ordinary start: wait at `idle`, unwind the sketch, check the baseline, then plan and build. */
916
750
  const ordinaryStart = async () => {
917
751
  await human("idle", {
@@ -920,6 +754,7 @@ const ordinaryStart = async () => {
920
754
  file: ".gtd/TODO.md"
921
755
  });
922
756
  refusePendingHandOff();
757
+ flagModeOn();
923
758
  await unwind();
924
759
  if (changes(".gtd/FEEDBACK.md").some((c) => c.status !== "deleted")) await human("unwind-failed", {
925
760
  message: unwindFailedMessage(),
@@ -934,4 +769,4 @@ const feature = shipped(ordinaryStart);
934
769
  //#region src/workflows/feature/index.ts
935
770
  var feature_default = feature;
936
771
  //#endregion
937
- export { REFACTOR_PACKAGE, access, afterTail, answerProductQuestions, answerReviewQuestions, answerTechnicalQuestions, architecture, author, build, buildTail, collecting, declaredTests, decompose, feature_default as default, defaults, deferNotes, design, envDefaults, feature, fixNits, fixSuite, implement, judgeSeam, naivePass, nextPackage, ordinaryStart, packageItem, packages, planAndBuild, reUnwind, refactorCollecting, refactorFirst, refactorStrays, requireDeclaredTests, requireNoNewFlags, requireNoTestFiles, requireTestCallSitesOnly, requireWithin, reviewedRefactor, seamBuild, skills, steering, summary, triage, unwind };
772
+ export { REFACTOR_PACKAGE, access, afterTail, answerProductQuestions, answerReviewQuestions, buildFeature, buildTail, collecting, feature_default as default, defaults, deferNotes, design, envDefaults, feature, fixNits, implement, judgeSeam, naivePass, ordinaryStart, planAndBuild, reUnwind, refactorCollecting, refactorFirst, refactorStrays, requireNoNewFlags, requireNoTestFiles, requireTestCallSitesOnly, requireWithin, reviewedRefactor, seamBuild, skills, steering, summary, triage, unwind };
@@ -1,7 +1,7 @@
1
1
  import { read, refuse, removeScript, run, scope, start } from "../flows.mjs";
2
2
  import { d as reviewNotes, f as reviewRisks } from "../chunks/steering-DVILanVf.mjs";
3
- import { D as agentWithSkills, H as finisherSystem, U as fixReviewNotesPrompt, _ as REVIEW, dt as defaults, ft as envDefaults, i as skills, n as summary, o as shipped, r as access, s as baseline, t as steering, y as coder } from "../chunks/reserved-Dmpg6dAp.mjs";
4
- import { r as handOffTail, t as REVIEW_ORIG } from "../chunks/tail-CLyE5VFR.mjs";
3
+ import { D as agentWithSkills, R as finisherSystem, _ as REVIEW, at as defaults, c as baseline, i as skills, n as summary, ot as envDefaults, r as access, s as shipped, t as steering, y as coder, z as fixReviewNotesPrompt } from "../chunks/reserved-DDiiAZ8U.mjs";
4
+ import { r as handOffTail, t as REVIEW_ORIG } from "../chunks/tail-ILPlELuy.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,6 +1,6 @@
1
1
  import { start } from "../flows.mjs";
2
- import { dt as defaults, ft as envDefaults, i as skills, l as gate, n as summary, o as shipped, r as access, rt as reviewGateBlockedMessage, t as steering } from "../chunks/reserved-Dmpg6dAp.mjs";
3
- import { a as refusePendingHandOff, r as handOffTail } from "../chunks/tail-CLyE5VFR.mjs";
2
+ import { Z as reviewGateBlockedMessage, at as defaults, i as skills, n as summary, ot as envDefaults, r as access, s as shipped, t as steering, u as gate } from "../chunks/reserved-DDiiAZ8U.mjs";
3
+ import { a as refusePendingHandOff, r as handOffTail } from "../chunks/tail-ILPlELuy.mjs";
4
4
  //#region src/workflows/review/review.ts
5
5
  /**
6
6
  * Pure review of everything since `reviewBase`: a green gate, the quality
@@ -1,5 +1,5 @@
1
1
  import { agent, changesSince, glob, head, mark, read, refuse, removeScript, run, scope, vars } from "../flows.mjs";
2
- import { a as flagShipped, dt as defaults, ft as envDefaults, gt as flipProblems, i as skills, l as gate, mt as flagMentions, n as summary, p as FEEDBACK, r as access, t as steering, vt as requireFlag, y as coder } from "../chunks/reserved-Dmpg6dAp.mjs";
2
+ import { at as defaults, ct as flagMentions, ft as requireFlag, i as skills, n as summary, o as flagShipped, ot as envDefaults, p as FEEDBACK, r as access, t as steering, u as gate, ut as flipProblems, y as coder } from "../chunks/reserved-DDiiAZ8U.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.";