@pmelab/gtd 57.0.0 → 58.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.
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +12 -10
- package/dist/chunks/{Schema-C6fLlQzx.mjs → Schema-B3o6eRNU.mjs} +637 -3957
- package/dist/chunks/{reserved-X2RkNHin.mjs → reserved-lMYCaapY.mjs} +27 -20
- package/dist/chunks/{review-v7sh5GF4.mjs → review-Bfaror38.mjs} +2 -2
- package/dist/chunks/{tail-S04KEewi.mjs → tail-Bd7L940p.mjs} +1 -1
- package/dist/chunks/testkit-D1-auYau.mjs +10362 -0
- package/dist/gtd.bundle.mjs +8 -8
- package/dist/testkit/gherkin.mjs +255 -0
- package/dist/testkit.mjs +2 -15461
- package/dist/workflows/cleanup.mjs +2 -2
- package/dist/workflows/feature.mjs +52 -13
- package/dist/workflows/fix.mjs +2 -2
- package/dist/workflows/review.mjs +3 -3
- package/dist/workflows/rollout.mjs +1 -1
- package/dist/workflows.mjs +74 -28
- package/package.json +8 -1
- package/src/cli/Cli.test.ts +1 -1
- package/src/cli/History.test.ts +1 -1
- package/src/cli/Metrics.test.ts +1 -1
- package/src/cli/Program.test.ts +1 -1
- package/src/cli/Strays.test.ts +1 -1
- package/src/edge/Edge.test.ts +1 -1
- package/src/emit/Emit.ts +1 -1
- package/src/emit/GitScript.ts +1 -1
- package/src/emit/OutcomeScript.ts +1 -1
- package/src/{testkit/steps.ts → gherkin/index.ts} +20 -3
- package/src/gherkin/module-config.feature +24 -0
- package/src/gherkin/tiny.fixture.ts +8 -0
- package/src/platform/Git.test.ts +2 -2
- package/src/platform/RetainedHistory.test.ts +2 -2
- package/src/platform/Workspace.test.ts +2 -2
- package/src/platform/WorktreeState.test.ts +1 -1
- package/src/step/planStart.test.ts +1 -1
- package/src/testkit/TestRepo.ts +7 -4
- package/src/testkit/index.ts +15 -9
- package/src/{testkit → twins}/Layers.ts +2 -2
- package/src/twins/index.ts +8 -0
- package/src/workflow/discovery.test.ts +1 -1
- package/src/workflow/discovery.ts +3 -3
- package/src/workflow/load.ts +3 -3
- package/src/workflows/feature/acceptance-criteria.feature +32 -0
- package/src/workflows/feature/criteria-coverage.feature +0 -1
- package/src/workflows/feature/criteria.ts +10 -4
- package/src/workflows/feature/fast-path.feature +4 -0
- package/src/workflows/feature/feature.test.ts +3 -39
- package/src/workflows/feature/feature.ts +3 -4
- package/src/workflows/feature/lens-models.feature +0 -1
- package/src/workflows/feature/lens-review.feature +0 -1
- package/src/workflows/feature/naive-acceptance.feature +4 -0
- package/src/workflows/feature/naive-test.feature +11 -6
- package/src/workflows/feature/one-step-land.feature +4 -0
- package/src/workflows/feature/planning.ts +2 -0
- package/src/workflows/feature/refactor-absorbs.feature +4 -0
- package/src/workflows/feature/refactor-first.feature +4 -0
- package/src/workflows/feature/refactor-lens-models.feature +4 -0
- package/src/workflows/feature/refactor-rebuild.feature +4 -0
- package/src/workflows/feature/refactor-review.feature +20 -0
- package/src/workflows/feature/release-flag.feature +167 -0
- package/src/workflows/feature/release-flag.test.ts +49 -0
- package/src/workflows/feature/release-flag.ts +46 -0
- package/src/workflows/feature/review-gate.feature +0 -1
- package/src/workflows/feature/reviewer-walkthrough.feature +0 -1
- package/src/workflows/feature/risk-tier.feature +32 -0
- package/src/workflows/feature/seam-rejection.feature +8 -0
- package/src/workflows/feature/seam.feature +8 -0
- package/src/workflows/feature/seam.test.ts +20 -7
- package/src/workflows/feature/seam.ts +7 -7
- package/src/workflows/feature/standards.feature +0 -1
- package/src/workflows/shared/options.test.ts +3 -10
- package/src/workflows/shared/options.ts +0 -9
- package/src/workflows/shared/text.test.ts +36 -28
- package/src/workflows/shared/text.ts +37 -20
- package/src/workflows/shared/vars.ts +0 -1
- package/src/workflows/feature/flag-mode.feature +0 -88
- /package/src/{testkit → gherkin}/testkit.feature +0 -0
- /package/src/{testkit → twins}/EmittedScriptRecognizer.test.ts +0 -0
- /package/src/{testkit → twins}/EmittedScriptRecognizer.ts +0 -0
- /package/src/{testkit → twins}/EmittedScripts.test.ts +0 -0
- /package/src/{testkit → twins}/FakeGitOperations.ts +0 -0
- /package/src/{testkit → twins}/FlowScripts.test.ts +0 -0
- /package/src/{testkit → twins}/FlowScripts.ts +0 -0
- /package/src/{testkit → twins}/GitTiers.test.ts +0 -0
- /package/src/{testkit → twins}/GitTiers.ts +0 -0
- /package/src/{testkit → twins}/InMemRepo.ts +0 -0
- /package/src/{testkit → twins}/Layers.test.ts +0 -0
- /package/src/{testkit → twins}/StrictGitOperations.ts +0 -0
- /package/src/{testkit → twins}/cliIo.ts +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { accessFor, agent, answered, changesSince, check, codeThreads, defineWorkflow, displayPath, env, head, human, judge, mark, numeric, quote, read, refuse, scope, skillsFor, start, vars } from "../flows.mjs";
|
|
2
2
|
import { f as NOISE_HEADING, h as ANSWER_LEAD, v as reviewChunks, w as FREE_TEXT_PLACEHOLDER } from "./steering-CCNvngSH.mjs";
|
|
3
3
|
import { gate as gate$1, healthy as healthy$1, lensScopes, lensesOf, removedAssertions } from "../workflow-kit.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { d as optionalWith, f as standardSchemaV1, n as Boolean$, o as String$, s as Struct } from "./Schema-B3o6eRNU.mjs";
|
|
5
5
|
//#region src/workflows/shared/registry.ts
|
|
6
6
|
const FILL = "";
|
|
7
7
|
const commentLength = (rest) => {
|
|
@@ -237,7 +237,6 @@ const defaults = {
|
|
|
237
237
|
standardMinP: "0.8",
|
|
238
238
|
refactorFlagPattern: "\\bGTD_FLAG_\\w+",
|
|
239
239
|
seamAllow: [...testFileGlobs, ".gtd/**"].join(", "),
|
|
240
|
-
flagMode: "true",
|
|
241
240
|
naiveTest: "false",
|
|
242
241
|
flag_risk_tier: "0",
|
|
243
242
|
qualityReviews: "correctness, owasp-security, ponytail-review, test-audit, conventions, spec-challenge, criteria-coverage",
|
|
@@ -671,6 +670,18 @@ in its docs or agent instructions (\`AGENTS.md\`, \`CLAUDE.md\`). When
|
|
|
671
670
|
none is declared, fall back to directories and packages. Landing is
|
|
672
671
|
refused while the section is missing.
|
|
673
672
|
`;
|
|
673
|
+
const releaseFlagBlock = `
|
|
674
|
+
## Release flag
|
|
675
|
+
|
|
676
|
+
Only when the sketch asks outright for the change to ship behind a
|
|
677
|
+
feature or release flag, \`.gtd/REQUIREMENTS.md\` carries a
|
|
678
|
+
\`## Release Flag\` section whose first line is \`new\` (a new
|
|
679
|
+
flag) or \`existing: <NAME>\` (behind a flag that already exists,
|
|
680
|
+
named as the sketch names it). Never add one on your own judgement:
|
|
681
|
+
without the section the change ships unflagged. A later lap keeps the
|
|
682
|
+
section exactly as the last settled file had it, unless the human
|
|
683
|
+
changed it. Landing is refused while its first line is anything else.
|
|
684
|
+
`;
|
|
674
685
|
const riskTierBlock = `
|
|
675
686
|
## Risk tier and production signals
|
|
676
687
|
|
|
@@ -710,7 +721,7 @@ ${footnoteFoldIn}${codeThreadReplies()}
|
|
|
710
721
|
or both
|
|
711
722
|
- Whichever lap this is, leave \`.gtd/REQUIREMENTS.md\`
|
|
712
723
|
uncommitted and finish once it reflects this lap's own work
|
|
713
|
-
${acceptanceCriteriaBlock}${impactBlock}
|
|
724
|
+
${acceptanceCriteriaBlock}${impactBlock}${releaseFlagBlock}
|
|
714
725
|
Every lap re-explores and leaves \`## Impact\` present. On a return
|
|
715
726
|
lap or review loop-back the human may have edited \`## Impact\` (or
|
|
716
727
|
footnoted it): read that edit from history (\`git log -1 -p --
|
|
@@ -780,11 +791,12 @@ ${stateFileRules}
|
|
|
780
791
|
- The only state file this turn touches is \`.gtd/REQUIREMENTS.md\`
|
|
781
792
|
— no other files for notes or output
|
|
782
793
|
- \`.gtd/REQUIREMENTS.md\` already holds the settled acceptance
|
|
783
|
-
criteria. Add a \`## Impact\` section and
|
|
784
|
-
|
|
794
|
+
criteria. Add a \`## Impact\` section — and a \`## Release Flag\`
|
|
795
|
+
section when the sketch asks for one — and change nothing else: a
|
|
796
|
+
turn that touches anything outside them is refused
|
|
785
797
|
- No human reviews this before the build: put any surprise in the
|
|
786
798
|
Impact prose, never as a question
|
|
787
|
-
${impactBlock}
|
|
799
|
+
${impactBlock}${releaseFlagBlock}
|
|
788
800
|
- Leave \`.gtd/REQUIREMENTS.md\` uncommitted and finish once it holds \`## Impact\`
|
|
789
801
|
`;
|
|
790
802
|
const clearCriteriaQuestion = {
|
|
@@ -843,6 +855,7 @@ What each change does next (then run \`gtd land\`):
|
|
|
843
855
|
- **Accept as-is** — change nothing and re-run; the plan stands as written. Refused while a thread is open.
|
|
844
856
|
- **Revise answers** — tick exactly one option per open question (replace \`_your answer_\` for your own) to send it back for the agent to fold your answers in, or delete a question to skip it.
|
|
845
857
|
- **Discuss** — start or continue a thread (\`- H:\`); the agent replies and this gate stops again.
|
|
858
|
+
- **Ask for a release flag** — add \`## Release Flag\` with \`new\` or \`existing: <NAME>\` as its first line, or delete the section to ship unflagged.
|
|
846
859
|
${riskTier ? RISK_TIER_GATE_LINE : ""}`;
|
|
847
860
|
const builderSystem = () => `${builderPersona}
|
|
848
861
|
|
|
@@ -1522,21 +1535,22 @@ const afterRefactorLine = (rebuild) => `- A reviewed refactor has just landed an
|
|
|
1522
1535
|
though never a release flag. Build only what is still missing, held to every
|
|
1523
1536
|
rule below; if nothing is, ${carries(rebuild) ? "carry over the acceptance tests below and change nothing else" : "change nothing and finish your turn"}
|
|
1524
1537
|
`;
|
|
1525
|
-
const flagLine = (
|
|
1526
|
-
|
|
1527
|
-
|
|
1538
|
+
const flagLine = (flag, amend) => flag.kind === "none" ? "- Add no release flag — the requirements ask for none" : flag.kind === "existing" ? `- Put the new behaviour behind the existing flag \`${flag.name}\`, as the
|
|
1539
|
+
requirements ask — add no new flag` : amend === true ? "- Keep the release flag the earlier lap added, if it added one; otherwise put\n the behaviour behind a new release flag" : `- Put the new behaviour behind a new release flag, as the requirements ask,
|
|
1540
|
+
following the repository's flag conventions`;
|
|
1541
|
+
const implementBuildingPrompt = (reference, amend, afterRefactor, flag = { kind: "none" }, rebuild = {}) => `${stateFileRules}
|
|
1528
1542
|
- Read \`.gtd/REQUIREMENTS.md\`: the settled requirements for this change
|
|
1529
1543
|
${impactHints}
|
|
1530
1544
|
${criteriaBinding(true)}
|
|
1531
1545
|
${afterRefactor === true ? afterRefactorLine(rebuild) : ""}${amend === true ? `- The change already exists in the tree from an earlier lap; amend it to meet
|
|
1532
1546
|
the re-derived requirements instead of rewriting it
|
|
1533
|
-
` :
|
|
1547
|
+
` : flag.kind !== "none" ? `- Implement them properly, fitting the codebase's seams and conventions
|
|
1534
1548
|
` : `- Implement them the quickest way that works — the naive version. Do not
|
|
1535
1549
|
restructure, abstract or refactor around the change
|
|
1536
1550
|
`}${reference === void 0 || amend === true ? "" : `- Reference only: \`git show ${reference}\` shows an earlier naive attempt.
|
|
1537
1551
|
Read it for ideas; never apply, cherry-pick or check it out — write
|
|
1538
1552
|
the change fresh${carries(rebuild) ? ", its acceptance tests excepted (below)" : ""}
|
|
1539
|
-
`}${rebuildLines(rebuild)}${flagLine(
|
|
1553
|
+
`}${rebuildLines(rebuild)}${flagLine(flag, amend)}
|
|
1540
1554
|
- Write the tests first, then the code that makes them pass
|
|
1541
1555
|
${behaviourTests}
|
|
1542
1556
|
- Leave \`.gtd/REQUIREMENTS.md\` in place and everything uncommitted, then
|
|
@@ -1555,7 +1569,7 @@ An edit together with an approval counts as steer. Only
|
|
|
1555
1569
|
\`.gtd/REQUIREMENTS.md\` is meant to change here: any other edit lands on the
|
|
1556
1570
|
branch unjudged.
|
|
1557
1571
|
`;
|
|
1558
|
-
/** `judged`: whether an overruled pass still meets the seam judge (
|
|
1572
|
+
/** `judged`: whether an overruled pass still meets the seam judge (a release flag asked for). */
|
|
1559
1573
|
const seamSteerMessage = (retry, judged = true) => isFault(retry) ? `The naive pass failed three times and the retries are spent. The last
|
|
1560
1574
|
attempt's tests (\`git show ${retry.hash}\`) fall short:
|
|
1561
1575
|
${retry.fault}
|
|
@@ -1879,19 +1893,12 @@ const ShippedOptions = Struct({
|
|
|
1879
1893
|
testCommand: setting,
|
|
1880
1894
|
plannerModel: setting,
|
|
1881
1895
|
coderModel: setting,
|
|
1882
|
-
flagMode: optionalWith(Boolean$, { exact: true }),
|
|
1883
1896
|
naiveTest: optionalWith(Boolean$, { exact: true })
|
|
1884
1897
|
});
|
|
1885
1898
|
const over = (base, options) => ({
|
|
1886
1899
|
...base,
|
|
1887
1900
|
...Object.fromEntries(Object.entries(options).filter(([name]) => Object.hasOwn(base, name)).map(([name, value]) => [name, String(value)]))
|
|
1888
1901
|
});
|
|
1889
|
-
/** The `flagMode` setting, pinned at process start. Anything but true/false fails rather than guess a side. */
|
|
1890
|
-
const flagModeOn = () => {
|
|
1891
|
-
const value = vars.flagMode ?? defaults.flagMode;
|
|
1892
|
-
if (value !== "true" && value !== "false") refuse(`gtd: flagMode must be "true" or "false", got ${JSON.stringify(value)}`);
|
|
1893
|
-
return value === "true";
|
|
1894
|
-
};
|
|
1895
1902
|
/** The `naiveTest` setting, pinned at process start. Anything but true/false fails rather than guess. */
|
|
1896
1903
|
const naiveTestOn = () => {
|
|
1897
1904
|
const value = vars.naiveTest ?? defaults.naiveTest;
|
|
@@ -1980,4 +1987,4 @@ const steering = {
|
|
|
1980
1987
|
[REVIEW]: "review"
|
|
1981
1988
|
};
|
|
1982
1989
|
//#endregion
|
|
1983
|
-
export {
|
|
1990
|
+
export { nitFixBlock as $, reviewing as A, parseStandards as At, designSystem as B, fixCheck as C, testFileGlobs as Ct, planner as D, conflictTitle as Dt, fixRisks as E, conflictFor as Et, clearCriteriaMessage as F, flipProblems as Ft, fixReviewNotesPrompt as G, findingGateFile as H, clearCriteriaQuestion as I, registryEntry as It, implementBuildingPrompt as J, handOffAwaitReviewMessage as K, criterionLine as L, requireFlag as Lt, buildReviewCollectingPrompt as M, standardKey as Mt, buildReviewTriageMessage as N, flagMentions as Nt, reviewMissing as O, isConflictTitle as Ot, builderSystem as P, flagReferences as Pt, naiveTryMessage as Q, designGateAnswerMessage as R, collecting as S, envDefaults as St, fixQuality as T, conflictBody as Tt, findingGateMessage as U, designTriagePrompt as V, finisherSystem as W, naiveApplyFailure as X, implementFixPrompt as Y, naivePassPrompt as Z, REQUIREMENTS as _, unwindFailedMessage as _t, flagShipped as a, refactorFixPrompt as at, awaitReview as b, withSummary as bt, baseline as c, reviewEditNotesCapture as ct, healthy as d, reviewGateBlockedMessage as dt, normaliseCriteriaScript as et, FEEDBACK as f, reviewNotesCapture as ft, REFACTOR_NOTE as g, startGateBlockedMessage as gt, REFACTOR as h, seamSteerMessage as ht, skills as i, refactorDroppedRefusal as it, agentWithSkills as j, renderStandards as jt, reviewQuality as k, oneLine as kt, gate as l, reviewEditsCapture as lt, QUALITY as m, seamByHandMessage as mt, summary as n, qualityTriageMessage as nt, naiveTestOn as o, refactorNotePrompt as ot, NAIVE_TEST as p, reviewerSystem as pt, idleMessage as q, access as r, refactorBuildingPrompt as rt, shipped as s, refactorRules as st, steering as t, qualityFindingsFile as tt, guarded as u, reviewFeedbackFixPrompt as ut, REVIEW as v, unwindFailure as vt, fixNits as w, STANDARDS as wt, coder as x, defaults as xt, answerReviewQuestions as y, withGuidance as yt, designImpactPrompt as z };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { answered, changesSince, head, judge, numeric, read, refuse, requireRevert, restoreScript, run, vars, writeScript } from "../flows.mjs";
|
|
2
2
|
import { S as reviewSections, _ as REVIEW_SECTIONS, v as reviewChunks, x as reviewRisks } from "./steering-CCNvngSH.mjs";
|
|
3
3
|
import { review } from "../workflow-kit.mjs";
|
|
4
|
-
import { At as
|
|
5
|
-
import { i as isOptionalObject, n as closeReview, o as tail, s as NO_FINDINGS } from "./tail-
|
|
4
|
+
import { $ as nitFixBlock, A as reviewing, At as parseStandards, C as fixCheck, Dt as conflictTitle, E as fixRisks, Et as conflictFor, Mt as standardKey, N as buildReviewTriageMessage, O as reviewMissing, Ot as isConflictTitle, S as collecting, Tt as conflictBody, b as awaitReview, bt as withSummary, ct as reviewEditNotesCapture, d as healthy, ft as reviewNotesCapture, jt as renderStandards, kt as oneLine, lt as reviewEditsCapture, u as guarded, v as REVIEW, w as fixNits, wt as STANDARDS, y as answerReviewQuestions } from "./reserved-lMYCaapY.mjs";
|
|
5
|
+
import { i as isOptionalObject, n as closeReview, o as tail, s as NO_FINDINGS } from "./tail-Bd7L940p.mjs";
|
|
6
6
|
//#region src/workflows/shared/learn.ts
|
|
7
7
|
const SUMMARY_MAX = 200;
|
|
8
8
|
const summary = (body) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { answered, head, human, judge, mark, numeric, read, refuse, removeScript, run, scope, sectionBodies, showScript, vars, writeScript } from "../flows.mjs";
|
|
2
2
|
import { F as formatFinding, p as findingEntries, r as steeringFormatFor, x as reviewRisks } from "./steering-CCNvngSH.mjs";
|
|
3
3
|
import { lensEntriesOf, lensOf, qualityLap, reviewToHandOff } from "../workflow-kit.mjs";
|
|
4
|
-
import { A as
|
|
4
|
+
import { A as reviewing, C as fixCheck, E as fixRisks, H as findingGateFile, K as handOffAwaitReviewMessage, O as reviewMissing, T as fixQuality, U as findingGateMessage, b as awaitReview, bt as withSummary, d as healthy, k as reviewQuality, m as QUALITY, nt as qualityTriageMessage, tt as qualityFindingsFile, u as guarded, v as REVIEW, yt as withGuidance } from "./reserved-lMYCaapY.mjs";
|
|
5
5
|
//#region src/workflows/shared/lenses.ts
|
|
6
6
|
const NO_FINDINGS = {
|
|
7
7
|
fixed: [],
|