@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
|
@@ -30,16 +30,9 @@ describe("the shipped workflow factories", () => {
|
|
|
30
30
|
})
|
|
31
31
|
})
|
|
32
32
|
|
|
33
|
-
it("
|
|
34
|
-
expect(defaults.flagMode).
|
|
35
|
-
expect(configure(feature({ flagMode: false }))).toMatchObject({
|
|
36
|
-
ok: true,
|
|
37
|
-
build: { defaults: { flagMode: "false" } },
|
|
38
|
-
})
|
|
39
|
-
expect(configure(review({ flagMode: true }))).toMatchObject({
|
|
40
|
-
ok: true,
|
|
41
|
-
build: { defaults: { flagMode: "true" } },
|
|
42
|
-
})
|
|
33
|
+
it("refuse the removed flagMode option", () => {
|
|
34
|
+
expect(defaults.flagMode).toBeUndefined()
|
|
35
|
+
expect(configure(feature({ flagMode: false } as never))).toMatchObject({ ok: false })
|
|
43
36
|
})
|
|
44
37
|
|
|
45
38
|
it("declare flag_risk_tier off by default; it is no factory option", () => {
|
|
@@ -27,7 +27,6 @@ export const ShippedOptions = Schema.Struct({
|
|
|
27
27
|
testCommand: setting,
|
|
28
28
|
plannerModel: setting,
|
|
29
29
|
coderModel: setting,
|
|
30
|
-
flagMode: Schema.optionalWith(Schema.Boolean, { exact: true }),
|
|
31
30
|
naiveTest: Schema.optionalWith(Schema.Boolean, { exact: true }),
|
|
32
31
|
})
|
|
33
32
|
|
|
@@ -45,14 +44,6 @@ const over = (
|
|
|
45
44
|
),
|
|
46
45
|
})
|
|
47
46
|
|
|
48
|
-
/** The `flagMode` setting, pinned at process start. Anything but true/false fails rather than guess a side. */
|
|
49
|
-
export const flagModeOn = (): boolean => {
|
|
50
|
-
const value = vars.flagMode ?? defaults.flagMode!
|
|
51
|
-
if (value !== "true" && value !== "false")
|
|
52
|
-
refuse(`gtd: flagMode must be "true" or "false", got ${JSON.stringify(value)}`)
|
|
53
|
-
return value === "true"
|
|
54
|
-
}
|
|
55
|
-
|
|
56
47
|
/** The `naiveTest` setting, pinned at process start. Anything but true/false fails rather than guess. */
|
|
57
48
|
export const naiveTestOn = (): boolean => {
|
|
58
49
|
const value = vars.naiveTest ?? defaults.naiveTest!
|
|
@@ -912,45 +912,53 @@ describe("the seam phase's texts", () => {
|
|
|
912
912
|
expect(prompt).not.toContain("rejected")
|
|
913
913
|
})
|
|
914
914
|
|
|
915
|
-
it("cites the reference as reading material only
|
|
915
|
+
it("cites the reference as reading material only", () => {
|
|
916
916
|
const prompt = renderText(() => implementBuildingPrompt("abc123"))
|
|
917
917
|
expect(prompt).toContain("git show abc123")
|
|
918
918
|
expect(prompt).toContain("never apply")
|
|
919
|
-
expect(prompt).toContain("release flag")
|
|
920
|
-
})
|
|
921
|
-
|
|
922
|
-
it("high and undefined tiers carry the flag bullet; low says to add none", () => {
|
|
923
|
-
const base = renderText(() => implementBuildingPrompt("abc123"))
|
|
924
|
-
expect(renderText(() => implementBuildingPrompt("abc123", "high"))).toBe(base)
|
|
925
|
-
expect(base).toContain("new release flag")
|
|
926
|
-
const low = renderText(() => implementBuildingPrompt("abc123", "low"))
|
|
927
|
-
expect(low).toContain("Add no release flag — this change is low risk tier")
|
|
928
|
-
expect(low).not.toContain("new release flag")
|
|
929
|
-
expect(low).toContain("git show abc123")
|
|
930
919
|
})
|
|
931
920
|
|
|
932
921
|
it("drops the git show line when there is no reference", () => {
|
|
933
|
-
const prompt = renderText(() => implementBuildingPrompt(undefined
|
|
922
|
+
const prompt = renderText(() => implementBuildingPrompt(undefined))
|
|
934
923
|
expect(prompt).not.toContain("git show")
|
|
935
924
|
expect(prompt).not.toContain("Reference only")
|
|
936
|
-
expect(prompt).toContain("Add no release flag")
|
|
937
|
-
expect(prompt).toContain("Implement them properly")
|
|
938
925
|
})
|
|
939
926
|
|
|
940
|
-
it("
|
|
941
|
-
for (const [
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
["high", true],
|
|
945
|
-
] as const) {
|
|
946
|
-
const prompt = renderText(() => implementBuildingPrompt(undefined, tier, amend, false, false))
|
|
947
|
-
expect(prompt).toContain("Add no release flag — this project ships without release flags")
|
|
927
|
+
it("asks for no flag and the naive version when the requirements ask for none, on any lap", () => {
|
|
928
|
+
for (const amend of [false, true]) {
|
|
929
|
+
const prompt = renderText(() => implementBuildingPrompt(undefined, amend))
|
|
930
|
+
expect(prompt).toContain("Add no release flag — the requirements ask for none")
|
|
948
931
|
expect(prompt).not.toContain("new release flag")
|
|
949
|
-
expect(prompt).not.toContain("low risk tier")
|
|
950
932
|
}
|
|
951
|
-
expect(
|
|
952
|
-
|
|
953
|
-
)
|
|
933
|
+
expect(renderText(() => implementBuildingPrompt(undefined))).toContain(
|
|
934
|
+
"the quickest way that works",
|
|
935
|
+
)
|
|
936
|
+
})
|
|
937
|
+
|
|
938
|
+
it("asks for a new flag, kept on a later lap, when the requirements ask for one", () => {
|
|
939
|
+
const first = renderText(() => implementBuildingPrompt("abc123", false, false, { kind: "new" }))
|
|
940
|
+
expect(first).toContain("behind a new release flag, as the requirements ask")
|
|
941
|
+
expect(first).toContain("Implement them properly")
|
|
942
|
+
const amend = renderText(() => implementBuildingPrompt(undefined, true, false, { kind: "new" }))
|
|
943
|
+
expect(amend).toContain("Keep the release flag the earlier lap added")
|
|
944
|
+
})
|
|
945
|
+
|
|
946
|
+
it("names the existing flag the requirements ask for, and asks for no new one", () => {
|
|
947
|
+
const prompt = renderText(() =>
|
|
948
|
+
implementBuildingPrompt(undefined, false, false, { kind: "existing", name: "GTD_FLAG_BETA" }),
|
|
949
|
+
)
|
|
950
|
+
expect(prompt).toContain("behind the existing flag `GTD_FLAG_BETA`")
|
|
951
|
+
expect(prompt).toContain("add no new flag")
|
|
952
|
+
expect(prompt).toContain("Implement them properly")
|
|
953
|
+
})
|
|
954
|
+
|
|
955
|
+
it("explains the Release Flag section at triage, at the impact turn and at the design gate", () => {
|
|
956
|
+
for (const prompt of [() => designTriagePrompt("base"), () => designImpactPrompt()]) {
|
|
957
|
+
const text = renderText(prompt)
|
|
958
|
+
expect(text).toContain("`## Release Flag`")
|
|
959
|
+
expect(text).toContain("Never add one on your own judgement")
|
|
960
|
+
}
|
|
961
|
+
expect(renderText(() => designGateAnswerMessage())).toContain("**Ask for a release flag**")
|
|
954
962
|
})
|
|
955
963
|
|
|
956
964
|
it("keeps a fix turn to the feedback file's rules", () => {
|
|
@@ -992,7 +1000,7 @@ describe("the seam phase's texts", () => {
|
|
|
992
1000
|
expect(message).not.toContain("outside the expected set")
|
|
993
1001
|
})
|
|
994
1002
|
|
|
995
|
-
it("promises no judge on an overrule
|
|
1003
|
+
it("promises no judge on an overrule when no release flag is asked for", () => {
|
|
996
1004
|
for (const retry of [{ red: "abc123" }, { fault: "acceptance-internals: x", hash: "abc123" }]) {
|
|
997
1005
|
const message = renderText(() => seamSteerMessage(retry, false))
|
|
998
1006
|
expect(message).not.toContain("seam judge")
|
|
@@ -348,6 +348,19 @@ none is declared, fall back to directories and packages. Landing is
|
|
|
348
348
|
refused while the section is missing.
|
|
349
349
|
`
|
|
350
350
|
|
|
351
|
+
const releaseFlagBlock = `
|
|
352
|
+
## Release flag
|
|
353
|
+
|
|
354
|
+
Only when the sketch asks outright for the change to ship behind a
|
|
355
|
+
feature or release flag, \`.gtd/REQUIREMENTS.md\` carries a
|
|
356
|
+
\`## Release Flag\` section whose first line is \`new\` (a new
|
|
357
|
+
flag) or \`existing: <NAME>\` (behind a flag that already exists,
|
|
358
|
+
named as the sketch names it). Never add one on your own judgement:
|
|
359
|
+
without the section the change ships unflagged. A later lap keeps the
|
|
360
|
+
section exactly as the last settled file had it, unless the human
|
|
361
|
+
changed it. Landing is refused while its first line is anything else.
|
|
362
|
+
`
|
|
363
|
+
|
|
351
364
|
const riskTierBlock = `
|
|
352
365
|
## Risk tier and production signals
|
|
353
366
|
|
|
@@ -389,7 +402,7 @@ ${footnoteFoldIn}${codeThreadReplies()}
|
|
|
389
402
|
or both
|
|
390
403
|
- Whichever lap this is, leave \`.gtd/REQUIREMENTS.md\`
|
|
391
404
|
uncommitted and finish once it reflects this lap's own work
|
|
392
|
-
${acceptanceCriteriaBlock}${impactBlock}
|
|
405
|
+
${acceptanceCriteriaBlock}${impactBlock}${releaseFlagBlock}
|
|
393
406
|
Every lap re-explores and leaves \`## Impact\` present. On a return
|
|
394
407
|
lap or review loop-back the human may have edited \`## Impact\` (or
|
|
395
408
|
footnoted it): read that edit from history (\`git log -1 -p --
|
|
@@ -461,11 +474,12 @@ ${stateFileRules}
|
|
|
461
474
|
- The only state file this turn touches is \`.gtd/REQUIREMENTS.md\`
|
|
462
475
|
— no other files for notes or output
|
|
463
476
|
- \`.gtd/REQUIREMENTS.md\` already holds the settled acceptance
|
|
464
|
-
criteria. Add a \`## Impact\` section and
|
|
465
|
-
|
|
477
|
+
criteria. Add a \`## Impact\` section — and a \`## Release Flag\`
|
|
478
|
+
section when the sketch asks for one — and change nothing else: a
|
|
479
|
+
turn that touches anything outside them is refused
|
|
466
480
|
- No human reviews this before the build: put any surprise in the
|
|
467
481
|
Impact prose, never as a question
|
|
468
|
-
${impactBlock}
|
|
482
|
+
${impactBlock}${releaseFlagBlock}
|
|
469
483
|
- Leave \`.gtd/REQUIREMENTS.md\` uncommitted and finish once it holds \`## Impact\`
|
|
470
484
|
`
|
|
471
485
|
|
|
@@ -543,6 +557,7 @@ What each change does next (then run \`gtd land\`):
|
|
|
543
557
|
- **Accept as-is** — change nothing and re-run; the plan stands as written. Refused while a thread is open.
|
|
544
558
|
- **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.
|
|
545
559
|
- **Discuss** — start or continue a thread (\`- H:\`); the agent replies and this gate stops again.
|
|
560
|
+
- **Ask for a release flag** — add \`## Release Flag\` with \`new\` or \`existing: <NAME>\` as its first line, or delete the section to ship unflagged.
|
|
546
561
|
${riskTier ? RISK_TIER_GATE_LINE : ""}`
|
|
547
562
|
|
|
548
563
|
export const builderSystem = (): string =>
|
|
@@ -1532,26 +1547,28 @@ const afterRefactorLine = (rebuild: Rebuild): string =>
|
|
|
1532
1547
|
rule below; if nothing is, ${carries(rebuild) ? "carry over the acceptance tests below and change nothing else" : "change nothing and finish your turn"}
|
|
1533
1548
|
`
|
|
1534
1549
|
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1550
|
+
/** What \`## Release Flag\` in \`.gtd/REQUIREMENTS.md\` asks for; no section is \`none\`. */
|
|
1551
|
+
export type ReleaseFlag =
|
|
1552
|
+
| { readonly kind: "none" }
|
|
1553
|
+
| { readonly kind: "new" }
|
|
1554
|
+
| { readonly kind: "existing"; readonly name: string }
|
|
1555
|
+
|
|
1556
|
+
const flagLine = (flag: ReleaseFlag, amend: boolean | undefined): string =>
|
|
1557
|
+
flag.kind === "none"
|
|
1558
|
+
? "- Add no release flag — the requirements ask for none"
|
|
1559
|
+
: flag.kind === "existing"
|
|
1560
|
+
? `- Put the new behaviour behind the existing flag \`${flag.name}\`, as the
|
|
1561
|
+
requirements ask — add no new flag`
|
|
1544
1562
|
: amend === true
|
|
1545
1563
|
? "- Keep the release flag the earlier lap added, if it added one; otherwise put\n the behaviour behind a new release flag"
|
|
1546
|
-
: `- Put the new behaviour behind a new release flag,
|
|
1547
|
-
repository's flag conventions`
|
|
1564
|
+
: `- Put the new behaviour behind a new release flag, as the requirements ask,
|
|
1565
|
+
following the repository's flag conventions`
|
|
1548
1566
|
|
|
1549
1567
|
export const implementBuildingPrompt = (
|
|
1550
1568
|
reference: string | undefined,
|
|
1551
|
-
tier?: "low" | "high",
|
|
1552
1569
|
amend?: boolean,
|
|
1553
1570
|
afterRefactor?: boolean,
|
|
1554
|
-
|
|
1571
|
+
flag: ReleaseFlag = { kind: "none" },
|
|
1555
1572
|
rebuild: Rebuild = {},
|
|
1556
1573
|
): string =>
|
|
1557
1574
|
`${stateFileRules}
|
|
@@ -1563,7 +1580,7 @@ ${afterRefactor === true ? afterRefactorLine(rebuild) : ""}${
|
|
|
1563
1580
|
? `- The change already exists in the tree from an earlier lap; amend it to meet
|
|
1564
1581
|
the re-derived requirements instead of rewriting it
|
|
1565
1582
|
`
|
|
1566
|
-
:
|
|
1583
|
+
: flag.kind !== "none"
|
|
1567
1584
|
? `- Implement them properly, fitting the codebase's seams and conventions
|
|
1568
1585
|
`
|
|
1569
1586
|
: `- Implement them the quickest way that works — the naive version. Do not
|
|
@@ -1576,7 +1593,7 @@ ${afterRefactor === true ? afterRefactorLine(rebuild) : ""}${
|
|
|
1576
1593
|
Read it for ideas; never apply, cherry-pick or check it out — write
|
|
1577
1594
|
the change fresh${carries(rebuild) ? ", its acceptance tests excepted (below)" : ""}
|
|
1578
1595
|
`
|
|
1579
|
-
}${rebuildLines(rebuild)}${flagLine(
|
|
1596
|
+
}${rebuildLines(rebuild)}${flagLine(flag, amend)}
|
|
1580
1597
|
- Write the tests first, then the code that makes them pass
|
|
1581
1598
|
${behaviourTests}
|
|
1582
1599
|
- Leave \`.gtd/REQUIREMENTS.md\` in place and everything uncommitted, then
|
|
@@ -1599,7 +1616,7 @@ An edit together with an approval counts as steer. Only
|
|
|
1599
1616
|
branch unjudged.
|
|
1600
1617
|
`
|
|
1601
1618
|
|
|
1602
|
-
/** `judged`: whether an overruled pass still meets the seam judge (
|
|
1619
|
+
/** `judged`: whether an overruled pass still meets the seam judge (a release flag asked for). */
|
|
1603
1620
|
export const seamSteerMessage = (retry: NaiveRetry, judged = true): string =>
|
|
1604
1621
|
isFault(retry)
|
|
1605
1622
|
? `The naive pass failed three times and the retries are spent. The last
|
|
@@ -28,7 +28,6 @@ export const defaults: Readonly<Record<string, string>> = {
|
|
|
28
28
|
standardMinP: "0.8",
|
|
29
29
|
refactorFlagPattern: "\\bGTD_FLAG_\\w+",
|
|
30
30
|
seamAllow: [...testFileGlobs, ".gtd/**"].join(", "),
|
|
31
|
-
flagMode: "true",
|
|
32
31
|
// A person tries every green naive pass at `seam.try` before anything builds on it.
|
|
33
32
|
naiveTest: "false",
|
|
34
33
|
// GTD_FLAG_RISK_TIER, recorded at process start; only "1" is on.
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
@inmem
|
|
2
|
-
Feature: flag mode off lands the naive pass with no release flag, seam judge or refactor
|
|
3
|
-
|
|
4
|
-
`flagMode` is a factory option of the shipped workflows, on by default. Off,
|
|
5
|
-
the project ships without feature flags: no seam judge and no refactor run,
|
|
6
|
-
and the naive pass itself lands, straight through the health loop and the
|
|
7
|
-
quality lap.
|
|
8
|
-
|
|
9
|
-
Background:
|
|
10
|
-
Given a gtd config with:
|
|
11
|
-
"""
|
|
12
|
-
import { feature } from "@pmelab/gtd/workflows/feature"
|
|
13
|
-
export { summary, steering, skills, access } from "@pmelab/gtd/workflows/feature"
|
|
14
|
-
export default feature({ flagMode: false })
|
|
15
|
-
"""
|
|
16
|
-
And an environment variable "GTD_QUALITYREVIEWS" set to "correctness"
|
|
17
|
-
And a file "src/calc.ts" with:
|
|
18
|
-
"""
|
|
19
|
-
export const add = (a: number, b: number) => a + b
|
|
20
|
-
"""
|
|
21
|
-
And the working tree is committed as "feat: add calculator"
|
|
22
|
-
And a file "TODO.md" with:
|
|
23
|
-
"""
|
|
24
|
-
# Add subtract
|
|
25
|
-
|
|
26
|
-
subtract(a, b) returns the difference.
|
|
27
|
-
"""
|
|
28
|
-
And step "unwind" changes nothing
|
|
29
|
-
And step "start-gate.check" changes nothing
|
|
30
|
-
And step "design.triage" writes ".gtd/REQUIREMENTS.md" with:
|
|
31
|
-
"""
|
|
32
|
-
# Requirements
|
|
33
|
-
|
|
34
|
-
## Concerns
|
|
35
|
-
|
|
36
|
-
### Subtract
|
|
37
|
-
|
|
38
|
-
- `subtract(a, b)` returns `a - b`.
|
|
39
|
-
|
|
40
|
-
## Impact
|
|
41
|
-
|
|
42
|
-
- the greeting module
|
|
43
|
-
|
|
44
|
-
## Acceptance Criteria
|
|
45
|
-
|
|
46
|
-
- AC-1: the change behaves as described.
|
|
47
|
-
"""
|
|
48
|
-
And step "design.gate.answer" changes nothing
|
|
49
|
-
|
|
50
|
-
Scenario: flag mode off lands the naive pass unjudged, and asks for no flag
|
|
51
|
-
When the process is driven
|
|
52
|
-
Then the process rests at "seam.naive"
|
|
53
|
-
And the resting step's content contains "the quickest way that works"
|
|
54
|
-
And the resting step's content does not contain "release flag"
|
|
55
|
-
Given step "seam.naive" writes "src/calc.test.ts" with:
|
|
56
|
-
"""
|
|
57
|
-
it("[AC-1] subtracts", () => {})
|
|
58
|
-
"""
|
|
59
|
-
And step "seam.naive" writes "src/calc.ts" with:
|
|
60
|
-
"""
|
|
61
|
-
export const add = (a: number, b: number) => a + b
|
|
62
|
-
export const subtract = (a: number, b: number) => a - b
|
|
63
|
-
"""
|
|
64
|
-
And step "seam.check" changes nothing
|
|
65
|
-
And step "implement.applying" runs its script
|
|
66
|
-
And step "implement.health.check" changes nothing
|
|
67
|
-
And step "implement.closing" runs its script
|
|
68
|
-
And step "build.quality.correctness.reviewing" changes nothing
|
|
69
|
-
When the process is driven
|
|
70
|
-
Then the process rests at "build.review.reviewing"
|
|
71
|
-
And "src/calc.ts" contains "subtract"
|
|
72
|
-
And "src/calc.test.ts" contains "[AC-1] subtracts"
|
|
73
|
-
And the commit subjects end with:
|
|
74
|
-
"""
|
|
75
|
-
chore: initial commit
|
|
76
|
-
feat: add calculator
|
|
77
|
-
gtd(human): idle → unwind
|
|
78
|
-
gtd(check): unwind → start-gate.check
|
|
79
|
-
gtd(check): start-gate.check → design.triage
|
|
80
|
-
gtd(agent): design.triage → design.gate.answer
|
|
81
|
-
gtd(human): design.gate.answer → seam.naive
|
|
82
|
-
gtd(agent): seam.naive → seam.check
|
|
83
|
-
gtd(check): seam.check → implement.applying
|
|
84
|
-
gtd(check): implement.applying → implement.health.check
|
|
85
|
-
gtd(check): implement.health.check → implement.closing
|
|
86
|
-
gtd(check): implement.closing → build.quality.correctness.reviewing
|
|
87
|
-
gtd(agent): build.quality.correctness.reviewing → build.review.reviewing
|
|
88
|
-
"""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|