geneseed 3.12.0 → 3.13.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/CHANGELOG.md +121 -0
- package/README.md +2 -2
- package/SHIPPED.md +1 -1
- package/adapters/bob/README.md +1 -1
- package/adapters/claude-code/README.md +1 -1
- package/adapters/openclaude/README.md +1 -1
- package/adapters/opencode/README.md +3 -3
- package/docs/README.md +41 -22
- package/docs/concepts/agents.md +3 -1
- package/docs/concepts/collaboration.md +3 -1
- package/docs/concepts/exclusions.md +4 -2
- package/docs/concepts/footprint.md +3 -1
- package/docs/concepts/foreman-mode.md +3 -1
- package/docs/concepts/hook-gates.md +61 -0
- package/docs/concepts/hooks.md +8 -56
- package/docs/concepts/host-matrix.md +38 -0
- package/docs/concepts/hosts.md +6 -32
- package/docs/concepts/loop-branch.md +66 -0
- package/docs/concepts/loop-bricks.md +48 -0
- package/docs/concepts/loop-contracts.md +33 -0
- package/docs/concepts/loop-gates.md +30 -0
- package/docs/concepts/loop-notes.md +43 -0
- package/docs/concepts/loop-risk.md +36 -0
- package/docs/concepts/loop-templates.md +50 -0
- package/docs/concepts/loops.md +24 -116
- package/docs/concepts/lsp.md +2 -0
- package/docs/concepts/memory.md +3 -1
- package/docs/concepts/notebook.md +3 -1
- package/docs/concepts/rules.md +4 -2
- package/docs/concepts/skills.md +3 -1
- package/docs/concepts/themes.md +3 -1
- package/docs/extending.md +23 -8
- package/docs/guides/autostart.md +3 -1
- package/docs/guides/choose-your-setup.md +5 -80
- package/docs/guides/headless.md +5 -3
- package/docs/guides/install-agent-md.md +37 -0
- package/docs/guides/install-bob.md +20 -0
- package/docs/guides/install-claude-code.md +22 -0
- package/docs/guides/install-clone.md +34 -0
- package/docs/guides/install-openclaude.md +25 -0
- package/docs/guides/install-opencode.md +35 -0
- package/docs/guides/install-scripted.md +21 -0
- package/docs/guides/install.md +9 -118
- package/docs/guides/loop-finish.md +54 -0
- package/docs/guides/loop-running.md +66 -0
- package/docs/guides/loop-which-template.md +35 -0
- package/docs/guides/mcp-filesystem.md +41 -0
- package/docs/guides/mcp-gitlab.md +66 -0
- package/docs/guides/mcp-markitdown.md +36 -0
- package/docs/guides/mcp.md +8 -137
- package/docs/guides/migrate.md +3 -1
- package/docs/guides/project-context.md +4 -2
- package/docs/guides/read-non-markdown.md +17 -0
- package/docs/guides/run-a-loop.md +64 -0
- package/docs/guides/run-anywhere.md +2 -0
- package/docs/guides/setup-doctrines.md +55 -0
- package/docs/guides/setup-footprint.md +48 -0
- package/docs/guides/uninstall.md +3 -1
- package/docs/guides/upgrade.md +3 -1
- package/docs/guides/verify.md +3 -1
- package/docs/guides/wiki.md +3 -1
- package/docs/guides/worktree.md +3 -1
- package/docs/reference/about.md +3 -1
- package/docs/reference/cli.md +2 -0
- package/docs/reference/env-context.md +40 -0
- package/docs/reference/environment.md +10 -59
- package/docs/reference/glossary.md +3 -1
- package/docs/reference/loop-actions.md +20 -0
- package/docs/reference/opencode-plugins.md +14 -118
- package/docs/reference/plugin-activity.md +20 -0
- package/docs/reference/plugin-context.md +27 -0
- package/docs/reference/plugin-guard.md +27 -0
- package/docs/reference/plugin-learn.md +27 -0
- package/docs/reference/plugin-notify.md +20 -0
- package/docs/reference/plugin-ponytail.md +19 -0
- package/docs/reference/plugin-workflow.md +25 -0
- package/docs/reference/troubleshoot-doctor.md +50 -0
- package/docs/reference/troubleshoot-hooks.md +99 -0
- package/docs/reference/troubleshoot-install.md +108 -0
- package/docs/reference/troubleshoot-tools.md +56 -0
- package/docs/reference/troubleshoot-update.md +23 -0
- package/docs/reference/troubleshoot-web.md +66 -0
- package/docs/reference/troubleshooting.md +13 -337
- package/docs/understand/a-day.md +3 -1
- package/docs/understand/enforced-vs-asked.md +3 -1
- package/docs/understand/harness.md +2 -0
- package/docs/understand/machine-bob.md +17 -0
- package/docs/understand/machine-claude.md +35 -0
- package/docs/understand/machine-opencode.md +36 -0
- package/docs/understand/on-your-machine.md +12 -55
- package/docs/understand/take-it-out.md +13 -0
- package/docs/web-ui.md +35 -15
- package/harness.config.json +1 -1
- package/js/README.md +11 -3
- package/js/cli-table.json +27 -1
- package/js/hosts/mcp.mjs +1 -1
- package/js/hosts/native.mjs +43 -5
- package/js/inspect/checks-build.mjs +28 -0
- package/js/loop/catalog.mjs +12 -1
- package/js/loop/cli.mjs +28 -6
- package/js/loop/graph.mjs +18 -0
- package/js/loop/registry.mjs +196 -0
- package/js/loop/score.mjs +45 -6
- package/js/loop/state.mjs +125 -11
- package/js/maintain/setup.mjs +1 -1
- package/js/web/actions.mjs +25 -0
- package/js/web/api.mjs +13 -0
- package/js/web/docs.mjs +64 -12
- package/js/web/routes.mjs +5 -1
- package/package.json +1 -1
- package/src/agents/explorer.md +2 -2
- package/src/agents/researcher.md +3 -3
- package/src/bricks/README.md +3 -1
- package/src/bricks/adr-challenge.md +20 -0
- package/src/bricks/adr-draft.md +15 -0
- package/src/bricks/characterize.md +17 -0
- package/src/bricks/ci-fix.md +2 -1
- package/src/bricks/ci-triage.md +20 -0
- package/src/bricks/compat-check.md +16 -0
- package/src/bricks/done-check.md +16 -0
- package/src/bricks/fitness-define.md +22 -0
- package/src/bricks/flake-check.md +17 -0
- package/src/bricks/flake-repro.md +18 -0
- package/src/bricks/identify.md +6 -3
- package/src/bricks/migration-plan.md +21 -0
- package/src/bricks/mutation-check.md +18 -0
- package/src/bricks/plan.md +6 -6
- package/src/bricks/red-test.md +16 -0
- package/src/bricks/review.md +5 -3
- package/src/bricks/spec.md +18 -0
- package/src/bricks/upgrade-scout.md +16 -0
- package/src/loops/api-endpoint.json +31 -0
- package/src/loops/architecture-decision.json +22 -0
- package/src/loops/bugfix.json +1 -0
- package/src/loops/ci-repair.json +19 -0
- package/src/loops/deps-upgrade.json +29 -0
- package/src/loops/enforce-architecture-rule.json +28 -0
- package/src/loops/feature.json +8 -5
- package/src/loops/fix-flaky-tests.json +30 -0
- package/src/loops/legacy-refactor.json +26 -0
- package/src/loops/legacy-tests.json +29 -0
- package/src/loops/refactor.json +5 -1
- package/src/loops/remove-dead-code.json +30 -0
- package/src/loops/spec-first-feature.json +29 -0
- package/src/loops/tdd.json +25 -0
- package/src/loops/update-contract.json +33 -0
- package/src/skills/brick-forge.md +3 -1
- package/src/skills/bruno-collection-generator.md +3 -3
- package/src/skills/bruno-test-writer.md +3 -3
- package/src/skills/ci-fix.md +3 -3
- package/src/skills/consolidate-memory.md +4 -4
- package/src/skills/council.md +1 -1
- package/src/skills/fresh-eyes.md +1 -1
- package/src/skills/git-archaeology.md +1 -1
- package/src/skills/git-rescue.md +4 -3
- package/src/skills/handoff.md +1 -1
- package/src/skills/herdr.md +1 -1
- package/src/skills/learn-mode.md +2 -2
- package/src/skills/loop.md +22 -10
- package/src/skills/opencode-theme.md +3 -3
- package/src/skills/ponytail.md +1 -1
- package/src/skills/profile.md +3 -4
- package/src/skills/prose.md +2 -3
- package/src/skills/quiz.md +1 -1
- package/src/skills/react-view-transitions/SKILL.md +1 -1
- package/src/skills/react-view-transitions/VENDOR.md +8 -3
- package/src/skills/research.md +3 -3
- package/src/skills/review-response.md +2 -2
- package/src/skills/rule.md +3 -3
- package/src/skills/security-audit.md +4 -4
- package/src/skills/teach.md +1 -1
- package/src/skills/wiki.md +3 -3
- package/src/skills/workflow.md +4 -4
- package/src/skills/worktree.md +2 -2
- package/web/dist/assets/Activity-Ca2Aruu7.js +1 -0
- package/web/dist/assets/ActivityDetail-Bo7v4Z_r.js +1 -0
- package/web/dist/assets/Dashboard-BuMq46aT.js +2 -0
- package/web/dist/assets/Docs-BzccCllG.js +5 -0
- package/web/dist/assets/FilterInput-CBcJBQPI.js +1 -0
- package/web/dist/assets/GreenhouseView-BCIKcnGG.js +2 -0
- package/web/dist/assets/Installs-DMFJvq7s.js +2 -0
- package/web/dist/assets/JournalView-o1rmd1_1.js +1 -0
- package/web/dist/assets/Laws-BANxq_I_.js +3 -0
- package/web/dist/assets/Library-DW4x0fbh.js +1 -0
- package/web/dist/assets/Loops-DEBibbBP.js +2 -0
- package/web/dist/assets/{Markdown-qjM2_ofS.js → Markdown-CdTX0kLe.js} +14 -14
- package/web/dist/assets/OperatorHudView-CLD0fYaA.js +2 -0
- package/web/dist/assets/Personal-6uMJvyBG.js +1 -0
- package/web/dist/assets/Tabs-BubnyZhF.js +1 -0
- package/web/dist/assets/activity-CObqyxkL.js +1 -0
- package/web/dist/assets/{api-CyMRbU2x.js → api-D_ixdyEY.js} +1 -1
- package/web/dist/assets/drawable-C_x5xncq.js +1 -0
- package/web/dist/assets/index-CMPgezFm.js +2 -0
- package/web/dist/assets/index-DMsT4Aa6.css +1 -0
- package/web/dist/assets/{react-B9Z_tXRV.js → react-Bbzhmq4v.js} +1 -1
- package/web/dist/assets/rolldown-runtime-hePW80VL.js +1 -0
- package/web/dist/assets/sections-Dg23Hel5.js +1 -0
- package/web/dist/assets/usePoll-BOqeunzF.js +1 -0
- package/web/dist/index.html +6 -5
- package/web/dist/assets/Activity-GaaZWXTY.js +0 -1
- package/web/dist/assets/ActivityDetail-4t7d45Du.js +0 -1
- package/web/dist/assets/Dashboard-CYn7Tp16.js +0 -2
- package/web/dist/assets/Docs-BeFKLg2T.js +0 -5
- package/web/dist/assets/FilterInput-CVyqmYWM.js +0 -1
- package/web/dist/assets/GreenhouseView-C6ibc8IE.js +0 -2
- package/web/dist/assets/Installs-DRYjYnxs.js +0 -2
- package/web/dist/assets/JournalView-1HbU1mfg.js +0 -1
- package/web/dist/assets/Laws-DFoG8JWB.js +0 -3
- package/web/dist/assets/Library-DDjgNwz_.js +0 -1
- package/web/dist/assets/Loops-D9VEoO0F.js +0 -1
- package/web/dist/assets/OperatorHudView-Bs7paWmh.js +0 -2
- package/web/dist/assets/Personal-BY5n4gTw.js +0 -1
- package/web/dist/assets/Tabs-ho-EYD8i.js +0 -1
- package/web/dist/assets/drawable-CLS9drMb.js +0 -1
- package/web/dist/assets/index-CX_hXMi5.css +0 -1
- package/web/dist/assets/index-Cjr7XCA3.js +0 -2
- package/web/dist/assets/sections-GalMS0Zv.js +0 -1
- package/web/dist/assets/usePoll-O0sJEw1Y.js +0 -1
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: characterize
|
|
3
|
+
description: Pin what legacy code does today with characterization tests, touching tests only.
|
|
4
|
+
effect: mutate
|
|
5
|
+
agent: tester
|
|
6
|
+
outcomes: pass, fail
|
|
7
|
+
---
|
|
8
|
+
For the card's change point (with no card, the code the requirement names), write tests that pin
|
|
9
|
+
what the code DOES today, not what it should do: assert a value you expect to be wrong, run it,
|
|
10
|
+
and copy the observed value in. Touch only test files — never production code.
|
|
11
|
+
|
|
12
|
+
Pin odd behaviour as it is and name it in the test's title; do not fix it here. If LOOP.md's notes
|
|
13
|
+
list surviving mutants for this card, add the assertions that kill them.
|
|
14
|
+
|
|
15
|
+
Report `pass` once the new tests run green against the unchanged code.
|
|
16
|
+
Report `fail` if the code cannot be put under test without breaking a dependency first — that is
|
|
17
|
+
a refactor in its own right — naming the dependency.
|
package/src/bricks/ci-fix.md
CHANGED
|
@@ -11,7 +11,8 @@ guess from the check's title, before changing anything.
|
|
|
11
11
|
Touch only what that failure requires; this is a repair, not a chance to improve the pipeline
|
|
12
12
|
along the way.
|
|
13
13
|
|
|
14
|
-
Report `pass` once the named check is fixed and green
|
|
14
|
+
Report `pass` once the named check is fixed and green LOCALLY — CI itself is re-read after the
|
|
15
|
+
push, not here.
|
|
15
16
|
|
|
16
17
|
Report `fail` if the check cannot be fixed from this repo alone (an infra outage, a flake with no
|
|
17
18
|
reproducible cause, a required secret that is missing), naming why.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ci-triage
|
|
3
|
+
description: Read the failing CI checks for this commit and pick one code failure to fix, or stop.
|
|
4
|
+
effect: read
|
|
5
|
+
agent: explorer
|
|
6
|
+
outcomes: more, done
|
|
7
|
+
---
|
|
8
|
+
Key on the commit, not the branch: `gh run list --commit <HEAD sha> --json databaseId,status,conclusion`.
|
|
9
|
+
A commit pushed moments ago may not have a run yet — poll that command for up to ~2 minutes
|
|
10
|
+
before concluding none exists. Wait on a pending run with `gh run watch <id>`, then read
|
|
11
|
+
`gh run view <id> --log-failed` — never guess from a check's title. Classify each failure as
|
|
12
|
+
code, flaky or infra. Never edit any file. `ci-repair` needs CI to run on `loop/*` branches: if
|
|
13
|
+
still no run after that poll, write "CI does not run for <sha>" to a file in the OS temp
|
|
14
|
+
directory and report `done` with that file's path — never as green.
|
|
15
|
+
|
|
16
|
+
Write the classification, one failure per line, to a file in the OS temp directory and report
|
|
17
|
+
that file's path with the outcome. Report `more` with a card for ONE code failure:
|
|
18
|
+
{"intent": "<fix check X: cause>", "writeSet": ["<files the fix touches>"],
|
|
19
|
+
"actions": ["<each of: format, imports, rename, logic, new-file, api, delete, architecture>"]}
|
|
20
|
+
Report `done` when CI is green for HEAD, or only flaky or infra failures remain — naming them.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: compat-check
|
|
3
|
+
description: Confirm consumers of the old and the new interface both still work after this iteration.
|
|
4
|
+
effect: read
|
|
5
|
+
agent: tester
|
|
6
|
+
outcomes: pass, fail
|
|
7
|
+
---
|
|
8
|
+
Run the tests of every consumer this change can reach — those still on the old shape as well as
|
|
9
|
+
those already moved — and, where the repo records consumer contracts (Pact, Spring Cloud
|
|
10
|
+
Contract), the provider verification against them. In a contract step, where the old shape is
|
|
11
|
+
removed on purpose, check instead that no consumer still uses it. Never edit any file: send
|
|
12
|
+
reports to the OS temp directory.
|
|
13
|
+
|
|
14
|
+
Report `pass` if every consumer works. Report `fail` naming the broken consumer, the check and
|
|
15
|
+
its raw failure, written to a file in the OS temp directory — report that file's path with the
|
|
16
|
+
outcome.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: done-check
|
|
3
|
+
description: Verify the requirement is met — every acceptance criterion proven by a passing test or a stated manual check.
|
|
4
|
+
effect: read
|
|
5
|
+
agent: reviewer
|
|
6
|
+
outcomes: pass, fail
|
|
7
|
+
---
|
|
8
|
+
Read the requirement's acceptance criteria — `specs/<slug>/spec.md` when the branch has one, else
|
|
9
|
+
the requirement in LOOP.md — and the branch's full diff against its base. Run the suite. For
|
|
10
|
+
every criterion, name the test that proves it, or the manual check (what to do, what to see) when
|
|
11
|
+
no test can. Never edit any file. Judge only the stated criteria — never style or extras.
|
|
12
|
+
|
|
13
|
+
Report `pass` only if every criterion maps to a passing test or a stated manual check.
|
|
14
|
+
Report `fail` otherwise: write each unmet criterion, one per line, with what is missing (no test,
|
|
15
|
+
a failing test, a half-built behaviour) to a file in the OS temp directory and report that file's
|
|
16
|
+
path — the next iteration's `identify` builds from it.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fitness-define
|
|
3
|
+
description: Encode the requirement's architecture rule as a test, with an allowlist of today's violations.
|
|
4
|
+
effect: mutate
|
|
5
|
+
agent: architect
|
|
6
|
+
gate: human
|
|
7
|
+
outcomes: pass, fail
|
|
8
|
+
---
|
|
9
|
+
Turn the requirement's architecture rule into an executable test in the suite, with the repo's
|
|
10
|
+
own tools first: ArchUnit for Java (a `FreezingArchRule`, whose violation store is the
|
|
11
|
+
allowlist), then dependency-cruiser, import-linter, eslint-plugin-boundaries or size-limit.
|
|
12
|
+
Record today's violations in an allowlist beside the test so the suite stays green — each later
|
|
13
|
+
iteration removes one entry. Touch only the test, its allowlist and the tool's test-scoped setup,
|
|
14
|
+
and declare the tool's generated store as a glob in the write set (`--write-set '**/archunit_store/**'`
|
|
15
|
+
— single-quote it, the same as any glob in `--write-set`).
|
|
16
|
+
|
|
17
|
+
The user reviews the rule before the loop continues: write the rule in one sentence, the test's
|
|
18
|
+
path, the allowlist's path and its entry count to a file in the OS temp directory and report that
|
|
19
|
+
file's path with the outcome.
|
|
20
|
+
|
|
21
|
+
Report `pass` once the test runs green with the allowlist in place. Report `fail` if the rule
|
|
22
|
+
cannot be checked deterministically, with the note file naming what is ambiguous.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: flake-check
|
|
3
|
+
description: Rerun the card's test until it proves stable — a retry or a sleep is not a fix.
|
|
4
|
+
effect: read
|
|
5
|
+
agent: tester
|
|
6
|
+
outcomes: stable, flaky
|
|
7
|
+
---
|
|
8
|
+
Rerun the card's test 20 times alone, then 20 with its suite, as `flake-repro` did (Maven: a
|
|
9
|
+
loop of `mvn test -Dtest=<Class>#<method>`, shuffled). Never edit any file.
|
|
10
|
+
|
|
11
|
+
Read this iteration's diff first. Polling on the awaited condition (Awaitility
|
|
12
|
+
`await().atMost(…).until(…)`, `waitFor`) in place of a fixed sleep is a fix; adding a sleep or
|
|
13
|
+
raising an existing timeout is not, and neither is a retry (`rerunFailingTestsCount`,
|
|
14
|
+
`@RetryingTest`, `jest.retryTimes`) — report `flaky` naming it, whatever the runs say.
|
|
15
|
+
|
|
16
|
+
Report `stable` only on 0 failures in all runs. Report `flaky` otherwise, with the failure count
|
|
17
|
+
and one failure's output in a file in the OS temp directory — report that file's path.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: flake-repro
|
|
3
|
+
description: Confirm which suspected tests are flaky by repeated runs, before anything is fixed.
|
|
4
|
+
effect: read
|
|
5
|
+
agent: tester
|
|
6
|
+
outcomes: flaky, stable, broken
|
|
7
|
+
---
|
|
8
|
+
Run each suspected test the requirement names 20 times (or the N it gives) alone, then 20 with
|
|
9
|
+
its suite in a shuffled order — no code change, no retry option. Maven: loop `mvn test
|
|
10
|
+
-Dtest=<Class>#<method>` (multi-module: add `-pl <module> -Dsurefire.failIfNoSpecifiedTests=false`),
|
|
11
|
+
shuffled with `-Dsurefire.runOrder=random` and, under JUnit 5,
|
|
12
|
+
`-Djunit.jupiter.testmethod.order.default=org.junit.jupiter.api.MethodOrderer$Random`. Never
|
|
13
|
+
`-Dsurefire.rerunFailingTestsCount`: it hides the failures you count. Never edit any file. Write
|
|
14
|
+
each test as `<test>: <failures>/<runs>` with one failure's output to a file in the OS temp
|
|
15
|
+
directory and report that file's path.
|
|
16
|
+
|
|
17
|
+
Report `broken` if any test fails every run — a bug for `bugfix`, not a flake. Report `flaky` if a
|
|
18
|
+
test failed some runs, listing the confirmed ones. Report `stable` if none failed.
|
package/src/bricks/identify.md
CHANGED
|
@@ -9,12 +9,15 @@ Read the requirement and the loop's history (LOOP.md, `git log --format=%(traile
|
|
|
9
9
|
branch). If the requirement is fully met and the suite is green, report `done`.
|
|
10
10
|
|
|
11
11
|
Otherwise pick the SMALLEST next change that moves the requirement forward and can be tested on
|
|
12
|
-
its own
|
|
13
|
-
|
|
12
|
+
its own — when the branch has `specs/*/spec.md`, its next unfinished task. If the latest note is
|
|
13
|
+
`done-check`'s unmet criteria, report `more` with a card for one of them, never `done`. Report
|
|
14
|
+
`more` with a card, as JSON:
|
|
15
|
+
{"intent": "<one line>", "writeSet": ["<every file ANY brick this iteration writes, tests/docs too>"],
|
|
14
16
|
"actions": ["<each of: format, imports, rename, logic, new-file, api, delete, architecture>"]}
|
|
15
17
|
|
|
16
18
|
Declare every action honestly: the diff is scored again before commit, and anything outside the
|
|
17
19
|
write set or under-declared escalates to a blocking stop. If LOOP.md's notes say the previous
|
|
18
|
-
attempt was re-split, make this card strictly smaller than that one.
|
|
20
|
+
attempt was re-split, make this card strictly smaller than that one. The card obeys every
|
|
21
|
+
instruction in the template's `rules` (e.g. its intent cites the proof that code is unused).
|
|
19
22
|
|
|
20
23
|
Never edit, create or delete any file: this brick only reads.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: migration-plan
|
|
3
|
+
description: Plan a breaking interface change as expand, migrate each consumer, contract — for the user to review.
|
|
4
|
+
effect: read
|
|
5
|
+
skill: migrate
|
|
6
|
+
gate: human
|
|
7
|
+
outcomes: pass, fail
|
|
8
|
+
---
|
|
9
|
+
Following the migrate skill, plan the change as ordered steps: expand (add the new shape beside
|
|
10
|
+
the old), migrate (one consumer or call-site group per step), contract (remove the old shape).
|
|
11
|
+
Every step must leave the system deployable and fit one `identify` card. Name the contract files
|
|
12
|
+
the expand and contract steps touch — API specs, schema migrations, event schemas. Never edit any
|
|
13
|
+
file.
|
|
14
|
+
|
|
15
|
+
The user reviews the plan before the loop continues: write the steps, one per line, then the
|
|
16
|
+
contract files, to a file in the OS temp directory and report that file's path with the outcome.
|
|
17
|
+
Those files belong in LOOP.md's `contracts`, so the expand and contract steps stop for a human:
|
|
18
|
+
the user adds any the template's defaults miss to LOOP.md's `contracts` before answering ok.
|
|
19
|
+
|
|
20
|
+
Report `pass` with the plan. Report `fail` if no backward-compatible path exists, naming what
|
|
21
|
+
forces the break.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mutation-check
|
|
3
|
+
description: Prove the new tests bite, by mutation testing scoped to the code the card names.
|
|
4
|
+
effect: read
|
|
5
|
+
agent: tester
|
|
6
|
+
outcomes: pass, fail, unavailable
|
|
7
|
+
---
|
|
8
|
+
Run the project's mutation tool scoped to the production code the card's intent names. Java: PIT
|
|
9
|
+
first — `mvn test-compile org.pitest:pitest-maven:mutationCoverage -DtargetClasses=<fq.Class*>
|
|
10
|
+
-DreportsDirectory=<OS temp dir> -DtimestampedReports=false`, or Gradle's `pitest` task; else
|
|
11
|
+
Stryker, mutmut or cargo-mutants. Never edit any file — reports and caches (.mutmut-cache,
|
|
12
|
+
mutants.out/, .stryker-tmp/) go to the OS temp dir, or are removed.
|
|
13
|
+
|
|
14
|
+
Report `pass` if no surviving mutant sits on a line the new tests target. Report `fail` with each
|
|
15
|
+
survivor as `file:line`, the mutation, and the assertion that would kill it, in a file in the OS
|
|
16
|
+
temp directory — report its path. Report `unavailable` when no tool is configured — the pom lacks
|
|
17
|
+
`pitest-junit5-plugin` under JUnit 5, or Gradle does not apply `info.solidsoft.pitest`: never add
|
|
18
|
+
it to the build; write what you checked to a temp file and report its path.
|
package/src/bricks/plan.md
CHANGED
|
@@ -8,10 +8,10 @@ outcomes: pass
|
|
|
8
8
|
Read the requirement and survey the code it touches. Split the work into an ordered list of
|
|
9
9
|
small iterations, each one sized to a single `identify` card — one testable change apiece.
|
|
10
10
|
|
|
11
|
-
Do not edit any code; this brick only plans it.
|
|
12
|
-
the ordered list, one iteration per line,
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
Do not edit any code; this brick only plans it. `plan` is not an iteration head, so its card is
|
|
12
|
+
never recorded — write the ordered list, one iteration per line, to a file in the OS temp
|
|
13
|
+
directory (never inside the worktree) and report that file's path with the outcome, so it is
|
|
14
|
+
recorded into LOOP.md's notes. Report `pass`.
|
|
15
15
|
|
|
16
|
-
If the requirement cannot be split — it is already one atomic change — say so in the
|
|
17
|
-
let the loop proceed with a single iteration.
|
|
16
|
+
If the requirement cannot be split — it is already one atomic change — say so in the note file
|
|
17
|
+
and let the loop proceed with a single iteration.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: red-test
|
|
3
|
+
description: Write the failing test for the card's intent before any production code changes.
|
|
4
|
+
effect: mutate
|
|
5
|
+
agent: tester
|
|
6
|
+
outcomes: red, green, untestable
|
|
7
|
+
---
|
|
8
|
+
Write the smallest test that expresses the card's intent at its seam, touching only the test
|
|
9
|
+
files in the card's `writeSet` — never production code; making it pass is `apply`'s job. Run it.
|
|
10
|
+
|
|
11
|
+
Report `red` if it fails FOR THE REASON the intent states — not an import error, a typo, or a
|
|
12
|
+
broken fixture in the test itself.
|
|
13
|
+
Report `green` if it already passes: the behaviour exists, so keep the test as coverage.
|
|
14
|
+
Report `untestable` if no seam lets a test reach the behaviour without changing production code
|
|
15
|
+
first, naming what blocks it. If the card's `writeSet` names no test file, report `untestable`
|
|
16
|
+
and say so.
|
package/src/bricks/review.md
CHANGED
|
@@ -6,12 +6,14 @@ agent: reviewer
|
|
|
6
6
|
outcomes: pass, fail
|
|
7
7
|
---
|
|
8
8
|
Read the card's intent and write set, then read the diff this iteration actually produced. Check
|
|
9
|
-
that the diff matches the intent, stays inside the declared write set,
|
|
10
|
-
unrelated change.
|
|
9
|
+
that the diff matches the intent, stays inside the declared write set, does not smuggle in an
|
|
10
|
+
unrelated change, and keeps any rule in `rules` (e.g. a cited proof that code is unused).
|
|
11
11
|
|
|
12
12
|
Never edit any file — findings go back to `apply`, which makes the fix.
|
|
13
13
|
|
|
14
14
|
Report `pass` if the diff is a faithful, scoped implementation of the card.
|
|
15
15
|
|
|
16
16
|
Report `fail` with concrete findings — `file:line`, what is wrong, what to do instead — if the
|
|
17
|
-
diff drifts from the intent, touches an undeclared file, or leaves an obvious defect behind.
|
|
17
|
+
diff drifts from the intent, touches an undeclared file, breaks a rule, or leaves an obvious defect behind.
|
|
18
|
+
The outcome alone does not carry the findings to `apply` — write them to a file in the OS temp
|
|
19
|
+
directory (never inside the worktree) and report that file's path with the outcome.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec
|
|
3
|
+
description: Write the feature's spec — scope, EARS acceptance criteria, ordered tasks — for the user to review.
|
|
4
|
+
effect: mutate
|
|
5
|
+
agent: architect
|
|
6
|
+
gate: human
|
|
7
|
+
outcomes: pass, fail
|
|
8
|
+
---
|
|
9
|
+
Write `specs/<slug>/spec.md` (the slug of the loop's title) and touch nothing else — no code: the
|
|
10
|
+
problem, what is out of scope, acceptance criteria in EARS form ("WHEN <trigger> THE SYSTEM SHALL
|
|
11
|
+
<response>"), each one testable, and an ordered task list sized to one `identify` card apiece,
|
|
12
|
+
ending with an end-to-end verification task. A gate amendment in LOOP.md's notes answers your
|
|
13
|
+
open questions or corrects the spec: revise the spec to follow it.
|
|
14
|
+
|
|
15
|
+
The user reviews the spec before the loop continues. Report `pass` once every criterion is
|
|
16
|
+
testable, with the spec's path and its criteria count in a file in the OS temp directory — report
|
|
17
|
+
that file's path. Report `fail` if a criterion cannot be stated testably: list the open questions
|
|
18
|
+
in such a file and report its path; the user answers them with an amend.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: upgrade-scout
|
|
3
|
+
description: Pick the next dependency upgrade and read its breaking changes, or declare all done.
|
|
4
|
+
effect: read
|
|
5
|
+
agent: researcher
|
|
6
|
+
outcomes: more, done
|
|
7
|
+
---
|
|
8
|
+
Read the requirement and the loop's history (LOOP.md, `git log --format=%(trailers)` on this
|
|
9
|
+
branch). Pick the next package or group the requirement names that is not yet upgraded, skipping
|
|
10
|
+
any release younger than 14 days, and read its changelog or migration guide. Never edit any file.
|
|
11
|
+
|
|
12
|
+
Report `done` when every named package is upgraded. Otherwise report `more` with a card:
|
|
13
|
+
{"intent": "<bump X to N and adapt>", "writeSet": ["<manifest, lockfile, every file to adapt>"],
|
|
14
|
+
"actions": ["<each of: format, imports, rename, logic, new-file, api, delete, architecture>"]}
|
|
15
|
+
Write the breaking changes that hit this repo to a file in the OS temp directory and report that
|
|
16
|
+
file's path with the outcome — the card alone does not carry them to `apply`.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "api-endpoint",
|
|
3
|
+
"description": "Build an HTTP API feature (a Spring MVC controller, say) one endpoint change per iteration: plan, apply, test, write or update the endpoint's Bruno request, run a security review, and review.",
|
|
4
|
+
"category": "development",
|
|
5
|
+
"rules": [
|
|
6
|
+
"The card's write set names the endpoint's .bru requests too, not only the code.",
|
|
7
|
+
"An OpenAPI or Swagger spec edit stops for a human by design; the aggressive preset or trimming LOOP.md's contracts relaxes it."
|
|
8
|
+
],
|
|
9
|
+
"nodes": ["plan", "identify", "apply", "test", "bruno-test", "security-scan", "review"],
|
|
10
|
+
"start": "plan",
|
|
11
|
+
"edges": [
|
|
12
|
+
{ "from": "plan", "on": "pass", "to": "identify" },
|
|
13
|
+
{ "from": "identify", "on": "more", "to": "apply" },
|
|
14
|
+
{ "from": "identify", "on": "done", "to": "$close" },
|
|
15
|
+
{ "from": "apply", "on": "pass", "to": "test" },
|
|
16
|
+
{ "from": "test", "on": "pass", "to": "bruno-test" },
|
|
17
|
+
{ "from": "test", "on": "fail", "to": "apply" },
|
|
18
|
+
{ "from": "bruno-test", "on": "pass", "to": "security-scan" },
|
|
19
|
+
{ "from": "bruno-test", "on": "fail", "to": "$stop" },
|
|
20
|
+
{ "from": "security-scan", "on": "pass", "to": "review" },
|
|
21
|
+
{ "from": "security-scan", "on": "fail", "to": "apply" },
|
|
22
|
+
{ "from": "review", "on": "pass", "to": "identify" },
|
|
23
|
+
{ "from": "review", "on": "fail", "to": "apply" }
|
|
24
|
+
],
|
|
25
|
+
"loops": [
|
|
26
|
+
{ "name": "iterations", "nodes": ["identify", "apply", "test", "bruno-test", "security-scan", "review"], "max": 20, "iteration": true },
|
|
27
|
+
{ "name": "apply-test", "nodes": ["apply", "test"], "max": 5 },
|
|
28
|
+
{ "name": "review-fix", "nodes": ["apply", "test", "bruno-test", "security-scan", "review"], "max": 3 }
|
|
29
|
+
],
|
|
30
|
+
"contracts": ["**/openapi*.yaml", "**/openapi*.yml", "**/openapi*.json", "**/swagger*.yaml", "**/swagger*.yml", "**/swagger*.json"]
|
|
31
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "architecture-decision",
|
|
3
|
+
"description": "Record one architecture decision record per decision the requirement names: draft it, have a skeptic attack it, and let the user review the ADR that survives, until every decision is recorded as Proposed.",
|
|
4
|
+
"category": "architecture",
|
|
5
|
+
"rules": [
|
|
6
|
+
"Pick the next undocumented decision; the card's write set is its ADR file."
|
|
7
|
+
],
|
|
8
|
+
"nodes": ["identify", "adr-draft", "adr-challenge"],
|
|
9
|
+
"start": "identify",
|
|
10
|
+
"edges": [
|
|
11
|
+
{ "from": "identify", "on": "more", "to": "adr-draft" },
|
|
12
|
+
{ "from": "identify", "on": "done", "to": "$close" },
|
|
13
|
+
{ "from": "adr-draft", "on": "pass", "to": "adr-challenge" },
|
|
14
|
+
{ "from": "adr-challenge", "on": "pass", "to": "identify" },
|
|
15
|
+
{ "from": "adr-challenge", "on": "fail", "to": "adr-draft" }
|
|
16
|
+
],
|
|
17
|
+
"loops": [
|
|
18
|
+
{ "name": "iterations", "nodes": ["identify", "adr-draft", "adr-challenge"], "max": 8, "iteration": true },
|
|
19
|
+
{ "name": "challenge-fix", "nodes": ["adr-draft", "adr-challenge"], "max": 3 }
|
|
20
|
+
],
|
|
21
|
+
"weights": { "new-file": 0.2, "architecture": 0.2 }
|
|
22
|
+
}
|
package/src/loops/bugfix.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bugfix",
|
|
3
3
|
"description": "Reproduce the bug with a failing test, then iterate: apply the fix, test, and review, until the requirement is met and the reproduction passes.",
|
|
4
|
+
"category": "development",
|
|
4
5
|
"nodes": ["reproduce", "identify", "apply", "test", "review"],
|
|
5
6
|
"start": "reproduce",
|
|
6
7
|
"edges": [
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ci-repair",
|
|
3
|
+
"description": "Read the branch's failing CI checks, fix one code failure per iteration, test, and push, until CI is green or only flaky or infra failures remain.",
|
|
4
|
+
"category": "day-to-day",
|
|
5
|
+
"nodes": ["ci-triage", "ci-fix", "test"],
|
|
6
|
+
"start": "ci-triage",
|
|
7
|
+
"edges": [
|
|
8
|
+
{ "from": "ci-triage", "on": "more", "to": "ci-fix" },
|
|
9
|
+
{ "from": "ci-triage", "on": "done", "to": "$close" },
|
|
10
|
+
{ "from": "ci-fix", "on": "pass", "to": "test" },
|
|
11
|
+
{ "from": "ci-fix", "on": "fail", "to": "$stop" },
|
|
12
|
+
{ "from": "test", "on": "pass", "to": "ci-triage" },
|
|
13
|
+
{ "from": "test", "on": "fail", "to": "ci-fix" }
|
|
14
|
+
],
|
|
15
|
+
"loops": [
|
|
16
|
+
{ "name": "iterations", "nodes": ["ci-triage", "ci-fix", "test"], "max": 10, "iteration": true },
|
|
17
|
+
{ "name": "fix-test", "nodes": ["ci-fix", "test"], "max": 3 }
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "deps-upgrade",
|
|
3
|
+
"description": "Confirm the suite is green, then upgrade one package or group per iteration: read its breaking changes, bump and adapt, test, audit, and review, until every named package is upgraded.",
|
|
4
|
+
"category": "day-to-day",
|
|
5
|
+
"rules": [
|
|
6
|
+
"The card's write set names the manifest, the lockfile and every file the bump adapts."
|
|
7
|
+
],
|
|
8
|
+
"nodes": ["baseline-green", "upgrade-scout", "apply", "test", "deps-audit", "review"],
|
|
9
|
+
"start": "baseline-green",
|
|
10
|
+
"edges": [
|
|
11
|
+
{ "from": "baseline-green", "on": "pass", "to": "upgrade-scout" },
|
|
12
|
+
{ "from": "baseline-green", "on": "fail", "to": "$stop" },
|
|
13
|
+
{ "from": "upgrade-scout", "on": "more", "to": "apply" },
|
|
14
|
+
{ "from": "upgrade-scout", "on": "done", "to": "$close" },
|
|
15
|
+
{ "from": "apply", "on": "pass", "to": "test" },
|
|
16
|
+
{ "from": "test", "on": "pass", "to": "deps-audit" },
|
|
17
|
+
{ "from": "test", "on": "fail", "to": "apply" },
|
|
18
|
+
{ "from": "deps-audit", "on": "pass", "to": "review" },
|
|
19
|
+
{ "from": "deps-audit", "on": "fail", "to": "apply" },
|
|
20
|
+
{ "from": "review", "on": "pass", "to": "upgrade-scout" },
|
|
21
|
+
{ "from": "review", "on": "fail", "to": "apply" }
|
|
22
|
+
],
|
|
23
|
+
"loops": [
|
|
24
|
+
{ "name": "iterations", "nodes": ["upgrade-scout", "apply", "test", "deps-audit", "review"], "max": 20, "iteration": true },
|
|
25
|
+
{ "name": "apply-test", "nodes": ["apply", "test"], "max": 5 },
|
|
26
|
+
{ "name": "review-fix", "nodes": ["apply", "test", "deps-audit", "review"], "max": 3 }
|
|
27
|
+
],
|
|
28
|
+
"ignoreDeletions": ["**/package-lock.json", "**/yarn.lock", "**/pnpm-lock.yaml", "**/*.lock", "**/gradle.lockfile"]
|
|
29
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "enforce-architecture-rule",
|
|
3
|
+
"description": "Confirm the suite is green, encode the requirement's architecture rule as a test with an allowlist of today's violations for the user to review, then fix one violation per iteration, test, and review, until the allowlist is empty.",
|
|
4
|
+
"category": "architecture",
|
|
5
|
+
"rules": [
|
|
6
|
+
"Each fix removes its violation's allowlist entry in the same iteration."
|
|
7
|
+
],
|
|
8
|
+
"nodes": ["baseline-green", "fitness-define", "identify", "apply", "test", "review"],
|
|
9
|
+
"start": "baseline-green",
|
|
10
|
+
"edges": [
|
|
11
|
+
{ "from": "baseline-green", "on": "pass", "to": "fitness-define" },
|
|
12
|
+
{ "from": "baseline-green", "on": "fail", "to": "$stop" },
|
|
13
|
+
{ "from": "fitness-define", "on": "pass", "to": "identify" },
|
|
14
|
+
{ "from": "fitness-define", "on": "fail", "to": "$stop" },
|
|
15
|
+
{ "from": "identify", "on": "more", "to": "apply" },
|
|
16
|
+
{ "from": "identify", "on": "done", "to": "$close" },
|
|
17
|
+
{ "from": "apply", "on": "pass", "to": "test" },
|
|
18
|
+
{ "from": "test", "on": "pass", "to": "review" },
|
|
19
|
+
{ "from": "test", "on": "fail", "to": "apply" },
|
|
20
|
+
{ "from": "review", "on": "pass", "to": "identify" },
|
|
21
|
+
{ "from": "review", "on": "fail", "to": "apply" }
|
|
22
|
+
],
|
|
23
|
+
"loops": [
|
|
24
|
+
{ "name": "iterations", "nodes": ["identify", "apply", "test", "review"], "max": 20, "iteration": true },
|
|
25
|
+
{ "name": "apply-test", "nodes": ["apply", "test"], "max": 5 },
|
|
26
|
+
{ "name": "review-fix", "nodes": ["apply", "test", "review"], "max": 3 }
|
|
27
|
+
]
|
|
28
|
+
}
|
package/src/loops/feature.json
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "feature",
|
|
3
|
-
"description": "Plan the feature into ordered iterations, then build each one: apply, test, and review, until the plan is complete.",
|
|
4
|
-
"
|
|
3
|
+
"description": "Plan the feature into ordered iterations, then build each one: apply, test, and review, until the plan is complete — and an independent done-check maps every requirement to a passing test before the loop closes.",
|
|
4
|
+
"category": "development",
|
|
5
|
+
"nodes": ["plan", "identify", "apply", "test", "review", "done-check"],
|
|
5
6
|
"start": "plan",
|
|
6
7
|
"edges": [
|
|
7
8
|
{ "from": "plan", "on": "pass", "to": "identify" },
|
|
8
9
|
{ "from": "identify", "on": "more", "to": "apply" },
|
|
9
|
-
{ "from": "identify", "on": "done", "to": "
|
|
10
|
+
{ "from": "identify", "on": "done", "to": "done-check" },
|
|
10
11
|
{ "from": "apply", "on": "pass", "to": "test" },
|
|
11
12
|
{ "from": "test", "on": "pass", "to": "review" },
|
|
12
13
|
{ "from": "test", "on": "fail", "to": "apply" },
|
|
13
14
|
{ "from": "review", "on": "pass", "to": "identify" },
|
|
14
|
-
{ "from": "review", "on": "fail", "to": "apply" }
|
|
15
|
+
{ "from": "review", "on": "fail", "to": "apply" },
|
|
16
|
+
{ "from": "done-check", "on": "pass", "to": "$close" },
|
|
17
|
+
{ "from": "done-check", "on": "fail", "to": "identify" }
|
|
15
18
|
],
|
|
16
19
|
"loops": [
|
|
17
|
-
{ "name": "iterations", "nodes": ["identify", "apply", "test", "review"], "max": 20, "iteration": true },
|
|
20
|
+
{ "name": "iterations", "nodes": ["identify", "apply", "test", "review", "done-check"], "max": 20, "iteration": true },
|
|
18
21
|
{ "name": "apply-test", "nodes": ["apply", "test"], "max": 5 },
|
|
19
22
|
{ "name": "review-fix", "nodes": ["apply", "test", "review"], "max": 3 }
|
|
20
23
|
]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fix-flaky-tests",
|
|
3
|
+
"description": "Confirm the suspected flaky tests by 20 repeated runs, then fix one per iteration at its root cause, re-confirm it with 20 runs, test, and review.",
|
|
4
|
+
"category": "tests",
|
|
5
|
+
"rules": [
|
|
6
|
+
"Fix at the root cause — shared state, ordering, time, concurrency — never with a retry, a sleep or a longer timeout.",
|
|
7
|
+
"A test that fails every run is a bug for the bugfix template; one that never fails is not fixed."
|
|
8
|
+
],
|
|
9
|
+
"nodes": ["flake-repro", "identify", "apply", "flake-check", "test", "review"],
|
|
10
|
+
"start": "flake-repro",
|
|
11
|
+
"edges": [
|
|
12
|
+
{ "from": "flake-repro", "on": "flaky", "to": "identify" },
|
|
13
|
+
{ "from": "flake-repro", "on": "stable", "to": "$stop" },
|
|
14
|
+
{ "from": "flake-repro", "on": "broken", "to": "$stop" },
|
|
15
|
+
{ "from": "identify", "on": "more", "to": "apply" },
|
|
16
|
+
{ "from": "identify", "on": "done", "to": "$close" },
|
|
17
|
+
{ "from": "apply", "on": "pass", "to": "flake-check" },
|
|
18
|
+
{ "from": "flake-check", "on": "stable", "to": "test" },
|
|
19
|
+
{ "from": "flake-check", "on": "flaky", "to": "apply" },
|
|
20
|
+
{ "from": "test", "on": "pass", "to": "review" },
|
|
21
|
+
{ "from": "test", "on": "fail", "to": "apply" },
|
|
22
|
+
{ "from": "review", "on": "pass", "to": "identify" },
|
|
23
|
+
{ "from": "review", "on": "fail", "to": "apply" }
|
|
24
|
+
],
|
|
25
|
+
"loops": [
|
|
26
|
+
{ "name": "iterations", "nodes": ["identify", "apply", "flake-check", "test", "review"], "max": 10, "iteration": true },
|
|
27
|
+
{ "name": "stabilise", "nodes": ["apply", "flake-check"], "max": 4 },
|
|
28
|
+
{ "name": "review-fix", "nodes": ["apply", "flake-check", "test", "review"], "max": 3 }
|
|
29
|
+
]
|
|
30
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "legacy-refactor",
|
|
3
|
+
"description": "Confirm the suite is green, pin the code's current behaviour with characterization tests in their own commit, then refactor behind that net: apply, test, and review, until the requirement is met.",
|
|
4
|
+
"category": "refactoring",
|
|
5
|
+
"nodes": ["baseline-green", "characterize", "identify", "apply", "test", "review"],
|
|
6
|
+
"start": "baseline-green",
|
|
7
|
+
"edges": [
|
|
8
|
+
{ "from": "baseline-green", "on": "pass", "to": "characterize" },
|
|
9
|
+
{ "from": "baseline-green", "on": "fail", "to": "$stop" },
|
|
10
|
+
{ "from": "characterize", "on": "pass", "to": "identify" },
|
|
11
|
+
{ "from": "characterize", "on": "fail", "to": "$stop" },
|
|
12
|
+
{ "from": "identify", "on": "more", "to": "apply" },
|
|
13
|
+
{ "from": "identify", "on": "done", "to": "$close" },
|
|
14
|
+
{ "from": "apply", "on": "pass", "to": "test" },
|
|
15
|
+
{ "from": "test", "on": "pass", "to": "review" },
|
|
16
|
+
{ "from": "test", "on": "fail", "to": "apply" },
|
|
17
|
+
{ "from": "review", "on": "pass", "to": "identify" },
|
|
18
|
+
{ "from": "review", "on": "fail", "to": "apply" }
|
|
19
|
+
],
|
|
20
|
+
"loops": [
|
|
21
|
+
{ "name": "iterations", "nodes": ["identify", "apply", "test", "review"], "max": 20, "iteration": true },
|
|
22
|
+
{ "name": "apply-test", "nodes": ["apply", "test"], "max": 5 },
|
|
23
|
+
{ "name": "review-fix", "nodes": ["apply", "test", "review"], "max": 3 }
|
|
24
|
+
],
|
|
25
|
+
"weights": { "logic": 0.6 }
|
|
26
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "legacy-tests",
|
|
3
|
+
"description": "Confirm the suite is green, then pin legacy behaviour one change point at a time: characterization tests, a run, and a mutation check that proves they bite.",
|
|
4
|
+
"category": "tests",
|
|
5
|
+
"rules": [
|
|
6
|
+
"Tests only: production code is never touched."
|
|
7
|
+
],
|
|
8
|
+
"nodes": ["baseline-green", "identify", "characterize", "test", "mutation-check"],
|
|
9
|
+
"start": "baseline-green",
|
|
10
|
+
"edges": [
|
|
11
|
+
{ "from": "baseline-green", "on": "pass", "to": "identify" },
|
|
12
|
+
{ "from": "baseline-green", "on": "fail", "to": "$stop" },
|
|
13
|
+
{ "from": "identify", "on": "more", "to": "characterize" },
|
|
14
|
+
{ "from": "identify", "on": "done", "to": "$close" },
|
|
15
|
+
{ "from": "characterize", "on": "pass", "to": "test" },
|
|
16
|
+
{ "from": "characterize", "on": "fail", "to": "$stop" },
|
|
17
|
+
{ "from": "test", "on": "pass", "to": "mutation-check" },
|
|
18
|
+
{ "from": "test", "on": "fail", "to": "characterize" },
|
|
19
|
+
{ "from": "mutation-check", "on": "pass", "to": "identify" },
|
|
20
|
+
{ "from": "mutation-check", "on": "fail", "to": "characterize" },
|
|
21
|
+
{ "from": "mutation-check", "on": "unavailable", "to": "identify" }
|
|
22
|
+
],
|
|
23
|
+
"loops": [
|
|
24
|
+
{ "name": "iterations", "nodes": ["identify", "characterize", "test", "mutation-check"], "max": 20, "iteration": true },
|
|
25
|
+
{ "name": "write-run", "nodes": ["characterize", "test"], "max": 3 },
|
|
26
|
+
{ "name": "kill-mutants", "nodes": ["characterize", "test", "mutation-check"], "max": 3 }
|
|
27
|
+
],
|
|
28
|
+
"weights": { "new-file": 0.2 }
|
|
29
|
+
}
|
package/src/loops/refactor.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "refactor",
|
|
3
|
-
"description": "Confirm the suite is green before touching anything, then iterate on the shape of the code alone.
|
|
3
|
+
"description": "Confirm the suite is green before touching anything, then iterate on the shape of the code alone.",
|
|
4
|
+
"category": "refactoring",
|
|
5
|
+
"rules": [
|
|
6
|
+
"Tests are not edited: a refactor that needs a different test is a behaviour change, not a refactor."
|
|
7
|
+
],
|
|
4
8
|
"nodes": ["baseline-green", "identify", "apply", "test"],
|
|
5
9
|
"start": "baseline-green",
|
|
6
10
|
"edges": [
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "remove-dead-code",
|
|
3
|
+
"description": "Confirm the suite is green, then remove one coherent group of unused code per iteration — exports, classes, files, retired flags — test it, and review it. Deletions score soft, not blocking.",
|
|
4
|
+
"category": "refactoring",
|
|
5
|
+
"rules": [
|
|
6
|
+
"Each card's intent cites the proof it is unused: the requirement's tool output (knip, ts-prune, vulture, PMD or IntelliJ inspections) and a reference search (git grep over code AND resources) for reflection, DI by name, Spring bean names and config.",
|
|
7
|
+
"Generated sources do not count as unused.",
|
|
8
|
+
"Public entry points belong in LOOP.md's contracts, not in a deletion."
|
|
9
|
+
],
|
|
10
|
+
"nodes": ["baseline-green", "identify", "apply", "test", "review"],
|
|
11
|
+
"start": "baseline-green",
|
|
12
|
+
"edges": [
|
|
13
|
+
{ "from": "baseline-green", "on": "pass", "to": "identify" },
|
|
14
|
+
{ "from": "baseline-green", "on": "fail", "to": "$stop" },
|
|
15
|
+
{ "from": "identify", "on": "more", "to": "apply" },
|
|
16
|
+
{ "from": "identify", "on": "done", "to": "$close" },
|
|
17
|
+
{ "from": "apply", "on": "pass", "to": "test" },
|
|
18
|
+
{ "from": "test", "on": "pass", "to": "review" },
|
|
19
|
+
{ "from": "test", "on": "fail", "to": "apply" },
|
|
20
|
+
{ "from": "review", "on": "pass", "to": "identify" },
|
|
21
|
+
{ "from": "review", "on": "fail", "to": "apply" }
|
|
22
|
+
],
|
|
23
|
+
"loops": [
|
|
24
|
+
{ "name": "iterations", "nodes": ["identify", "apply", "test", "review"], "max": 20, "iteration": true },
|
|
25
|
+
{ "name": "apply-test", "nodes": ["apply", "test"], "max": 5 },
|
|
26
|
+
{ "name": "review-fix", "nodes": ["apply", "test", "review"], "max": 3 }
|
|
27
|
+
],
|
|
28
|
+
"weights": { "delete": 0.5 },
|
|
29
|
+
"ignoreDeletions": ["**/generated/**", "**/generated-sources/**", "**/target/**", "**/build/generated/**"]
|
|
30
|
+
}
|