@pmelab/gtd 48.0.0 → 50.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 (45) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +31 -20
  3. package/dist/chunks/{reserved-DF1HD6jL.mjs → reserved-CdOzKFVX.mjs} +150 -24
  4. package/dist/chunks/{review-Bv40kZu9.mjs → review-BChXEl2Y.mjs} +132 -24
  5. package/dist/chunks/{steering-D7hWeMgE.mjs → steering-DtUVUz9l.mjs} +49 -13
  6. package/dist/chunks/{tail-D89fU_wf.mjs → tail-DRM2eC1z.mjs} +1 -1
  7. package/dist/gtd.bundle.mjs +22 -5
  8. package/dist/steering.mjs +2 -2
  9. package/dist/testkit.mjs +1 -1
  10. package/dist/web/main.js +27 -3
  11. package/dist/workflow-kit.mjs +1 -1
  12. package/dist/workflows/cleanup.mjs +2 -2
  13. package/dist/workflows/feature.mjs +16 -9
  14. package/dist/workflows/fix.mjs +3 -3
  15. package/dist/workflows/review.mjs +3 -3
  16. package/dist/workflows/rollout.mjs +1 -1
  17. package/dist/workflows.mjs +338 -62
  18. package/package.json +1 -1
  19. package/src/steering/index.ts +2 -0
  20. package/src/steering/review.test.ts +87 -0
  21. package/src/steering/review.ts +75 -8
  22. package/src/workflows/feature/coverage.feature +3 -3
  23. package/src/workflows/feature/fast-path.feature +2 -2
  24. package/src/workflows/feature/feature.ts +10 -3
  25. package/src/workflows/feature/flag-mode.feature +2 -2
  26. package/src/workflows/feature/lens-review.feature +128 -13
  27. package/src/workflows/feature/one-step-land.feature +2 -2
  28. package/src/workflows/feature/refactor-absorbs.feature +2 -2
  29. package/src/workflows/feature/refactor-first.feature +2 -2
  30. package/src/workflows/feature/refactor-rebuild.feature +2 -2
  31. package/src/workflows/feature/refactor-review.feature +6 -6
  32. package/src/workflows/feature/review-answers.feature +51 -5
  33. package/src/workflows/feature/review-gate.feature +23 -6
  34. package/src/workflows/feature/reviewer-walkthrough.feature +240 -0
  35. package/src/workflows/feature/seam-rejection.feature +2 -2
  36. package/src/workflows/feature/seam.feature +2 -2
  37. package/src/workflows/feature/severity-budget.feature +111 -0
  38. package/src/workflows/feature/severity-sorted-review.feature +197 -0
  39. package/src/workflows/feature/slice-findings.feature +68 -5
  40. package/src/workflows/feature/slicing.feature +6 -6
  41. package/src/workflows/feature/standards.feature +29 -1
  42. package/src/workflows/shared/review.ts +226 -25
  43. package/src/workflows/shared/steps.ts +3 -2
  44. package/src/workflows/shared/text.test.ts +216 -0
  45. package/src/workflows/shared/text.ts +201 -19
package/dist/steering.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { C as parseFootnotes, D as headingSectionBodies, E as getParseCount, O as headingSections, S as openThreadFindings, T as parseThreadsWithFindings, _ as unansweredNotes, a as unansweredQuestions, b as FOOTNOTE_ACTION_TITLE, c as stripCodeThreads, d as ANSWER_FIX, f as ANSWER_LEAD, g as reviewRisks, h as reviewNotes, i as steeringFormatOrFreeForm, k as formatFinding, l as freeFormFormat, m as reviewDecisions, n as openThreads, o as viewOf, p as ANSWER_WONT_FIX, r as steeringFormatFor, s as parseCodeThreads, t as BUILT_IN_MODE_NAMES, u as applySteeringEdits, v as FREE_TEXT_PLACEHOLDER, w as parseThreads, x as THREAD_REPLY_ACTION_TITLE, y as isAnswered } from "./chunks/steering-D7hWeMgE.mjs";
2
- export { ANSWER_FIX, ANSWER_LEAD, ANSWER_WONT_FIX, BUILT_IN_MODE_NAMES, FOOTNOTE_ACTION_TITLE, FREE_TEXT_PLACEHOLDER, THREAD_REPLY_ACTION_TITLE, applySteeringEdits, formatFinding, freeFormFormat, getParseCount, headingSectionBodies, headingSections, isAnswered, openThreadFindings, openThreads, parseCodeThreads, parseFootnotes, parseThreads, parseThreadsWithFindings, reviewDecisions, reviewNotes, reviewRisks, steeringFormatFor, steeringFormatOrFreeForm, stripCodeThreads, unansweredNotes, unansweredQuestions, viewOf };
1
+ import { A as headingSections, C as THREAD_REPLY_ACTION_TITLE, D as parseThreadsWithFindings, E as parseThreads, O as getParseCount, S as FOOTNOTE_ACTION_TITLE, T as parseFootnotes, _ as reviewRisks, a as unansweredQuestions, b as FREE_TEXT_PLACEHOLDER, c as stripCodeThreads, d as ANSWER_FIX, f as ANSWER_LEAD, g as reviewNotes, h as reviewDecisions, i as steeringFormatOrFreeForm, j as formatFinding, k as headingSectionBodies, l as freeFormFormat, m as reviewChunks, n as openThreads, o as viewOf, p as ANSWER_WONT_FIX, r as steeringFormatFor, s as parseCodeThreads, t as BUILT_IN_MODE_NAMES, u as applySteeringEdits, v as severityLine, w as openThreadFindings, x as isAnswered, y as unansweredNotes } from "./chunks/steering-DtUVUz9l.mjs";
2
+ export { ANSWER_FIX, ANSWER_LEAD, ANSWER_WONT_FIX, BUILT_IN_MODE_NAMES, FOOTNOTE_ACTION_TITLE, FREE_TEXT_PLACEHOLDER, THREAD_REPLY_ACTION_TITLE, applySteeringEdits, formatFinding, freeFormFormat, getParseCount, headingSectionBodies, headingSections, isAnswered, openThreadFindings, openThreads, parseCodeThreads, parseFootnotes, parseThreads, parseThreadsWithFindings, reviewChunks, reviewDecisions, reviewNotes, reviewRisks, severityLine, steeringFormatFor, steeringFormatOrFreeForm, stripCodeThreads, unansweredNotes, unansweredQuestions, viewOf };
package/dist/testkit.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { answered, applyScript, checkScript, configProblems, configure, installContext, isFactoryWorkflow, moveScript, numeric, protocolMismatch, removeScript, restoreScript, revertScript, showScript, t as flows_exports, writeScript } from "./flows.mjs";
2
2
  import { A as beatKindOf, B as ACCESS_REFUSAL, C as renderLandPlain, D as renderBeatJson, E as beatDocument, O as statusOf, S as renderLandJson, T as renderBeatPlain, U as renderFormat, _ as selectPath, a as contextLimitFault, g as resolveSession, h as globMatches, j as demandOf, l as parseContextWindow, m as slicesDocument, o as contextShapeFault, p as renderSlicesJson, v as judgeJson, x as noopText, y as landFields } from "./chunks/wire-BJuZWR3C.mjs";
3
- import { D as headingSectionBodies, O as headingSections, T as parseThreadsWithFindings, a as unansweredQuestions, k as formatFinding, n as openThreads, r as steeringFormatFor, s as parseCodeThreads, t as BUILT_IN_MODE_NAMES } from "./chunks/steering-D7hWeMgE.mjs";
3
+ import { A as headingSections, D as parseThreadsWithFindings, a as unansweredQuestions, j as formatFinding, k as headingSectionBodies, n as openThreads, r as steeringFormatFor, s as parseCodeThreads, t as BUILT_IN_MODE_NAMES } from "./chunks/steering-DtUVUz9l.mjs";
4
4
  import { $ as logWarning, $i as BaseProto, $n as map$5, $r as make$19, $t as provide$1, A as catchIf, Ai as add$1, An as scopeMake, Ar as flatMap$3, At as suspend$5, B as flatMap$4, Bi as getOrElse, Bn as get$3, Br as sync$1, Bt as unsafeMakeLatch, C as all$1, Ci as toArray, Cn as isInterrupted, Cr as exitFail, Ct as sandbox, D as async, Di as GenericTag, Dn as squash, Dr as exitZipRight, Dt as scopedWith$1, E as asVoid$1, Ei as unsafeHead, En as reduceWithContext, Er as exitVoid, Et as scoped$4, F as ensuring$2, Fi as fromIterable, Fn as join$3, Fr as map$3, Ft as tryMap, G as forkIn, Gi as match$4, Gn as TypeId$10, Gr as whenEffect, Gt as zipLeft, H as fnUntraced, Hi as isNone, Hn as modify$1, Hr as uninterruptible, Ht as when, I as exit, Ii as splitAt, In as sequential, Ir as onInterrupt, It as tryPromise, J as ignore, Ji as isLeft, Jn as all, Jr as DeferredTypeId$1, Jt as spaced$1, K as forkScoped, Ki as none, Kn as Class, Kr as withFiberRuntime, Kt as zipRight$3, L as fail$5, Li as filter$1, Ln as bind, Lr as scopeClose, Lt as try_, M as die$2, Mi as getOption, Mn as _await$2, Mr as interruptAsFiber, Mt as tap, N as dieMessage, Ni as omit, Nn as inheritAll$1, Nr as interruptFiber, Nt as tapErrorCause, O as catchAll$1, Oi as Reference, On as ensuring$3, Or as fiberId, Ot as serviceOption, P as either, Pi as empty$5, Pn as interruptAllAs$1, Pr as interruptible$1, Pt as timeout, Q as isEffect, Qi as pipeArguments, Qn as isFailure, Qr as ids, Qt as mergeAll$2, R as failCause$4, Ri as flatMap$5, Rn as bindTo, Rr as succeed$4, Rt as uninterruptible$1, S as addFinalizer$1, Si as takeRight, Sn as isDieType, Sr as exitAs, St as runtime, T as as, Ti as unsafeGet, Tn as map$6, Tr as exitSucceed, Tt as scopeWith, U as forEach$2, Ui as isSome, Un as set$1, Ur as uninterruptibleMask$1, Ut as withFiberRuntime$1, V as flatten$4, Vi as getOrUndefined, Vn as make$16, Vr as tap$1, Vt as unsafeMakeSemaphore$1, W as forkDaemon, Wi as map$8, Wn as update$1, Wr as void_$2, Wt as zip$1, X as interruptible, Xi as match$2, Xn as fail$4, Xr as combine, Xt as tagged, Y as interrupt$4, Yi as left, Yn as die, Yr as empty$6, Yt as TaggedError$1, Z as intoDeferred, Zi as right, Zn as failCause$3, Zr as combineAll, Zt as fromEffect$5, _ as decodeSync, _i as of, _n as fail$3, _r as deferredIsDone, _t as raceWith, a as Literal, aa as constFalse, ai as size$2, an as updateContext$1, ar as zipRight$2, at as matchCause, b as acquireRelease, bi as reverse, bn as interrupt$3, br as deferredUnsafeDone, bt as runPromise, c as String$, ca as constVoid, ci as append$1, cn as Scope, cr as asyncInterrupt, ct as negate, d as Union, da as pipe, di as empty$4, dn as close, dr as deferredAwait, dt as orElse, ea as NodeInspectSymbol, ei as none$1, en as provideMerge$1, er as mapBoth, et as makeSemaphore, f as between, fi as filter, fn as extend, fr as deferredComplete, ft as orElseSucceed, gi as map$7, gn as die$1, gr as deferredInterruptWith, gt as race, hi as isEmpty$2, hn as NoSuchElementException, hr as deferredInterrupt, ht as provideService, i as Defect, ia as hasProperty, ii as has, in as unsafeRunPromiseExit, ir as zip$2, it as match$5, j as catchTag, ji as get$5, jn as scopeTag, jr as interrupt$2, jt as sync$2, k as catchAllCause, ki as Tag, kn as forEachConcurrentDiscard, kr as fiberRefLocally, kt as succeed$6, l as Struct, la as dual, li as appendAll, ln as addFinalizer, lr as catchAll, lt as onError, m as optional$1, mi as isChunk, mn as make$18, mr as deferredFailCause, mt as provide$2, n as Boolean$, na as toJSON, ni as make$17, nn as succeed$3, nr as succeed$5, nt as mapBoth$1, o as Never, oa as constTrue, oi as decode, on as forkIn$1, or as as$1, ot as matchCauseEffect, p as decodeUnknown, pi as fromIterable$1, pn as fork, pr as deferredFail, pt as promise, q as gen, qi as some, qn as spanTag, qr as zipRight$1, qt as zipWith, r as Cause, ra as equals, ri as set$2, rn as unsafeFork, rr as void_$3, rt as mapError, s as Number$, sa as constUndefined, si as isFinite, sn as unsafeMakeSemaphore, sr as asVoid, st as matchEffect, t as Array$, ta as format, ti as get$4, tn as scoped$3, tr as match$3, tt as map$4, u as TaggedError, ua as identity, ui as drop, un as addFinalizerExit, ur as currentContext$1, ut as orDie, v as encodeSync, vi as prepend, vn as failureOrCause, vr as deferredMake, vt as repeat, w as annotateLogs, wi as unsafeFromArray, wn as isInterruptedOnly, wr as exitFailCause, wt as scope, x as acquireUseRelease$2, xi as take$2, xn as interruptors, xr as deferredUnsafeMake, xt as runPromiseExit$1, y as _void, yi as reduce, yn as flipCauseOption, yr as deferredSucceed, yt as retry, z as fiberIdWith, zi as fromNullable, zn as sleep, zr as suspend$4, zt as uninterruptibleMask } from "./chunks/Schema-C6fLlQzx.mjs";
5
5
  import { createRequire } from "node:module";
6
6
  import * as Crypto from "node:crypto";
package/dist/web/main.js CHANGED
@@ -31565,6 +31565,8 @@ const qaDescriptor = {
31565
31565
  unansweredQuestions,
31566
31566
  openThreads: openThreadsOf
31567
31567
  };
31568
+ /** A chunk's leading `_critical: security_` paragraph: the tier gtd ranked it with, and why. */
31569
+ const SEVERITY_LINE_RE = /^_((?:critical|should|could)(?::[^_\n]*)?)_$/;
31568
31570
  /**
31569
31571
  * The canonical sample. Every detail here is load-bearing for the formatter
31570
31572
  * round-trip: both footnote bodies exceed 80 characters so a reflow actually
@@ -31855,12 +31857,26 @@ const answerListOf = (content, body) => {
31855
31857
  })
31856
31858
  };
31857
31859
  };
31860
+ /** A leading severity line is the chunk's tier, never its prose. */
31861
+ const splitSeverity = (content, run) => {
31862
+ const first = run[0];
31863
+ const label = first?.type === "paragraph" ? SEVERITY_LINE_RE.exec(sourceText(content, first).trim())?.[1] : void 0;
31864
+ if (label === void 0) return { leadingRun: run };
31865
+ return {
31866
+ severity: {
31867
+ label,
31868
+ line: toLspPosition(first.position.start).line
31869
+ },
31870
+ leadingRun: run.slice(1)
31871
+ };
31872
+ };
31858
31873
  /** Splits one chunk's body nodes into its file pointers (hunk pointers are task items, collected recursively at ANY nesting depth via `taskItems` — a nested hunk is the same kind of hunk as a top-level one) and description prose. The description is the chunk's own leading run and never a node that contains a hunk pointer: it stops at the first node whose `taskItems` include a real pointer (at any depth — a blockquote wrapping a pointer list stops it just as a top-level list would). Every node kind in what's left before that point contributes — a `footnoteDefinition` is the one exception, excluded by `blockNodesOfRun` itself (it's a note, never document content). */
31859
31874
  const parseChunkBody = (content, lines, title, body) => {
31860
31875
  const answer = answerListOf(content, body);
31861
31876
  const isAnswer = (n) => answer !== void 0 && (n === answer.list || n === body[answer.lead]);
31862
31877
  const firstPointerIndex = body.findIndex((n) => !isAnswer(n) && taskItems(n).some((item) => hasPointerToken(content, item)));
31863
- const leadingRun = (firstPointerIndex === -1 ? body : body.slice(0, firstPointerIndex)).filter((n) => !isAnswer(n));
31878
+ const run = (firstPointerIndex === -1 ? body : body.slice(0, firstPointerIndex)).filter((n) => !isAnswer(n));
31879
+ const { severity, leadingRun } = splitSeverity(content, run);
31864
31880
  const descriptionNodes = blockNodesOfRun(content, leadingRun);
31865
31881
  const descriptionInline = collapseImages(blockRunInline(content, leadingRun));
31866
31882
  const description = leadingRun.filter((n) => n.type !== "footnoteDefinition").map((n) => sourceText(content, n)).join(" ").trim();
@@ -31879,6 +31895,7 @@ const parseChunkBody = (content, lines, title, body) => {
31879
31895
  files,
31880
31896
  errors,
31881
31897
  ...answer === void 0 ? {} : { answers: answer.options },
31898
+ ...severity === void 0 ? {} : { severity },
31882
31899
  boxed: body.some((n) => !isAnswer(n) && taskItems(n).length > 0)
31883
31900
  };
31884
31901
  };
@@ -31915,7 +31932,7 @@ const parseChangesets = (tree, content, lines) => {
31915
31932
  const errors = [];
31916
31933
  for (const { heading, headingLine, body } of splitChunks(tree)) {
31917
31934
  const title = headingText$1(content, heading);
31918
- const { description, descriptionNodes, descriptionInline, files, answers, boxed, errors: bodyErrors } = parseChunkBody(content, lines, title, body);
31935
+ const { description, descriptionNodes, descriptionInline, files, answers, severity, boxed, errors: bodyErrors } = parseChunkBody(content, lines, title, body);
31919
31936
  errors.push(...bodyErrors);
31920
31937
  if (files.length === 0 && boxed) errors.push({
31921
31938
  message: `Chunk "${title}" has no file pointers`,
@@ -31929,7 +31946,8 @@ const parseChangesets = (tree, content, lines) => {
31929
31946
  descriptionInline,
31930
31947
  files,
31931
31948
  headingLine,
31932
- ...answers === void 0 ? {} : { answers }
31949
+ ...answers === void 0 ? {} : { answers },
31950
+ ...severity === void 0 ? {} : { severity }
31933
31951
  });
31934
31952
  }
31935
31953
  if (changesets.length === 0) errors.push({ message: "REVIEW.md has no '##' chunks" });
@@ -32230,6 +32248,7 @@ const reviewView = (content) => {
32230
32248
  detail: chunk.description,
32231
32249
  detailInline: chunk.descriptionInline,
32232
32250
  body: chunk.descriptionNodes,
32251
+ ...chunk.severity === void 0 ? {} : { status: chunk.severity.label },
32233
32252
  anchor: {
32234
32253
  kind: "chunk",
32235
32254
  index: chunkIndex
@@ -34779,6 +34798,11 @@ const ChunkRow = ({ chunk, chunkIndex, state }) => {
34779
34798
  disabled: hunks.length === 0,
34780
34799
  className: "flex-1 text-left",
34781
34800
  children: [
34801
+ chunk.status !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
34802
+ "data-testid": `chunk-severity-${chunkIndex}`,
34803
+ className: cn("text-small font-semibold", chunk.status.startsWith("critical") ? "text-warning" : "text-muted"),
34804
+ children: chunk.status
34805
+ }),
34782
34806
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
34783
34807
  className: "font-semibold",
34784
34808
  children: chunk.title
@@ -1,5 +1,5 @@
1
1
  import { changes, changesSince, hasThreadFor, head, mark, read, refuse, requireReplies, requireThreadsClosed, scope } from "./flows.mjs";
2
- import { _ as unansweredNotes, c as stripCodeThreads, g as reviewRisks, h as reviewNotes, m as reviewDecisions, w as parseThreads } from "./chunks/steering-D7hWeMgE.mjs";
2
+ import { E as parseThreads, _ as reviewRisks, c as stripCodeThreads, g as reviewNotes, h as reviewDecisions, y as unansweredNotes } from "./chunks/steering-DtUVUz9l.mjs";
3
3
  //#region src/workflow-kit/health.ts
4
4
  /** Hand a red suite that repeated attempts could not fix to a person, until `limit` rounds are spent. */
5
5
  const escalation = async (count, steps) => {
@@ -1,6 +1,6 @@
1
1
  import { agent, changes, glob, read, refuse, scope, start, vars } from "../flows.mjs";
2
- import { Ct as defaults, It as flagReferences, Rt as registryEntry, S as coder, i as skills, n as summary, o as flagShipped, r as access, t as steering, wt as envDefaults, zt as requireFlag } from "../chunks/reserved-DF1HD6jL.mjs";
3
- import { a as refusePendingHandOff, r as handOffTail } from "../chunks/tail-D89fU_wf.mjs";
2
+ import { At as defaults, Gt as registryEntry, Kt as requireFlag, S as coder, Ut as flagReferences, i as skills, jt as envDefaults, n as summary, o as flagShipped, r as access, t as steering } from "../chunks/reserved-CdOzKFVX.mjs";
3
+ import { a as refusePendingHandOff, r as handOffTail } from "../chunks/tail-DRM2eC1z.mjs";
4
4
  //#region src/workflows/cleanup/cleanup.ts
5
5
  const removingPrompt = (name, registry) => `Clean up the release flag "${name}", which is default-on: delete its entry in ${registry}, and remove every \`GTD_FLAG_${name.toUpperCase()}\` check from the shipped sources. Keep the flag-on path; delete code only the off path reached, including tests that pin the off path.`;
6
6
  const cleanupFlow = async () => {
@@ -1,8 +1,8 @@
1
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, slice, start, vars, wrote } from "../flows.mjs";
2
2
  import { lensEntriesOf } from "../workflow-kit.mjs";
3
- import { $ as naivePassPrompt, B as coverageQuestion, C as collecting, Ct as defaults, F as builderSystem, G as designTriagePrompt, H as criterionLine, I as clearCriteriaMessage, L as clearCriteriaQuestion, M as agentWithSkills, N as buildReviewCollectingPrompt, O as planner, Q as naiveApplyFailure, S as coder, T as fixNits, Tt as testFileGlobs, U as designGateAnswerMessage, V as coveringPrompt, W as designSystem, X as implementBuildingPrompt, Y as idleMessage, Z as implementFixPrompt, _ as REQUIREMENTS, _t as slicingPrompt, a as flagModeOn, at as refactorDroppedRefusal, b as answerReviewQuestions, bt as unwindFailedMessage, ct as refactorRules, d as healthy, et as normaliseCriteriaScript, f as FEEDBACK, g as REFACTOR_NOTE, gt as seamSteerMessage, h as REFACTOR, ht as seamByHandMessage, i as skills, it as refactorBuildingPrompt, l as gate, mt as reviewerSystem, n as summary, ot as refactorFixPrompt, p as HANDOFF, r as access, s as shipped, st as refactorNotePrompt, t as steering, tt as oversizedMessage, vt as startGateBlockedMessage, wt as envDefaults, xt as unwindFailure, y as SLICES, yt as uncoveredMessage, z as coverageMessage } from "../chunks/reserved-DF1HD6jL.mjs";
4
- import { a as refusePendingHandOff, c as joinReports, o as tail } from "../chunks/tail-D89fU_wf.mjs";
5
- import { i as reUnwind, n as humanReview, r as isCode$1, t as buildTail } from "../chunks/review-Bv40kZu9.mjs";
3
+ import { $ as naiveApplyFailure, At as defaults, B as coverageMessage, C as collecting, Ct as uncoveredMessage, Et as unwindFailure, F as builderSystem, G as designSystem, H as coveringPrompt, K as designTriagePrompt, L as clearCriteriaMessage, M as agentWithSkills, Mt as testFileGlobs, N as buildReviewCollectingPrompt, O as planner, Q as implementFixPrompt, R as clearCriteriaQuestion, S as coder, T as fixNits, Tt as unwindFailedMessage, U as criterionLine, V as coverageQuestion, W as designGateAnswerMessage, X as idleMessage, Z as implementBuildingPrompt, _ as REQUIREMENTS, _t as reviewerSystem, a as flagModeOn, b as answerReviewQuestions, bt as slicingPrompt, ct as refactorFixPrompt, d as healthy, et as naivePassPrompt, f as FEEDBACK, g as REFACTOR_NOTE, h as REFACTOR, i as skills, jt as envDefaults, l as gate, lt as refactorNotePrompt, n as summary, nt as oversizedMessage, ot as refactorBuildingPrompt, p as HANDOFF, r as access, s as shipped, st as refactorDroppedRefusal, t as steering, tt as normaliseCriteriaScript, ut as refactorRules, vt as seamByHandMessage, xt as startGateBlockedMessage, y as SLICES, yt as seamSteerMessage } from "../chunks/reserved-CdOzKFVX.mjs";
4
+ import { a as refusePendingHandOff, c as joinReports, o as tail } from "../chunks/tail-DRM2eC1z.mjs";
5
+ import { i as reUnwind, n as humanReview, r as isCode$1, t as buildTail } from "../chunks/review-BChXEl2Y.mjs";
6
6
  import { posix } from "node:path";
7
7
  //#region src/workflows/shared/fences.ts
8
8
  const markFenced = (text) => {
@@ -1171,14 +1171,21 @@ const buildSlice = async (sliceBase, build) => {
1171
1171
  });
1172
1172
  });
1173
1173
  };
1174
- /** The quality lap of slice `last.slice`, then the human review since `base`, listing what earlier slices' `laps` left too. */
1174
+ /**
1175
+ * The quality lap of slice `last.slice`, then a reviewer's walkthrough since
1176
+ * `base` for the human, carrying what earlier slices' `laps` left too.
1177
+ */
1175
1178
  const reviewedTail = (base, lensBase, last = {
1176
1179
  slice: "",
1177
1180
  laps: []
1178
- }) => tail((escalations, report) => humanReview(base, escalations, { report: last.laps.length === 0 ? report : joinReports([...last.laps, {
1179
- slice: last.slice,
1180
- report
1181
- }]) }), {
1181
+ }, lap = "first") => tail((escalations, report) => humanReview(base, escalations, {
1182
+ report: last.laps.length === 0 ? report : joinReports([...last.laps, {
1183
+ slice: last.slice,
1184
+ report
1185
+ }]),
1186
+ walkthrough: true,
1187
+ lap
1188
+ }), {
1182
1189
  green: true,
1183
1190
  lensBase
1184
1191
  });
@@ -1200,7 +1207,7 @@ const featureFeedback = async (first, lensBase, ids) => {
1200
1207
  tier: riskTierOn() ? recordRisk() : void 0,
1201
1208
  amend: true
1202
1209
  });
1203
- outcome = await reviewedTail(outcome.base, lensBase);
1210
+ outcome = await reviewedTail(outcome.base, lensBase, void 0, "feedback");
1204
1211
  }
1205
1212
  };
1206
1213
  /** Design — skipped when the sketch's own criteria are judged clear — then `buildFeature`. */
@@ -1,7 +1,7 @@
1
1
  import { read, refuse, removeScript, run, scope, start } from "../flows.mjs";
2
- import { g as reviewRisks, h as reviewNotes } from "../chunks/steering-D7hWeMgE.mjs";
3
- import { Ct as defaults, K as finisherSystem, M as agentWithSkills, S as coder, c as baseline, i as skills, n as summary, q as fixReviewNotesPrompt, r as access, s as shipped, t as steering, v as REVIEW, wt as envDefaults } from "../chunks/reserved-DF1HD6jL.mjs";
4
- import { r as handOffTail, t as REVIEW_ORIG } from "../chunks/tail-D89fU_wf.mjs";
2
+ import { _ as reviewRisks, g as reviewNotes } from "../chunks/steering-DtUVUz9l.mjs";
3
+ import { At as defaults, J as fixReviewNotesPrompt, M as agentWithSkills, S as coder, c as baseline, i as skills, jt as envDefaults, n as summary, q as finisherSystem, r as access, s as shipped, t as steering, v as REVIEW } from "../chunks/reserved-CdOzKFVX.mjs";
4
+ import { r as handOffTail, t as REVIEW_ORIG } from "../chunks/tail-DRM2eC1z.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 { Ct as defaults, K as finisherSystem, M as agentWithSkills, S as coder, _ as REQUIREMENTS, dt as reviewFeedbackFixPrompt, ft as reviewGateBlockedMessage, i as skills, l as gate, n as summary, r as access, s as shipped, t as steering, wt as envDefaults } from "../chunks/reserved-DF1HD6jL.mjs";
3
- import { a as refusePendingHandOff } from "../chunks/tail-D89fU_wf.mjs";
4
- import { i as reUnwind, t as buildTail } from "../chunks/review-Bv40kZu9.mjs";
2
+ import { At as defaults, M as agentWithSkills, S as coder, _ as REQUIREMENTS, i as skills, jt as envDefaults, l as gate, mt as reviewGateBlockedMessage, n as summary, pt as reviewFeedbackFixPrompt, q as finisherSystem, r as access, s as shipped, t as steering } from "../chunks/reserved-CdOzKFVX.mjs";
3
+ import { a as refusePendingHandOff } from "../chunks/tail-DRM2eC1z.mjs";
4
+ import { i as reUnwind, t as buildTail } from "../chunks/review-BChXEl2Y.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 { Ct as defaults, Ft as flagMentions, Lt as flipProblems, S as coder, f as FEEDBACK, i as skills, l as gate, n as summary, o as flagShipped, r as access, t as steering, wt as envDefaults, zt as requireFlag } from "../chunks/reserved-DF1HD6jL.mjs";
2
+ import { At as defaults, Ht as flagMentions, Kt as requireFlag, S as coder, Wt as flipProblems, f as FEEDBACK, i as skills, jt as envDefaults, l as gate, n as summary, o as flagShipped, r as access, t as steering } from "../chunks/reserved-CdOzKFVX.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.";