mutate4py 0.1.0__tar.gz
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.
- mutate4py-0.1.0/.agents/backlog.md +19 -0
- mutate4py-0.1.0/.agents/ledger-project.md +54 -0
- mutate4py-0.1.0/.agents/ledger-swarmforge.md +68 -0
- mutate4py-0.1.0/.agents/references/equivalent-mutants.md +21 -0
- mutate4py-0.1.0/.agents/roles/QA.md +16 -0
- mutate4py-0.1.0/.agents/roles/cleaner.md +10 -0
- mutate4py-0.1.0/.agents/roles/coder.md +10 -0
- mutate4py-0.1.0/.agents/roles/hardender.md +32 -0
- mutate4py-0.1.0/.agents/skills/agent-retro/SKILL.md +219 -0
- mutate4py-0.1.0/.agents/skills/agent-retro/scripts/extract.py +940 -0
- mutate4py-0.1.0/.agents/skills/domain-modeling/ADR-FORMAT.md +47 -0
- mutate4py-0.1.0/.agents/skills/domain-modeling/CONTEXT-FORMAT.md +60 -0
- mutate4py-0.1.0/.agents/skills/domain-modeling/SKILL.md +74 -0
- mutate4py-0.1.0/.agents/skills/explain/SKILL.md +34 -0
- mutate4py-0.1.0/.agents/skills/grill-with-docs/SKILL.md +7 -0
- mutate4py-0.1.0/.agents/skills/grilling/SKILL.md +10 -0
- mutate4py-0.1.0/.agents/skills/recall/SKILL.md +123 -0
- mutate4py-0.1.0/.agents/skills/replay/SKILL.md +141 -0
- mutate4py-0.1.0/.agents/skills/review/SKILL.md +220 -0
- mutate4py-0.1.0/.agents/skills/review/references/review-rules.md +87 -0
- mutate4py-0.1.0/.agents/skills/search/SKILL.md +70 -0
- mutate4py-0.1.0/.agents/skills/session-crosslink/SKILL.md +141 -0
- mutate4py-0.1.0/.agents/skills/session-handoff/SKILL.md +137 -0
- mutate4py-0.1.0/.agents/skills/session-to-skill/SKILL.md +210 -0
- mutate4py-0.1.0/.agents/skills/setup-swarm/SKILL.md +150 -0
- mutate4py-0.1.0/.agents/skills/teach/SKILL.md +130 -0
- mutate4py-0.1.0/.agents/skills/using-entire/SKILL.md +149 -0
- mutate4py-0.1.0/.agents/skills/what-happened/SKILL.md +333 -0
- mutate4py-0.1.0/.claude/agents/entire-search.md +25 -0
- mutate4py-0.1.0/.claude/settings.json +85 -0
- mutate4py-0.1.0/.entire/.gitignore +5 -0
- mutate4py-0.1.0/.entire/settings.json +10 -0
- mutate4py-0.1.0/.github/workflows/ci.yml +53 -0
- mutate4py-0.1.0/.github/workflows/release.yml +29 -0
- mutate4py-0.1.0/.gitignore +25 -0
- mutate4py-0.1.0/AGENTS.md +38 -0
- mutate4py-0.1.0/CONTEXT.md +204 -0
- mutate4py-0.1.0/LICENSE +21 -0
- mutate4py-0.1.0/PKG-INFO +70 -0
- mutate4py-0.1.0/README.md +55 -0
- mutate4py-0.1.0/acceptance/__init__.py +0 -0
- mutate4py-0.1.0/acceptance/fixtures/empty_units.py +9 -0
- mutate4py-0.1.0/acceptance/fixtures/mixed_operators.py +10 -0
- mutate4py-0.1.0/acceptance/fixtures/module_level.py +4 -0
- mutate4py-0.1.0/acceptance/fixtures/plain.py +6 -0
- mutate4py-0.1.0/acceptance/fixtures/stale.py +11 -0
- mutate4py-0.1.0/acceptance/generate_acceptance.py +153 -0
- mutate4py-0.1.0/acceptance/run_acceptance.sh +142 -0
- mutate4py-0.1.0/acceptance/run_gherkin_mutation.sh +95 -0
- mutate4py-0.1.0/acceptance/runner_adapter.py +192 -0
- mutate4py-0.1.0/acceptance/steps/__init__.py +0 -0
- mutate4py-0.1.0/acceptance/steps/cli_surface_helpers.py +176 -0
- mutate4py-0.1.0/acceptance/steps/cli_surface_qa_steps.py +297 -0
- mutate4py-0.1.0/acceptance/steps/cli_surface_steps.py +194 -0
- mutate4py-0.1.0/acceptance/steps/coverage_helpers.py +187 -0
- mutate4py-0.1.0/acceptance/steps/coverage_qa_steps.py +266 -0
- mutate4py-0.1.0/acceptance/steps/coverage_steps.py +206 -0
- mutate4py-0.1.0/acceptance/steps/manifest_qa_steps.py +247 -0
- mutate4py-0.1.0/acceptance/steps/manifest_steps.py +455 -0
- mutate4py-0.1.0/acceptance/steps/parallel_workers_qa_steps.py +617 -0
- mutate4py-0.1.0/acceptance/steps/parallel_workers_steps.py +681 -0
- mutate4py-0.1.0/acceptance/steps/run_loop_helpers.py +86 -0
- mutate4py-0.1.0/acceptance/steps/run_loop_qa_steps.py +396 -0
- mutate4py-0.1.0/acceptance/steps/run_loop_steps.py +621 -0
- mutate4py-0.1.0/acceptance/steps/site_discovery_qa_steps.py +198 -0
- mutate4py-0.1.0/acceptance/steps/site_discovery_steps.py +241 -0
- mutate4py-0.1.0/acceptance/steps/step_lib.py +83 -0
- mutate4py-0.1.0/check.sh +99 -0
- mutate4py-0.1.0/docs/adr/0001-site-discovery-and-operators.md +102 -0
- mutate4py-0.1.0/docs/adr/0002-scan-counts-only-no-manifest-in-f1.md +63 -0
- mutate4py-0.1.0/docs/adr/0003-ci-skeleton-crap-and-mutation-gates-deferred.md +62 -0
- mutate4py-0.1.0/docs/adr/0004-manifest-faithful-port-of-mutate4go.md +72 -0
- mutate4py-0.1.0/docs/adr/0005-manifest-hash-is-ast-dump.md +47 -0
- mutate4py-0.1.0/docs/adr/0006-update-manifest-idempotent.md +57 -0
- mutate4py-0.1.0/docs/adr/0007-coverage-default-path-and-line-only-gate.md +49 -0
- mutate4py-0.1.0/docs/adr/0008-coverage-flags-pairwise-exclusive.md +39 -0
- mutate4py-0.1.0/docs/adr/0009-coverage-partition-surfaces-via-scan.md +48 -0
- mutate4py-0.1.0/docs/adr/0010-run-loop-composes-f3-coverage-and-baseline-gate.md +42 -0
- mutate4py-0.1.0/docs/adr/0011-timeout-printed-verbatim-folded-into-killed.md +45 -0
- mutate4py-0.1.0/docs/adr/0012-run-loop-serial-only-no-worker-token.md +64 -0
- mutate4py-0.1.0/docs/adr/0013-max-workers-restored-as-real-flag.md +62 -0
- mutate4py-0.1.0/docs/adr/0014-cli-validation-mirrors-upstream-parse-model.md +52 -0
- mutate4py-0.1.0/docs/adr/0015-parallel-workers-via-uv-clone-per-worker.md +118 -0
- mutate4py-0.1.0/docs/plan.md +258 -0
- mutate4py-0.1.0/docs/spec.md +383 -0
- mutate4py-0.1.0/features/ci.feature +92 -0
- mutate4py-0.1.0/features/cli-surface.feature +230 -0
- mutate4py-0.1.0/features/cli-surface_qa.feature +117 -0
- mutate4py-0.1.0/features/coverage.feature +169 -0
- mutate4py-0.1.0/features/coverage_qa.feature +145 -0
- mutate4py-0.1.0/features/manifest.feature +215 -0
- mutate4py-0.1.0/features/manifest_qa.feature +99 -0
- mutate4py-0.1.0/features/parallel-workers.feature +294 -0
- mutate4py-0.1.0/features/parallel-workers_qa.feature +154 -0
- mutate4py-0.1.0/features/run-loop.feature +247 -0
- mutate4py-0.1.0/features/run-loop_qa.feature +144 -0
- mutate4py-0.1.0/features/site-discovery.feature +157 -0
- mutate4py-0.1.0/features/site-discovery_qa.feature +97 -0
- mutate4py-0.1.0/features/test-selection.feature +55 -0
- mutate4py-0.1.0/perf.sh +89 -0
- mutate4py-0.1.0/pyproject.toml +58 -0
- mutate4py-0.1.0/src/mutate4py/__init__.py +3 -0
- mutate4py-0.1.0/src/mutate4py/__main__.py +431 -0
- mutate4py-0.1.0/src/mutate4py/_cmd.py +25 -0
- mutate4py-0.1.0/src/mutate4py/_coverage.py +123 -0
- mutate4py-0.1.0/src/mutate4py/_discovery.py +323 -0
- mutate4py-0.1.0/src/mutate4py/_ids.py +21 -0
- mutate4py-0.1.0/src/mutate4py/_manifest.py +172 -0
- mutate4py-0.1.0/src/mutate4py/_runner.py +629 -0
- mutate4py-0.1.0/src/mutate4py/_test_selection.py +113 -0
- mutate4py-0.1.0/src/mutate4py/_workers.py +241 -0
- mutate4py-0.1.0/swarm +127 -0
- mutate4py-0.1.0/swarmforge/constitution/articles/engineering.prompt +44 -0
- mutate4py-0.1.0/swarmforge/constitution/articles/handoffs.prompt +83 -0
- mutate4py-0.1.0/swarmforge/constitution/articles/local-engineering.prompt +11 -0
- mutate4py-0.1.0/swarmforge/constitution/articles/local-workflow.prompt +11 -0
- mutate4py-0.1.0/swarmforge/constitution/articles/project.prompt +15 -0
- mutate4py-0.1.0/swarmforge/constitution/articles/workflow.prompt +21 -0
- mutate4py-0.1.0/swarmforge/constitution.prompt +4 -0
- mutate4py-0.1.0/swarmforge/roles/QA.prompt +27 -0
- mutate4py-0.1.0/swarmforge/roles/architect.prompt +41 -0
- mutate4py-0.1.0/swarmforge/roles/cleaner.prompt +35 -0
- mutate4py-0.1.0/swarmforge/roles/coder.prompt +31 -0
- mutate4py-0.1.0/swarmforge/roles/curator.prompt +82 -0
- mutate4py-0.1.0/swarmforge/roles/hardender.prompt +32 -0
- mutate4py-0.1.0/swarmforge/roles/integrator.prompt +42 -0
- mutate4py-0.1.0/swarmforge/roles/specifier.prompt +42 -0
- mutate4py-0.1.0/swarmforge/roles/ux-engineer.prompt +30 -0
- mutate4py-0.1.0/swarmforge/skills/agent-retro/SKILL.md +219 -0
- mutate4py-0.1.0/swarmforge/skills/agent-retro/scripts/extract.py +940 -0
- mutate4py-0.1.0/swarmforge/skills/setup-swarm/SKILL.md +150 -0
- mutate4py-0.1.0/swarmforge/swarmforge.conf +20 -0
- mutate4py-0.1.0/swarmforge/templates/feature.feature +82 -0
- mutate4py-0.1.0/tests/__init__.py +0 -0
- mutate4py-0.1.0/tests/test_cli_surface_helpers.py +351 -0
- mutate4py-0.1.0/tests/test_cmd.py +41 -0
- mutate4py-0.1.0/tests/test_coverage.py +373 -0
- mutate4py-0.1.0/tests/test_coverage_helpers.py +304 -0
- mutate4py-0.1.0/tests/test_discovery.py +433 -0
- mutate4py-0.1.0/tests/test_main.py +1642 -0
- mutate4py-0.1.0/tests/test_manifest.py +625 -0
- mutate4py-0.1.0/tests/test_properties.py +370 -0
- mutate4py-0.1.0/tests/test_runner.py +1179 -0
- mutate4py-0.1.0/tests/test_test_selection.py +350 -0
- mutate4py-0.1.0/tests/test_workers.py +348 -0
- mutate4py-0.1.0/uv.lock +731 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Enforcement Gate Backlog
|
|
2
|
+
|
|
3
|
+
Dated proposals for mechanical enforcement gates, config changes, or CI guardrails.
|
|
4
|
+
Format: `<date> | <category> | <failure-class> | <affected> | <status> | <description>`
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
2026-06-28 | swarmforge-pattern | convention-gap | specifier | pending | Glossary canon is CONTEXT.md (## Glossary) per domain-modeling skill + sibling mutate4js, but F1-F4 specifier sessions wrote entries into an orphan docs/glossary.md (nothing linked it; the two drifted). Consolidated into CONTEXT.md and deleted docs/glossary.md in F5. specifier.prompt phase 3 says "glossary entries are part of the deliverable" without naming the file — add "write glossary terms to CONTEXT.md ## Glossary, never docs/glossary.md".
|
|
8
|
+
2026-06-25 | project-config | tool-error | all-roles | pending | Disable GPG commit signing in all worktrees' .git/config to eliminate 1Password SSH agent failures (git config --local commit.gpgsign false per worktree, or a global swarm setup step)
|
|
9
|
+
2026-06-25 | swarmforge-pattern | tool-error | architect,cleaner | pending | 1Password SSH agent unavailable in swarm sessions causes git fetch and commit signing failures; two roles required manual workaround (-c commit.gpgsign=false); setup-swarm should disable signing in each worktree
|
|
10
|
+
2026-06-25 | swarmforge-pattern | tool-error | cleaner,QA,hardender | pending | External GitHub tool installs blocked by auto-mode classifier across 3 roles; engineering.prompt needs explicit fallback rule: "if external install is blocked, use locally installed binary and continue"
|
|
11
|
+
2026-06-25 | swarmforge-pattern | tool-error | cleaner,QA,hardender | pending | extract.py returns zero non-null arc content on Claude Code 2.1.191+ across all roles (5 sessions: architect, cleaner, integrator, hardender, QA); investigate JSONL format change and update extract.py
|
|
12
|
+
2026-06-26 | swarmforge-pattern | tool-error | specifier,coder,cleaner,architect,hardender,QA | pending | extract.py arc null-content now confirmed across 9+ sessions and 6 roles in CC 2.1.193; this is now critical-path for all agent-retro data analysis — ESCALATE
|
|
13
|
+
2026-06-26 | swarmforge-pattern | convention-gap | specifier,specifier | pending | ir-dry-checker (specifier phase 6) is not installed; two specifier sessions in this pipeline hit it; either ship the tool or reword phase 6 to manual-prune
|
|
14
|
+
2026-06-26 | swarmforge-pattern | convention-gap | specifier,architect | pending | role-level tool API discovery gap: both specifier (grill-with-docs invocation failure) and architect (fc.hexaString/fc.float missing) were blocked by undocumented API surfaces; add "run --help or grep available API before using any unfamiliar tool/library function" to constitution
|
|
15
|
+
2026-06-26 | swarmforge-pattern | convention-gap | cleaner,QA,integrator | pending | pre-handoff lint+format verification gap: cleaner and QA do not run ruff check+format before handing off; integrator absorbs 2+ fix-push-watch cycles per pipeline run; add mandatory pre-handoff lint+format step to engineering verification
|
|
16
|
+
2026-06-26 | swarmforge-pattern | missing-artifact | coder,QA,cleaner | pending | drywall DRY check blocked by auto-mode sandbox across 3 roles attempting binary download; pre-install drywall in worktree setup or grant explicit permission in project settings.json
|
|
17
|
+
2026-06-26 | swarmforge-pattern | missing-artifact | QA,cleaner | pending | merge_and_process <role> <commit> appears in handoff PAYLOADs for non-hardender roles but no such script exists; both QA and cleaner had to infer the merge intent manually; either ship the script for all roles or update handoff spec to document the convention
|
|
18
|
+
2026-06-28 | swarmforge-pattern | tool-error | hardender | pending | uv re-provisioning per Gherkin mutation makes acceptance mutation slow (~10s/mutation); consider pre-provisioning worker trees once in a shared acceptance fixture or mocking _provision_worker in acceptance scenarios to avoid per-mutation cost
|
|
19
|
+
2026-06-28 | swarmforge-pattern | convention-gap | integrator | pending | gh pr create blocked by auto-mode classifier even when integrator role prompt explicitly owns "Open the PR"; consider pre-authorizing integrator's gh pr create in project settings.json allowlist
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Ledger — Project Knowledge
|
|
2
|
+
|
|
3
|
+
Permanent, append-only. Contains only `promoted` and `rejected→first-occurrence` items.
|
|
4
|
+
Format: `<date> | <session-id> | <role> | <failure-class> | <verdict> | <one-line summary>`
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
2026-06-25 | 9bc9e159 | architect | convention-gap | promoted→AGENTS.md | Correct role name spelling: hardender (two d's); worktree dir names are authoritative
|
|
8
|
+
2026-06-25 | 9bc9e159 | architect | tool-error | rejected→first-occurrence | extract.py null-arc: all arc entries return null content on Claude Code 2.1.191
|
|
9
|
+
2026-06-25 | 00466112 | cleaner | missing-artifact | promoted→AGENTS.md | drywall at /Users/gabadi/.local/bin/drywall (not in PyPI); crap4py from local sibling
|
|
10
|
+
2026-06-25 | 58d11592 | integrator | tool-error | rejected→first-occurrence | extract.py null-arc: integrator session confirms pattern (same failure class)
|
|
11
|
+
2026-06-25 | e4b18370 | curator | tool-error | rejected→first-occurrence | agent-retro: use grep -A50 "## Actions" instead of cat to read retros (full dump = 4-6x larger)
|
|
12
|
+
2026-06-25 | ba459785 | hardender | convention-gap | promoted→.agents/roles/hardender.md | mutate4py is the mutation tool — use mutmut on this project's own test suite, not itself
|
|
13
|
+
2026-06-25 | ba459785 | hardender | missing-artifact | promoted→AGENTS.md | crap4py installed from local sibling ~/workspace/addi/crap4py (not PyPI or GitHub URL)
|
|
14
|
+
2026-06-25 | ba459785 | hardender | missing-artifact | rejected→first-occurrence | gherkin-mutator --help not supported; read source to find --feature flag
|
|
15
|
+
2026-06-25 | 4c684992 | QA | tool-error | rejected→first-occurrence | extract.py null-arc: QA session confirms pattern (5th role reporting same failure)
|
|
16
|
+
2026-06-26 | ae4e1d02 | cleaner | convention-gap | promoted→AGENTS.md | uv run mutate4py is correct invocation; uvx breaks self-referential scanning
|
|
17
|
+
2026-06-26 | 93e42778 | coder | convention-gap | promoted→.agents/roles/coder.md | dead-code guard: delete stale partial impl after extracting a helper, before running tests
|
|
18
|
+
2026-06-26 | 93e42778 | coder | convention-gap | rejected→first-occurrence | Gherkin label "renaming the function" ambiguous (function vs parameter rename); specifier should clarify
|
|
19
|
+
2026-06-26 | 86d7f06f | hardender | convention-gap | promoted→.agents/roles/hardender.md | merge_and_process means git merge + hardening sequence, not a script on PATH
|
|
20
|
+
2026-06-26 | 86d7f06f | hardender | convention-gap | promoted→.agents/roles/hardender.md | mutmut 3.x uses --max-children not --max-workers
|
|
21
|
+
2026-06-26 | ba459785 | hardender | missing-artifact | promoted→AGENTS.md | gherkin-mutator flags: --feature, --generated-dir required; no --help; defaults to features/a-feature.feature
|
|
22
|
+
2026-06-26 | 48c13d25 | QA | convention-gap | promoted→AGENTS.md | manifest QA fixtures are committed inputs; all manifest QA steps must use writable-copy pattern
|
|
23
|
+
2026-06-26 | 14e97446 | specifier | convention-gap | promoted→AGENTS.md | gherkin-parser requires two args: gherkin-parser <feature-file> <json-output>
|
|
24
|
+
2026-06-26 | d24200ea | architect | convention-gap | promoted→AGENTS.md | _coverage.py must not import _discovery.py; IO-near code must not depend on IO-free domain types
|
|
25
|
+
2026-06-26 | b2aa029b | cleaner | convention-gap | promoted→AGENTS.md | acceptance step files are boundary files (15-site threshold); pure logic belongs in *_helpers.py modules
|
|
26
|
+
2026-06-26 | b2aa029b | cleaner | convention-gap | promoted→AGENTS.md | coverage_helpers.py is testable module for acceptance step helper functions; tests in tests/test_coverage_helpers.py
|
|
27
|
+
2026-06-26 | b2aa029b | cleaner | convention-gap | rejected→first-occurrence | agent-retro step 5: scan site list for per-pattern contributors before starting boundary-file mutation-site reduction
|
|
28
|
+
2026-06-26 | c53799e5 | architect | tool-error | rejected→first-occurrence | fork agent stalled (600s) when dispatched for open-ended architectural review with large inherited context
|
|
29
|
+
2026-06-26 | 0fe93f63 | coder | convention-gap | promoted→AGENTS.md | gherkin-parser must be called without rtk prefix; rtk breaks it
|
|
30
|
+
2026-06-26 | 0fe93f63 | coder | convention-gap | promoted→AGENTS.md | generate_acceptance.py: pass just module_name, not acceptance.steps.module_name
|
|
31
|
+
2026-06-26 | 0fe93f63 | coder | convention-gap | promoted→AGENTS.md | strip+modify+re-embed pattern: when modifying source with embedded manifest, strip first then re-embed
|
|
32
|
+
2026-06-26 | bb18021c | architect | convention-gap | rejected→first-occurrence | apply_mutant must stay in _discovery.py alongside Site and line-index helpers; do not re-extract
|
|
33
|
+
2026-06-26 | f72497fa | cleaner | convention-gap | promoted→AGENTS.md | mutate4py --scan accepts one file at a time; loop over files separately
|
|
34
|
+
2026-06-26 | da863ce7 | hardender | convention-gap | promoted→.agents/roles/hardender.md | mutmut run takes mutant-name patterns, not file paths; use bare mutmut run to run all
|
|
35
|
+
2026-06-26 | da863ce7 | hardender | convention-gap | promoted→AGENTS.md | runner_adapter.py must be executable (chmod +x) before gherkin-mutator can use it
|
|
36
|
+
2026-06-26 | da863ce7 | hardender | convention-gap | promoted→.agents/references/equivalent-mutants.md | five equivalent mutant categories for this project (falsy None, argparse dest, help-text, single-comma DA, single-op compare)
|
|
37
|
+
2026-06-28 | 976a22ac | hardender | convention-gap | promoted→.agents/roles/hardender.md | mutmut v3 module-path filtering fails (AssertionError); always run `mutmut run --max-children 8` first to populate stats before filtering
|
|
38
|
+
2026-06-28 | 976a22ac | hardender | convention-gap | promoted→.agents/roles/hardender.md | gherkin-mutator uses --feature <path> (named), not positional; check Clojure source at /tmp/aps-build/bb/... if CLI unclear
|
|
39
|
+
2026-06-28 | dc019dd9 | cleaner | convention-gap | promoted→.agents/roles/cleaner.md | boundary file 15-site threshold is a trigger not hard gate; document irreducible minimum when all testable logic is extracted
|
|
40
|
+
2026-06-28 | dc019dd9 | cleaner | convention-gap | promoted→.agents/roles/cleaner.md | when writing test for refactored function, verify error message strings match new implementation — do not copy from old code
|
|
41
|
+
2026-06-28 | a80e933d | integrator | convention-gap | promoted→.agents/roles/QA.md | QA must run ruff check+format before handoff (recurrence of 9fd9fe97); QA.md created with pre-handoff verification rule
|
|
42
|
+
2026-06-28 | 4f7feec9 | QA | convention-gap | promoted→.agents/roles/QA.md | before marking QA done, grep run_acceptance.sh for every *_qa.feature and confirm QA_STEPS_MAP entry exists; silent skip masks test failures
|
|
43
|
+
2026-06-28 | 3d5cea42 | coder | convention-gap | promoted→.agents/roles/coder.md | check for run_acceptance.sh wrapper before invoking acceptance generation scripts directly; scripts require positional args and fail silently
|
|
44
|
+
2026-06-28 | 3814e69e | cleaner | convention-gap | promoted→.agents/roles/cleaner.md | manifest "NEW" hashes after coder handoff are expected; do not hand-edit — mutation tool refreshes them on first scan
|
|
45
|
+
2026-06-28 | 8c38deb4 | architect | convention-gap | promoted→AGENTS.md | __main__.py is CLI adapter only; scan_report/scan_report_with_coverage/update_manifest belong in _runner.py and are tested directly
|
|
46
|
+
2026-06-28 | dc019dd9 | cleaner | convention-gap | promoted→AGENTS.md | cli_surface_helpers.py is testable module for CLI surface step helpers; tests in tests/test_cli_surface_helpers.py
|
|
47
|
+
2026-06-28 | 7b3678f5 | architect | tool-error | rejected→first-occurrence | agent-retro: $CLAUDE_SKILL_DIR not set in harness; extract.py path resolution requires find fallback
|
|
48
|
+
2026-06-28 | 3b4f8734 | hardender | convention-gap | promoted→.agents/roles/hardender.md | git checkout <file> after mutmut apply discards all local changes; save with git stash or patch before restoring
|
|
49
|
+
2026-06-28 | 3b4f8734 | hardender | convention-gap | promoted→.agents/roles/hardender.md | always regenerate acceptance entrypoints after modifying step handlers before running gherkin-mutator
|
|
50
|
+
2026-06-28 | 3b4f8734 | hardender | convention-gap | promoted→.agents/roles/hardender.md | gherkin-mutator --workers N requires concurrent runner; runner_adapter.py is single-process; always use --workers 1
|
|
51
|
+
2026-06-28 | 3b4f8734 | hardender | convention-gap | promoted→.agents/references/equivalent-mutants.md | _cmd.run_command capture_output variants and _copy_tree follow_symlinks=None/True are equivalent mutants
|
|
52
|
+
2026-06-28 | 5707a6e5 | coder | convention-gap | promoted→.agents/roles/coder.md | merge from hardener/cleaner can silently revert API contracts; diff public signatures before running tests
|
|
53
|
+
2026-06-28 | 19ff3fa9 | QA | convention-gap | promoted→.agents/roles/QA.md | QA harness must handle CLI-rejected values (e.g. --max-workers 0) without changing CLI validator
|
|
54
|
+
2026-06-28 | 19ff3fa9 | QA | convention-gap | promoted→.agents/roles/QA.md | shell counter files in acceptance steps must use PID not $COUNT; run_parallel cleans run-PID/ not workers/ parent
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Ledger — SwarmForge Items
|
|
2
|
+
|
|
3
|
+
Work queue for swarmforge-scoped retro actions, prunable.
|
|
4
|
+
Format: `<date> | <session-id> | <role> | <failure-class> | <verdict> | <status> | <one-line summary>`
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
2026-06-25 | 9bc9e159 | architect | tool-error | promoted→ledger-swarmforge | pending | SSH/1Password signing failure: determine if swarm sessions should disable GPG signing by default
|
|
8
|
+
2026-06-25 | 9bc9e159 | architect | convention-gap | promoted→ledger-swarmforge | pending | Constitution should list canonical role names to eliminate lookup errors
|
|
9
|
+
2026-06-25 | 00466112 | cleaner | tool-error | promoted→ledger-swarmforge | pending | crap4py external install blocked by auto-mode; needs permission pre-approval or fallback rule
|
|
10
|
+
2026-06-25 | 00466112 | cleaner | tool-error | promoted→ledger-swarmforge | pending | GPG commit fallback: document -c commit.gpgsign=false workaround for 1Password failures
|
|
11
|
+
2026-06-25 | 58d11592 | integrator | missing-artifact | promoted→ledger-swarmforge | pending | gtimeout not on macOS; use gh pr checks --watch bare or install coreutils
|
|
12
|
+
2026-06-25 | e4b18370 | curator | tool-error | promoted→ledger-swarmforge | pending | gh pr create blocked by auto-mode classifier; consider adding to curator allowed commands
|
|
13
|
+
2026-06-25 | a9efd9cb | coder | convention-gap | promoted→ledger-swarmforge | pending | CLI flag names must be cross-checked against feature files before writing step handlers
|
|
14
|
+
2026-06-25 | a9efd9cb | coder | convention-gap | promoted→ledger-swarmforge | pending | Write CLI step handlers when feature mixes API+CLI scenarios
|
|
15
|
+
2026-06-25 | a9efd9cb | coder | convention-gap | promoted→ledger-swarmforge | pending | Regex step patterns capture concrete values not Gherkin placeholder names
|
|
16
|
+
2026-06-25 | ba459785 | hardender | convention-gap | promoted→ledger-swarmforge | pending | Engineering rules mutation table: exception when project IS the mutation tool
|
|
17
|
+
2026-06-25 | 4c684992 | QA | tool-error | promoted→ledger-swarmforge | pending | External tool install blocked by sandbox; add fallback-to-local-binary rule to engineering.prompt
|
|
18
|
+
2026-06-26 | 34b59cea | specifier | convention-gap | promoted→ledger-swarmforge | pending | Specifier phase 3: for faithful-port features, exhaust upstream source before grilling the user
|
|
19
|
+
2026-06-26 | 34b59cea | specifier | convention-gap | promoted→ledger-swarmforge | pending | Contradiction: grill-with-docs skill is disable-model-invocation:true but role says run it autonomously
|
|
20
|
+
2026-06-26 | 34b59cea | specifier | missing-artifact | promoted→ledger-swarmforge | pending | ir-dry-checker (specifier phase 6) not installed; reword phase or provide the tool
|
|
21
|
+
2026-06-26 | 34b59cea | specifier | tool-error | promoted→ledger-swarmforge | pending | git reset --hard blocked by auto-mode classifier in specifier startup; ready_for_next.sh should own sync
|
|
22
|
+
2026-06-26 | ae4e1d02 | cleaner | convention-gap | promoted→ledger-swarmforge | pending | uv run mutate4py is correct (not uvx); uvx isolates env and breaks self-referential scanning
|
|
23
|
+
2026-06-26 | 86d7f06f | hardender | convention-gap | promoted→ledger-swarmforge | pending | merge_and_process directive meaning not documented in hardender role; caused 2 extra tool calls
|
|
24
|
+
2026-06-26 | 86d7f06f | hardender | convention-gap | promoted→ledger-swarmforge | pending | mutmut 3.x uses --max-children, not --max-workers; role prompt used wrong flag name
|
|
25
|
+
2026-06-26 | 48c13d25 | QA | convention-gap | promoted→ledger-swarmforge | pending | git merge origin/<branch> fails for fetched branches; always use local branch name in merge commands
|
|
26
|
+
2026-06-26 | f5e87210 | architect | convention-gap | promoted→ledger-swarmforge | pending | Handoff recipient typed from memory instead of conf lookup; already in AGENTS.md but not in architect role checklist
|
|
27
|
+
2026-06-26 | f5e87210 | architect | convention-gap | promoted→ledger-swarmforge | pending | Before writing fast-check property tests, grep Object.keys(fc) to avoid unknown-arbitrary failures (fc.hexaString, fc.float 32-bit)
|
|
28
|
+
2026-06-26 | 14e97446 | specifier | missing-artifact | promoted→ledger-swarmforge | pending | ir-dry-checker (phase 6) not installed; manual prune required; not recorded so future specifiers hunt for it again
|
|
29
|
+
2026-06-26 | c53799e5 | architect | tool-error | promoted→ledger-swarmforge | pending | Fork agent stalled (600s watchdog) for architectural review; large swarm-persona context may cause fork hang on open-ended tasks
|
|
30
|
+
2026-06-26 | 416dbe9a | cleaner | convention-gap | promoted→ledger-swarmforge | pending | When CRAP/DRY tools recorded as unavailable in memory/AGENTS.md, engineering startup should allow skipping with one-line note
|
|
31
|
+
2026-06-26 | 416dbe9a | cleaner | convention-gap | promoted→ledger-swarmforge | pending | --update-manifest not yet implemented; cleaner should note manifest will be stale after src edits until a full run
|
|
32
|
+
2026-06-26 | 9fd9fe97 | integrator | convention-gap | promoted→ledger-swarmforge | pending | QA role: before handing off, run ruff check --fix && ruff format and commit if any changes; prevents integrator fix cycles
|
|
33
|
+
2026-06-26 | 9fd9fe97 | integrator | convention-gap | promoted→ledger-swarmforge | pending | Integrator: after gh pr merge, if error contains "cannot delete branch" (worktree conflict), treat as success and continue
|
|
34
|
+
2026-06-26 | 9fd9fe97 | integrator | convention-gap | promoted→ledger-swarmforge | pending | Verify both ruff check and ruff format in local verification; both are separate CI steps
|
|
35
|
+
2026-06-26 | eeab6b91 | QA | convention-gap | promoted→ledger-swarmforge | pending | QA verification: generate coverage LCOV before running crap4py (two-step: uv run coverage run then uv run coverage lcov)
|
|
36
|
+
2026-06-26 | a6cab6bf | coder | convention-gap | promoted→ledger-swarmforge | pending | Scope find to src/ or specific subtree, never project root; venv noise bloats results by 50-100x
|
|
37
|
+
2026-06-26 | 38ff0a59 | hardender | convention-gap | promoted→ledger-swarmforge | pending | After commit exit-code 128 with signing error, run git log to check if commit succeeded before retrying
|
|
38
|
+
2026-06-26 | 4d4d0ea3 | integrator | convention-gap | promoted→ledger-swarmforge | pending | gh pr view without PR number resolves to current branch (swarmforge-integrator), not the feature branch; always pass explicit PR number
|
|
39
|
+
2026-06-26 | 4d4d0ea3 | integrator | convention-gap | promoted→ledger-swarmforge | pending | gh pr comment may be blocked in auto-mode; include diagnosis inline in PR body/description as first-choice fallback
|
|
40
|
+
2026-06-26 | 61ee6b27 | integrator | convention-gap | promoted→ledger-swarmforge | pending | Integrator: run ruff check && ruff format locally before pushing to confirm all issues resolved in single commit
|
|
41
|
+
2026-06-26 | b0229ad6 | QA | missing-artifact | promoted→ledger-swarmforge | pending | QA DRY check: drywall binary download blocked by auto-mode; note SKIPPED if blocked and continue (binary may already exist at ~/.local/bin/drywall)
|
|
42
|
+
2026-06-26 | d638c7e4 | QA | convention-gap | promoted→ledger-swarmforge | pending | Stale untracked test artifacts from prior QA sessions may exist in worktree root; prefer git stash -u over rm in auto-mode
|
|
43
|
+
2026-06-26 | f585b9ac | architect | convention-gap | promoted→ledger-swarmforge | pending | Fork review prompts for src/ architectural review should include test/ property test files to catch type errors in test consumers
|
|
44
|
+
2026-06-26 | 4d4d0ea3 | integrator | convention-gap | promoted→ledger-swarmforge | pending | After gh pr create fails with "already exists", capture PR URL from error output and continue with post-create gate
|
|
45
|
+
2026-06-26 | 04c94859 | hardender | convention-gap | promoted→ledger-swarmforge | pending | Hardender: before first mutation run on a file, verify embedManifest format produces valid TS (/* */ wrapped JSON, not raw JSON)
|
|
46
|
+
2026-06-26 | 04c94859 | hardender | convention-gap | promoted→ledger-swarmforge | pending | For TS/Bun mutation: use scoped test command per file (bun test test/X.test.ts) not full bun test — 6-8x speedup
|
|
47
|
+
2026-06-26 | 52201f30 | coder | convention-gap | promoted→ledger-swarmforge | pending | Integrator handoff payload should signal "verify and forward" vs "implement" to disambiguate passthrough sessions
|
|
48
|
+
2026-06-26 | fc5d7a74 | cleaner | convention-gap | promoted→ledger-swarmforge | pending | When adding type aliases, place them after all import statements, never between import blocks
|
|
49
|
+
2026-06-26 | 0fe93f63 | coder | convention-gap | promoted→ledger-swarmforge | pending | Coder: before delegating implementation to a fork, run existing unit tests to confirm green baseline; prevents misattributing pre-existing failures
|
|
50
|
+
2026-06-26 | b79e3962 | coder | convention-gap | promoted→ledger-swarmforge | pending | When spec text and spec examples contradict, trust examples first; validate algorithm against examples before overriding a fork's working implementation
|
|
51
|
+
2026-06-26 | fc327d2f | QA | missing-artifact | promoted→ledger-swarmforge | pending | merge_and_process in PAYLOAD is not a script on PATH for non-hardender roles; all roles must infer: fetch+merge the named commit then run role-specific sequence
|
|
52
|
+
2026-06-26 | 38acb0d3 | specifier | convention-gap | promoted→ledger-swarmforge | pending | Completion-cycle git_handoffs reuse fresh-spec payload template, giving no explicit "cycle done" signal; consider a distinct completion-notification type in handoff spec
|
|
53
|
+
2026-06-28 | 8c38deb4 | architect | convention-gap | promoted→ledger-swarmforge | pending | Before moving domain functions out of a module, grep tests for direct imports of those function names; prevents post-hoc test-contract repair
|
|
54
|
+
2026-06-28 | 8c38deb4 | architect | convention-gap | promoted→ledger-swarmforge | pending | Read existing test signatures for the old function before designing new API — don't discover test contract after implementing
|
|
55
|
+
2026-06-28 | 8c38deb4 | architect | convention-gap | promoted→ledger-swarmforge | pending | Extend dependency-rule review phase to include test-import check for functions being moved before touching source file
|
|
56
|
+
2026-06-28 | c6b84c63 | architect | convention-gap | promoted→ledger-swarmforge | pending | Think before Edit: if unsure whether a change is correct, articulate why before calling Edit — edit→revert pairs waste turns
|
|
57
|
+
2026-06-28 | 4f7feec9 | QA | tool-error | promoted→ledger-swarmforge | pending | tool_result_sizes in extract.py output is a dict (keyed by tool name), not a list; retro SKILL.md Step 5 uses sizes[:5] list slice syntax — schema mismatch causes KeyError
|
|
58
|
+
2026-06-28 | 5c32a862 | specifier | convention-gap | promoted→ledger-swarmforge | pending | When request names a flag/behavior the spec marks removed/locked, frontier brief must flag it as a reopenable assumption and ask; do not plan around spec stance as settled
|
|
59
|
+
2026-06-28 | 5c32a862 | specifier | convention-gap | promoted→ledger-swarmforge | pending | When a decision reverses, grep for every assertion of the reversed fact across the whole contract (not just the named section) before claiming done
|
|
60
|
+
2026-06-28 | b52f13f5 | specifier | convention-gap | promoted→ledger-swarmforge | pending | Default to terse Q→one-line-A when user signals non-expertise or confusion; offer depth on demand; lead dense explanations only when expertise is established
|
|
61
|
+
2026-06-28 | b52f13f5 | specifier | convention-gap | promoted→ledger-swarmforge | pending | AskUserQuestion should follow shared mental model; if user answers options with new prerequisite questions, drop to prose and re-ask once rather than re-prompting same decision
|
|
62
|
+
2026-06-28 | 3814e69e | cleaner | missing-artifact | promoted→ledger-swarmforge | pending | drywall binary download blocked in auto-mode again (cleaner); pre-install drywall in worktree setup or grant permission in settings.json (duplicate pattern, escalate)
|
|
63
|
+
2026-06-28 | c8748468 | hardender | tool-error | promoted→ledger-swarmforge | pending | RTK swallows stdout when underlying process calls process.exit(1) before writing; use bare command without rtk when zero output is unexpected
|
|
64
|
+
2026-06-28 | c8748468 | hardender | convention-gap | promoted→ledger-swarmforge | pending | Before writing handoff to: field, verify role name case with ls swarmforge/roles/ — names are case-sensitive (QA not qa)
|
|
65
|
+
2026-06-28 | c8748468 | hardender | convention-gap | promoted→ledger-swarmforge | pending | Do not bun add -d <local-path> tools to package.json for analysis — install ephemerally, run tool, then revert package.json and bun.lock with git checkout --
|
|
66
|
+
2026-06-28 | 5707a6e5 | coder | convention-gap | promoted→ledger-swarmforge | pending | After merge-result handoff, diff public function signatures of touched modules against pre-merge state before running tests
|
|
67
|
+
2026-06-29 | eaa9acfe | integrator | convention-gap | promoted→ledger-swarmforge | pending | Integrator: explicit git push -u origin feat/<initiative> step must precede gh pr create; push is not implicit
|
|
68
|
+
2026-06-29 | eaa9acfe | integrator | convention-gap | promoted→ledger-swarmforge | pending | Before pushing to CI, run both ruff check --fix AND ruff format in a single pass (they are separate CI steps)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Equivalent Mutant Categories — mutate4py Project
|
|
2
|
+
|
|
3
|
+
Recognized equivalent mutant patterns for this project. Surviving mutants in these categories do NOT need new tests — they are structurally equivalent for all valid inputs.
|
|
4
|
+
|
|
5
|
+
## Categories (from hardender session da863ce7, 2026-06-26)
|
|
6
|
+
|
|
7
|
+
1. **Falsy None vs False init** — replacing `None` with `False` (or vice versa) in initialization where the code only tests truthiness; both evaluate identically.
|
|
8
|
+
|
|
9
|
+
2. **argparse `dest=None`** — `dest` in argparse derives from the flag name; `dest=None` vs `dest="<flag>"` produces the same attribute name at runtime.
|
|
10
|
+
|
|
11
|
+
3. **Help-text mutations** — mutations inside `help="..."` strings for argparse arguments; help text has no behavioral effect.
|
|
12
|
+
|
|
13
|
+
4. **Single-comma DA lines with different `maxsplit`** — `_parse_da_line` mutations on lines that have exactly one comma; split with `maxsplit=1` or without produces the same result.
|
|
14
|
+
|
|
15
|
+
5. **Compare between-text with single operator occurrence** — `_mutate_compare` mutations where the between-text region contains exactly one operator; replace-first and replace-all are equivalent.
|
|
16
|
+
|
|
17
|
+
## Additional Categories (from hardender session 3b4f8734, 2026-06-28)
|
|
18
|
+
|
|
19
|
+
6. **`_cmd.run_command` `capture_output` variants** — mutants 5, 10, 13 in `_cmd.py`; `capture_output=True/False` variants produce identical behavior for the project's test inputs.
|
|
20
|
+
|
|
21
|
+
7. **`_copy_tree` `follow_symlinks=None/True`** — mutants 13, 14; the only distinction is for symlinks-to-directories, which crash with `IsADirectoryError` on both variants in the current call sites.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# QA Role — Operational Knowledge
|
|
2
|
+
|
|
3
|
+
## Pre-Handoff Lint and Format Check
|
|
4
|
+
Before handing off, MUST run `uv run ruff check src/ tests/ && uv run ruff format --check src/ tests/`. Fix any failures before handoff. Do not hand off with lint or format violations — integrator absorbs CI fix cycles.
|
|
5
|
+
|
|
6
|
+
## QA Feature Step Wiring
|
|
7
|
+
Before marking QA done, grep `acceptance/run_acceptance.sh` for every `*_qa.feature` file present in `features/`. Confirm each has a `QA_STEPS_MAP` entry. A missing `QA_STEPS_MAP` entry causes silent `SKIP QA: no steps module for X` output — the feature is silently skipped and failures are masked.
|
|
8
|
+
|
|
9
|
+
## QA Harness: Handling CLI-Rejected Values (e.g. --max-workers 0)
|
|
10
|
+
When a QA feature passes a value that the CLI rejects (e.g., `--max-workers 0` to test serial mode), handle it in `_run_qa_cmd` — not by changing the CLI validator. Changing the CLI validator to accept test-only values breaks the cli-surface acceptance test.
|
|
11
|
+
|
|
12
|
+
## Shell Counter Files in Acceptance Steps
|
|
13
|
+
Shell scripts in acceptance steps must not use `$COUNT` from `ls dir | wc -l` as unique file names with parallel workers — it is not safe under concurrency. Use `$$` (PID) or content-based detection (grep for a token in the worker's source copy) instead.
|
|
14
|
+
|
|
15
|
+
## Worker Directory Cleanup Assertions
|
|
16
|
+
`run_parallel` cleans up `run-PID-NANOS/` (the run-specific subdirectory) but leaves the `workers/` parent directory. Assertions must check for empty run subdirs, not for the absence of `workers/`.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Cleaner Role — Operational Knowledge
|
|
2
|
+
|
|
3
|
+
## Boundary File Irreducible Minimum
|
|
4
|
+
The 15-mutation-site threshold is a trigger, not a hard gate. When all extractable testable logic is in `*_helpers.py` and remaining sites are Context class methods, subprocess calls, and guard clauses, document as "irreducible boundary minimum" and proceed. Do not loop indefinitely trying to reach 15.
|
|
5
|
+
|
|
6
|
+
## Test Error Messages Must Match New Implementation
|
|
7
|
+
When writing a test for a refactored function, verify expected error message strings match the new implementation before committing. Do not copy message strings from old code — refactored functions may use different error strings.
|
|
8
|
+
|
|
9
|
+
## Manifest "NEW" Hashes After Coder Handoff
|
|
10
|
+
When manifest entries show "NEW" hashes and stale line numbers after a coder handoff, this is expected — the mutation tool refreshes them on first scan. Do not hand-edit manifest entries; skip to cleanup work.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Coder Role — Operational Knowledge
|
|
2
|
+
|
|
3
|
+
## Dead-Code Guard After Refactor
|
|
4
|
+
After extracting a helper function from a function body, immediately delete all stale local variables, intermediate loops, and partial implementations before running tests. Do not rely on test failures (NameError, etc.) to surface dead code — it should be removed proactively as part of the refactor step.
|
|
5
|
+
|
|
6
|
+
## Acceptance Convenience Wrapper
|
|
7
|
+
Before invoking acceptance generation steps manually (`generate_acceptance.py`, `runner_adapter.py`), check for `acceptance/run_acceptance.sh` first — it is the correct entry point and handles sequencing. Calling generation scripts directly without required args fails silently or with cryptic errors.
|
|
8
|
+
|
|
9
|
+
## Merge Handoff: Verify Public API Signatures
|
|
10
|
+
After receiving a merge-result handoff (hardener or cleaner branch merged onto a feature branch), diff the public function signatures of all touched modules against their pre-merge state before running tests. A merge can silently revert API contract changes (e.g., function signature, return type); in a dynamically-typed project this manifests as a runtime TypeError, not a compile error.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Hardender Role — Operational Knowledge
|
|
2
|
+
|
|
3
|
+
## Mutation Tool for This Project
|
|
4
|
+
This project (mutate4py) is self-hosted — it generates and checks its own mutation manifests. Use `uv run mutate4py` (not `uvx mutate4py`; uvx isolates the env and breaks self-referential scanning).
|
|
5
|
+
|
|
6
|
+
Key commands:
|
|
7
|
+
- `uv run mutate4py src/ --check-manifest` — verify all manifests are current (CI gate; exits 0 if current, 1 if missing/stale)
|
|
8
|
+
- `uv run mutate4py <file> --scan` — scan a single file and print surviving mutants
|
|
9
|
+
- `uv run mutate4py <file> --update-manifest` — regenerate and embed a file's manifest
|
|
10
|
+
|
|
11
|
+
`--scan`, `--update-manifest`, and `--check-manifest` are mutually exclusive. `--scan` and `--update-manifest` accept exactly ONE file; for multi-file operations loop over files or use a directory with `--check-manifest`.
|
|
12
|
+
|
|
13
|
+
## CRAP Tool
|
|
14
|
+
crap4py is installed from local sibling `~/workspace/addi/crap4py` via `uv tool install ~/workspace/addi/crap4py`, not from PyPI or GitHub URL.
|
|
15
|
+
|
|
16
|
+
## merge_and_process Directive
|
|
17
|
+
`merge_and_process <role> <commit>` in a handoff payload is NOT a script on PATH. It means: run `git merge <commit>` in the hardender worktree, then execute the standard hardening sequence (unit → acceptance → property tests → mutation manifest check → Gherkin mutation → CRAP → DRY).
|
|
18
|
+
|
|
19
|
+
## gherkin-mutator Named Arguments
|
|
20
|
+
gherkin-mutator uses `--feature <path>` (named option), not a positional argument. Check `/tmp/aps-build/bb/src/aps/cli/gherkin_mutator.clj` source if CLI is unclear.
|
|
21
|
+
|
|
22
|
+
## Restoring Files After Manual Mutation Debugging
|
|
23
|
+
After manually editing a source file to simulate a mutant for debugging, restore with `git checkout <file>` ONLY if no other local changes exist in that file. If you have local edits (e.g. a DRY fix, refactor), first save them: `git stash` (or `git diff > patch.diff && git checkout <file> && git apply patch.diff`). `git checkout <file>` discards ALL unstaged and staged changes, not just the mutation.
|
|
24
|
+
|
|
25
|
+
## Regenerate Acceptance Entrypoints After Step Handler Changes
|
|
26
|
+
After modifying any acceptance step handler file (`*_steps.py`), regenerate the acceptance entrypoints via `gherkin-parser` + `generate_acceptance.py` BEFORE running `gherkin-mutator`. Stale generated entrypoints cause all 19+ mutations to error.
|
|
27
|
+
|
|
28
|
+
## gherkin-mutator --workers
|
|
29
|
+
`runner_adapter.py` is concurrent (ThreadPoolExecutor, default 4 workers via `RUNNER_WORKERS` env var). Use `--workers 4` with gherkin-mutator. For all features in parallel, use `acceptance/run_gherkin_mutation.sh`.
|
|
30
|
+
|
|
31
|
+
## Equivalent Mutant Categories (Python)
|
|
32
|
+
See `.agents/references/equivalent-mutants.md` for recognized equivalent mutant patterns that do not need test coverage.
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-retro
|
|
3
|
+
description: Run a conversation retrospective — analyze what happened in this session, what worked, what didn't, and propose concrete improvements. Use when the user says "retro", "retrospective", "what happened in this session", "session review", "what did we do", "analyze this conversation", or when wrapping up a long session. Especially useful after using a skill you're developing. In swarmforge: invoked automatically as the last step before each role goes idle.
|
|
4
|
+
compatibility: Primary — requires `entire` CLI (0.6.2+) for transcript extraction. Fallback — Claude Code ~/.claude/projects/ path. Python 3.8+ for the extraction script.
|
|
5
|
+
metadata:
|
|
6
|
+
author: gabadi/swarm-forge (fork of giannimassi/agent-retro)
|
|
7
|
+
version: "0.1.0"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# agent-retro
|
|
11
|
+
|
|
12
|
+
## Step 1 — Extract Session Data
|
|
13
|
+
|
|
14
|
+
**Primary path (entire):**
|
|
15
|
+
The extractor script lives next to this SKILL.md at `scripts/extract.py`. Resolve its directory portably (Claude Code sets `$CLAUDE_SKILL_DIR`; pi does not):
|
|
16
|
+
```bash
|
|
17
|
+
EXTRACT="${CLAUDE_SKILL_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)/..}/scripts/extract.py"; [ -f "$EXTRACT" ] || EXTRACT="scripts/extract.py"
|
|
18
|
+
```
|
|
19
|
+
If neither resolves, ask the operator for the path to this skill's `scripts/extract.py`.
|
|
20
|
+
|
|
21
|
+
1. Run `entire session current --json` to get the active session ID and worktree path.
|
|
22
|
+
2. Check: does `worktree_path` in the result match `$PWD`?
|
|
23
|
+
- If **NO** (stale result — wrong repo or ended session) → skip `entire session info` entirely; go to **JSONL fallback** below.
|
|
24
|
+
- If **YES** → proceed:
|
|
25
|
+
- Run `entire session info <id> --transcript > /tmp/retro-session.jsonl`
|
|
26
|
+
- Verify: `python3 "$EXTRACT" /tmp/retro-session.jsonl --metadata-only`
|
|
27
|
+
- If verification succeeds, run full extraction: `python3 "$EXTRACT" /tmp/retro-session.jsonl --summary > /tmp/retro-extract.json`
|
|
28
|
+
- Proceed to Step 2 with `/tmp/retro-extract.json`.
|
|
29
|
+
|
|
30
|
+
**JSONL fallback:**
|
|
31
|
+
Use when: `entire` is not installed, `entire session current` returns no session, or `worktree_path` does not match `$PWD`. The fallback depends on the harness — `extract.py` auto-detects the format from the first line (`{"type":"session"` → pi; otherwise Claude Code).
|
|
32
|
+
|
|
33
|
+
**Claude Code fallback:**
|
|
34
|
+
1. Find the Claude Code project dir for this worktree: `ls ~/.claude/projects/ | grep <last-segment-of-PWD>`. Note: dot-prefixed segments encode as double-dash (`.worktrees` → `--worktrees`), so do not use naive `sed` — use `grep` on the last path segment instead.
|
|
35
|
+
2. Take the most recently modified `.jsonl` in that dir: `ls -t ~/.claude/projects/<encoded-cwd>/*.jsonl | head -1`.
|
|
36
|
+
|
|
37
|
+
**pi fallback:**
|
|
38
|
+
pi stores sessions under `~/.pi/agent/sessions/<encoded-cwd>/<timestamp>_<uuid>.jsonl`. The encoding wraps the cwd with `--` and replaces every `/`, `\`, and `:` with `-` (so `/Users/gabadi/.agents-skills` → `--Users-gabadi-.agents-skills--`). Dot-prefixed segments are **single**-dashed (`.worktrees/coder` → `-worktrees-coder`), unlike Claude's double-dash — do not reuse the Claude encoding.
|
|
39
|
+
1. Encode `$PWD` the same way and locate the dir:
|
|
40
|
+
```bash
|
|
41
|
+
ENCODED="--$(echo "$PWD" | sed 's|^[/\\]||; s|[/\\:]|-|g')--"
|
|
42
|
+
ls -t ~/.pi/agent/sessions/"$ENCODED"/*.jsonl | head -1
|
|
43
|
+
```
|
|
44
|
+
If the encoded lookup misses, fall back to `ls ~/.pi/agent/sessions/ | grep "$(basename "$PWD")"` to find the right dir.
|
|
45
|
+
2. The most recently modified `.jsonl` in that dir is the current/last session.
|
|
46
|
+
|
|
47
|
+
**Then (both harnesses):**
|
|
48
|
+
3. Verify: `python3 "$EXTRACT" <path> --metadata-only`
|
|
49
|
+
4. Run full extraction: `python3 "$EXTRACT" <path> --summary > /tmp/retro-extract.json`
|
|
50
|
+
|
|
51
|
+
The pi parser produces the same schema as the Claude parser (`conversation_arc`, `tokens.total`, `tokens.estimated_cost_usd`, `tool_result_sizes`, `tools`). `tokens.total` uses the same key names (`input_tokens`, `output_tokens`, `cache_creation_input_tokens`, `cache_read_input_tokens`) mapped from pi's `usage.{input,output,cacheWrite,cacheRead}`. Cost comes from pi's own `usage.cost.total` when present.
|
|
52
|
+
|
|
53
|
+
**If no transcript is found:** Report "No session transcript found" and stop. Do not fabricate data.
|
|
54
|
+
|
|
55
|
+
Raw JSONL is 1MB+ per session — never stream transcript bytes inline into context. Always write to a temp file and pass the path to extract.py.
|
|
56
|
+
|
|
57
|
+
**Null-arc guard:** Before using the arc, check whether content is populated:
|
|
58
|
+
```bash
|
|
59
|
+
python3 -c "
|
|
60
|
+
import json
|
|
61
|
+
d = json.load(open('/tmp/retro-extract.json'))
|
|
62
|
+
arc = d.get('conversation_arc', [])
|
|
63
|
+
non_null = sum(1 for e in arc if e.get('text') or e.get('content'))
|
|
64
|
+
print(f'arc entries: {len(arc)}, non-null content: {non_null}')
|
|
65
|
+
"
|
|
66
|
+
```
|
|
67
|
+
(Both the Claude and pi parsers populate `text`; the guard checks `text` or `content` for compatibility.)
|
|
68
|
+
If `non_null == 0` and `len(arc) > 0`, `extract.py` silently failed. Fall back to **in-context reconstruction**: write the retro from live session memory — (1) what tool calls succeeded first try, (2) what failed or needed retries, (3) any user corrections or redirects, (4) token budget marked as `(unavailable — extract.py returned no cost data)`. Do not fabricate metrics.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Step 2 — Read the Conversation Arc
|
|
73
|
+
|
|
74
|
+
Read `conversation_arc` from `/tmp/retro-extract.json`. This is the full story of the session: every user message and assistant response in order.
|
|
75
|
+
|
|
76
|
+
Identify:
|
|
77
|
+
- User corrections ("no, not that", "stop", "undo", "wrong")
|
|
78
|
+
- Redirects (user changing direction mid-task)
|
|
79
|
+
- Repeated instructions (same request given more than once)
|
|
80
|
+
- Pivots (abandoned approaches)
|
|
81
|
+
- Friction moments (back-and-forth on a single point)
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Step 3 — Classify Outcomes
|
|
86
|
+
|
|
87
|
+
Classify what the session produced:
|
|
88
|
+
- New code / feature
|
|
89
|
+
- Bug fix
|
|
90
|
+
- Communication (messages, comments, docs)
|
|
91
|
+
- Setup / configuration changes
|
|
92
|
+
- Spec or design artifact
|
|
93
|
+
- Process improvement
|
|
94
|
+
- Review or analysis
|
|
95
|
+
- Research
|
|
96
|
+
- Skill development
|
|
97
|
+
|
|
98
|
+
A session may have multiple outcomes.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Step 4 — Analyze What Worked
|
|
103
|
+
|
|
104
|
+
Identify:
|
|
105
|
+
- First-try successes (task completed without corrections)
|
|
106
|
+
- Efficient delegation (agents dispatched with clear scope)
|
|
107
|
+
- Good skill matches (right skill for the task)
|
|
108
|
+
- Clean conversation flow (no redirects)
|
|
109
|
+
- Smart tool choice (right tool, right scope)
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Step 5 — Analyze What Didn't Work
|
|
114
|
+
|
|
115
|
+
Identify friction patterns:
|
|
116
|
+
- User corrections, redirects, repetitions, stops, frustration signals
|
|
117
|
+
- Wasted agent dispatches (dispatched but result unused)
|
|
118
|
+
- Oversized tool results (large reads never referenced)
|
|
119
|
+
- Tool call retries (same tool called multiple times for the same target)
|
|
120
|
+
- Abandoned approaches (started, then discarded)
|
|
121
|
+
- Over-engineering (more than the task required)
|
|
122
|
+
- Under-specification (task started with insufficient context)
|
|
123
|
+
|
|
124
|
+
For skill-development retros: read the active SKILL.md (the `${CLAUDE_SKILL_DIR}/SKILL.md` of the skill being developed, or this skill's own `SKILL.md` resolved as above) and identify which instruction caused each friction.
|
|
125
|
+
|
|
126
|
+
Read `tool_result_sizes` from the extract — flag any tool result over 50KB that was followed by no further reference to that file.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Step 6 — Propose Actions
|
|
131
|
+
|
|
132
|
+
Lead with the defense-first question: **"What defensive rule did this session's work absorb that future maintainers must keep intact?"** Answer it before cataloging friction — rule-shaped learnings surface before cause-shaped ones.
|
|
133
|
+
|
|
134
|
+
Capture-first guard: enumerate every candidate learning from Steps 4–5 in full before writing anything to the retro file. Do not filter for "obviousness" or "self-correcting" here — capture everything; the curation stage downstream owns discards.
|
|
135
|
+
|
|
136
|
+
For each friction pattern, propose one of these action types:
|
|
137
|
+
- `skill-update` — change an existing skill. Include before/after text.
|
|
138
|
+
- `skill-create` — create a new skill.
|
|
139
|
+
- `rule-update` — change a rule or instruction in CLAUDE.md or a role prompt.
|
|
140
|
+
- `rule-create` — create a new rule.
|
|
141
|
+
- `setup-change` — change a configuration or environment setting.
|
|
142
|
+
- `memory-update` — update or create a memory entry.
|
|
143
|
+
- `investigate` — flag something for human review (uncertain root cause).
|
|
144
|
+
- `acknowledge` — nothing to change; note what worked well.
|
|
145
|
+
|
|
146
|
+
Be specific. "Improve X" is not a proposal. "Change the wording in Step 3 from Y to Z" is a proposal.
|
|
147
|
+
|
|
148
|
+
**Scope** — tag every proposed action with exactly one scope value:
|
|
149
|
+
- `project` — knowledge about the target project (its code, config, tools, conventions).
|
|
150
|
+
- `swarmforge` — knowledge about the harness itself (role prompts, constitution, scripts, pipeline mechanics).
|
|
151
|
+
- `skill` — a reusable procedure that should become or amend a skill.
|
|
152
|
+
- `ephemeral` — true one-offs; recorded for audit, never promoted.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Step 7 — Write the Retro File
|
|
157
|
+
|
|
158
|
+
Write to `~/.claude/worklog/retros/YYYY-MM-DD-<slug>.md` where `<slug>` is a 3–5 word kebab-case summary of the session.
|
|
159
|
+
|
|
160
|
+
Structure:
|
|
161
|
+
```markdown
|
|
162
|
+
# Session Retro: <slug>
|
|
163
|
+
Date: YYYY-MM-DD
|
|
164
|
+
Session ID: <id>
|
|
165
|
+
Role: <swarmforge role name, or "interactive" outside a swarm>
|
|
166
|
+
Branch: <branch>
|
|
167
|
+
Duration: <N>m
|
|
168
|
+
Cost: $<N>
|
|
169
|
+
|
|
170
|
+
## Token Budget
|
|
171
|
+
| Category | Tokens | Cost |
|
|
172
|
+
|---|---|---|
|
|
173
|
+
| Input | N | $N |
|
|
174
|
+
| Output | N | $N |
|
|
175
|
+
| Cache create | N | $N |
|
|
176
|
+
| Cache read | N | $N |
|
|
177
|
+
| **Total** | **N** | **$N** |
|
|
178
|
+
|
|
179
|
+
## Tool Result Waste
|
|
180
|
+
<table of oversized unused tool results, or "None detected">
|
|
181
|
+
|
|
182
|
+
## What Worked
|
|
183
|
+
<bullet list>
|
|
184
|
+
|
|
185
|
+
## What Didn't Work
|
|
186
|
+
<bullet list with root cause per item>
|
|
187
|
+
|
|
188
|
+
## Actions
|
|
189
|
+
| # | Type | Scope | Description | Target |
|
|
190
|
+
|---|------|-------|-------------|--------|
|
|
191
|
+
| 1 | skill-update | project | ... | ... |
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Step 8 — Walk Through Actions
|
|
197
|
+
|
|
198
|
+
Determine the mode:
|
|
199
|
+
|
|
200
|
+
**Interactive session (a human is present):**
|
|
201
|
+
- Present the retro file path and summary counts (N worked, N didn't work, N actions).
|
|
202
|
+
- Walk through each proposed action one by one: show type, scope, description, target. Ask: "Apply? [y/n/defer]". Apply approved actions immediately; mark deferred/skipped in the table.
|
|
203
|
+
- After the walkthrough, show the final action table with statuses.
|
|
204
|
+
|
|
205
|
+
**Autonomous session (swarmforge role, no human in the loop):**
|
|
206
|
+
- Do not ask anything. Do not apply any action.
|
|
207
|
+
- Mark every action's status as `pending-curation` in the table and finish the retro file.
|
|
208
|
+
- The curator role consumes the file downstream; your only job is complete, well-tagged capture.
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Step 9 — Preemptive Handoff Recommendation
|
|
213
|
+
|
|
214
|
+
Check `session` metadata from the extract:
|
|
215
|
+
- If `turn_count` > 500, `duration_seconds` > 14400 (4h), or `estimated_cost_usd` > 300:
|
|
216
|
+
- Add a `investigate` action: "Session size threshold reached — consider handoff"
|
|
217
|
+
- Include two ready-to-paste prompts:
|
|
218
|
+
- For `/compact`: "Continue from: <brief state summary>"
|
|
219
|
+
- For `/clear`: "Resume from: <brief state summary> — key context: <3 bullet points>"
|