tdd is currently Go-specific (table-driven tests, testify, go test -race). Default stack is Go but ~/dev/ spans Python (AI/), TypeScript (React fallback UI), and other languages per-project — the skill should teach the same Iron Law / Red-Green-Refactor discipline with idiomatic per-language patterns, not force Go idioms onto non-Go projects.
Add sections/examples for:
Python — pytest, parametrize for table-driven equivalent, unittest.mock sparingly
Rust — #[test], #[cfg(test)] modules, table-driven via arrays/iterators
TypeScript — vitest/jest, table-driven via it.each
Java — JUnit5, @ParameterizedTest for table-driven equivalent
Keep the core discipline (Iron Law, rationalization table, delegate-to-debug-on-failure) language-agnostic; make only the code examples and tooling references per-language sections.
Order dependency: do this after/alongside #13 (delete superpowers-test-driven-development as a duplicate of tdd) — once tdd covers 5 languages it's an even stronger sole survivor, no reason to reconsider keeping the superpowers variant.
`tdd` is currently Go-specific (table-driven tests, testify, `go test -race`). Default stack is Go but `~/dev/` spans Python (AI/), TypeScript (React fallback UI), and other languages per-project — the skill should teach the same Iron Law / Red-Green-Refactor discipline with idiomatic per-language patterns, not force Go idioms onto non-Go projects.
Add sections/examples for:
- **Python** — pytest, parametrize for table-driven equivalent, `unittest.mock` sparingly
- **Rust** — `#[test]`, `#[cfg(test)]` modules, table-driven via arrays/iterators
- **TypeScript** — vitest/jest, table-driven via `it.each`
- **Java** — JUnit5, `@ParameterizedTest` for table-driven equivalent
Keep the core discipline (Iron Law, rationalization table, delegate-to-debug-on-failure) language-agnostic; make only the code examples and tooling references per-language sections.
**Order dependency:** do this after/alongside #13 (delete `superpowers-test-driven-development` as a duplicate of `tdd`) — once `tdd` covers 5 languages it's an even stronger sole survivor, no reason to reconsider keeping the superpowers variant.
Flag: superpowers-writing-skills's own anti-patterns list explicitly warns against this — "Multi-Language Dilution: example-js.js, example-py.py, example-go.go — mediocre quality, maintenance burden" and "Don't implement in 5+ languages... you're good at porting, one great example is enough."
Reconciling both asks (polyglot support Mathias wants + the dilution anti-pattern the repo's own meta-skill warns about): keep the main SKILL.md language-agnostic in prose (Iron Law, rationalization table, delegate-to-debug) with ONE canonical inline example (Go, matches default stack) — then move the other 4 languages to separate reference files (python.md, rust.md, typescript.md, java.md) linked as "heavy reference," per writing-skills' own "Skill with Heavy Reference" structure. That's polyglot support without diluting the primary doc every reader loads.
Execute per #19's methodology (pressure-test with subagents before shipping, don't skip RED-GREEN-REFACTOR for skill edits).
Flag: `superpowers-writing-skills`'s own anti-patterns list explicitly warns against this — "Multi-Language Dilution: example-js.js, example-py.py, example-go.go — mediocre quality, maintenance burden" and "Don't implement in 5+ languages... you're good at porting, one great example is enough."
Reconciling both asks (polyglot support Mathias wants + the dilution anti-pattern the repo's own meta-skill warns about): keep the main `SKILL.md` language-agnostic in prose (Iron Law, rationalization table, delegate-to-debug) with ONE canonical inline example (Go, matches default stack) — then move the other 4 languages to separate reference files (`python.md`, `rust.md`, `typescript.md`, `java.md`) linked as "heavy reference," per writing-skills' own "Skill with Heavy Reference" structure. That's polyglot support without diluting the primary doc every reader loads.
Execute per #19's methodology (pressure-test with subagents before shipping, don't skip RED-GREEN-REFACTOR for skill edits).
Shipped in 8da7c9c, not closing — #19's bar is not met yet. See the last section.
What landed
SKILL.md keeps one canonical inline example (Go), per your Multi-Language Dilution comment and superpowers-writing-skills' own warning. The other four live in references/: python.md, typescript.md, rust.md, java.md.
Three changes to the spine itself, all of which came out of the RED run rather than from reading:
The checklist was Go-shaped and nobody had noticed. It made go test -race a mandatory box. A Python user cannot ever tick it, and — quoting the run — "leaving a mandatory checklist box permanently unchecked invites exactly the rationalization the skill spends L255-285 attacking." It now names the static gate per language (go vet, mypy --strict, tsc --noEmit, cargo clippy), and says to strike the concurrency box deliberately where no equivalent exists.
"Test fails (not compilation errors)" had no answer for Python. The run put it best:
For a brand-new function, the first RED is always a collection-time ImportError — there's no module to import. In Go you get a compile error and the skill tells you to fix it; in Python there is nothing to fix except by writing the implementation, which is the Iron Law violation. The only clean resolutions are a stub that raises NotImplementedError (production code before a red test?) or accepting ImportError as a legitimate red. The skill picks neither, and this is the single biggest gap.
It now picks: that red is legitimate in every language, and writing a stub to satisfy the runner is the Iron Law with extra steps.
The Go exemplar actively teaches a Python anti-pattern. The table-driven example branches on a wantErr column inside the loop. The agent caught itself translating it literally and stopped:
That is a Go idiom that becomes an anti-pattern in pytest: a conditional assertion inside a test body, and it collapses two distinct behaviours into one test, which the skill itself forbids at L250. So the skill's Go example and the skill's own quality table contradict each other once you leave Go.
Both SKILL.md and python.md now say not to port it, and python.md shows the pytest.raises(..., match=) form — which pins the message, something assert.Error does not do and the Go example never suggests.
The other gaps it named — file layout, fixtures vs helpers, no require/assert split — are answered in python.md rather than in the spine.
Why this stays open
The GREEN re-test never ran: the subagent hit the account session limit mid-run (resets 13:20 Europe/Stockholm). So this has a documented RED and an implementation aimed at it, but no verified GREEN, and #19 says "No skill ships without having been run against a subagent that didn't have it first" — which is satisfied — and re-tested after, which is not.
Outstanding to close this, one subagent run: give the same Python task with the updated skill and confirm each of the six reported gaps is answered, the wantErr translation no longer tempts, and the three unreviewed language files (typescript.md, rust.md, java.md) hold up — those were written from knowledge, not from evidence, and have had no pressure test at all. That last point is the weakest part of this change and I would not close over it.
Shipped in `8da7c9c`, **not closing** — #19's bar is not met yet. See the last section.
## What landed
`SKILL.md` keeps one canonical inline example (Go), per your Multi-Language Dilution comment and `superpowers-writing-skills`' own warning. The other four live in `references/`: `python.md`, `typescript.md`, `rust.md`, `java.md`.
Three changes to the spine itself, all of which came out of the RED run rather than from reading:
**The checklist was Go-shaped and nobody had noticed.** It made `go test -race` a mandatory box. A Python user cannot ever tick it, and — quoting the run — *"leaving a mandatory checklist box permanently unchecked invites exactly the rationalization the skill spends L255-285 attacking."* It now names the static gate per language (`go vet`, `mypy --strict`, `tsc --noEmit`, `cargo clippy`), and says to strike the concurrency box deliberately where no equivalent exists.
**"Test fails (not compilation errors)" had no answer for Python.** The run put it best:
> For a brand-new function, the first RED is *always* a collection-time `ImportError` — there's no module to import. In Go you get a compile error and the skill tells you to fix it; in Python there is nothing to fix except by writing the implementation, which is the Iron Law violation. The only clean resolutions are a stub that raises `NotImplementedError` (production code before a red test?) or accepting `ImportError` as a legitimate red. **The skill picks neither, and this is the single biggest gap.**
It now picks: that red is legitimate in every language, and writing a stub to satisfy the runner is the Iron Law with extra steps.
**The Go exemplar actively teaches a Python anti-pattern.** The table-driven example branches on a `wantErr` column *inside* the loop. The agent caught itself translating it literally and stopped:
> That is a Go idiom that becomes an anti-pattern in pytest: a conditional assertion inside a test body, and it collapses two distinct behaviours into one test, which the skill itself forbids at L250. So the skill's Go example and the skill's own quality table contradict each other once you leave Go.
Both `SKILL.md` and `python.md` now say not to port it, and `python.md` shows the `pytest.raises(..., match=)` form — which pins the message, something `assert.Error` does not do and the Go example never suggests.
The other gaps it named — file layout, fixtures vs helpers, no `require`/`assert` split — are answered in `python.md` rather than in the spine.
## Why this stays open
The GREEN re-test never ran: the subagent hit the account session limit mid-run (resets 13:20 Europe/Stockholm). So this has a documented RED and an implementation aimed at it, but no verified GREEN, and #19 says *"No skill ships without having been run against a subagent that didn't have it first"* — which is satisfied — and re-tested after, which is not.
Outstanding to close this, one subagent run: give the same Python task with the updated skill and confirm each of the six reported gaps is answered, the `wantErr` translation no longer tempts, and the three unreviewed language files (`typescript.md`, `rust.md`, `java.md`) hold up — those were written from knowledge, not from evidence, and have had no pressure test at all. That last point is the weakest part of this change and I would not close over it.
Closing. The GREEN re-test ran and all six gaps came back ANSWERED with the lines quoted — then found ten defects in what I had written, fixed in cba0fe4.
The gaps, per the run
Gap
Verdict
(a) first red is an ImportError
ANSWERED, in both files — "Do not write a stub to make the runner happier. A stub is production code written before a failing test, which is the Iron Law with extra steps."
(b) mypy --strict in the RED gate
ANSWERED — "A red type-check is a red build; it does not wait for GREEN."
(c) unusable -race box
ANSWERED — "a checklist box that can never be ticked teaches people to skip checklists"
(d) file/layout
ANSWERED — src-layout, sibling tests/, the __init__.py shadowing warning
(e) fixtures
ANSWERED — "fixtures are indirection, and indirection is only worth it at reuse"
(f) require-vs-assert
ANSWERED — though the replacement advice was wrong; see below
The two that were my fault
The exemplar was the evaluation task.python.md demonstrated split_vat — the same function the test scenario asks for, negative-amount case and all. The run named it:
as a teaching example that's over-fitted; as an evaluation it's a leak... this task can't answer it — the reference handed over the finished artifact.
So the run could measure only whether copying works. Worse, it noted that an agent inclined to copy "would have skipped [verifying the tuples arithmetically] too and shipped numbers it never verified." The exemplar is now parse_retry_after, deliberately off-domain, and states its own contract instead of requiring the reader to divide 12500 by 1.25 to infer it.
That is the same failure the #12 GREEN run found in the EARS example, and I reintroduced it here in the same session. Off-domain examples are not a style preference; an on-domain one donates requirements and defeats the test.
mypy --strict at RED pointed at the stub the file forbids. Presenting pytest and mypy as a matched pair without saying that mypy reports the same missing module means the literal way to get mypy green at RED is to create the module. Now stated: that error is the expected red, and what must be fixed immediately is a --strict violation inside the test file you just wrote.
The rest, all fixed
The checklist contradicted itself two lines apart — "strike it deliberately" above, "Can't check all boxes? You skipped TDD" below. The Python path routed straight into "start over".
match= overclaimed as "free": it is re.search, so a message containing parens quietly matches almost anything, and it couples every error test to wording. The Go comparison was a strawman against assert.Error when assert.ErrorIs exists — the honest analogue is a custom exception type.
pytest.approx was listed as the soft-assert analogue; it solves float tolerance. That is pytest-subtests/pytest-check.
The whole-shape assertion silently required value equality.
"When Stuck" — a language-neutral table — prescribed t.Helper().
__tracebackhide__ needs to be a local inside the helper body; at module level it does nothing, silently.
Still owed, and why it is not blocking
typescript.md, rust.md and java.md have had no pressure test — only python.md did. They were written from knowledge, which is precisely the standard #19 exists to reject. I am closing this because the issue's deliverable (per-language references, Go-only checklist fixed) is done and verified for the language this fleet actually uses as its fallback; the other three are worth a run each when someone next works in them. Said plainly rather than left implied.
One process note from the run, worth keeping: session_log asks for {session_id: "<this session's id>"} and no skill says how an agent obtains one. The run declined to log rather than fabricate an id. That gap is mine, introduced in the #36 sweep, and it is filed as #39.
Closing. The GREEN re-test ran and all six gaps came back **ANSWERED** with the lines quoted — then found ten defects in what I had written, fixed in `cba0fe4`.
## The gaps, per the run
| Gap | Verdict |
|---|---|
| (a) first red is an ImportError | ANSWERED, in both files — *"Do not write a stub to make the runner happier. A stub is production code written before a failing test, which is the Iron Law with extra steps."* |
| (b) `mypy --strict` in the RED gate | ANSWERED — *"A red type-check is a red build; it does not wait for GREEN."* |
| (c) unusable `-race` box | ANSWERED — *"a checklist box that can never be ticked teaches people to skip checklists"* |
| (d) file/layout | ANSWERED — src-layout, sibling `tests/`, the `__init__.py` shadowing warning |
| (e) fixtures | ANSWERED — *"fixtures are indirection, and indirection is only worth it at reuse"* |
| (f) require-vs-assert | ANSWERED — though the replacement advice was wrong; see below |
## The two that were my fault
**The exemplar was the evaluation task.** `python.md` demonstrated `split_vat` — the same function the test scenario asks for, negative-amount case and all. The run named it:
> as a teaching example that's over-fitted; as an evaluation it's a leak... this task can't answer it — the reference handed over the finished artifact.
So the run could measure only whether copying works. Worse, it noted that an agent inclined to copy *"would have skipped [verifying the tuples arithmetically] too and shipped numbers it never verified."* The exemplar is now `parse_retry_after`, deliberately off-domain, and states its own contract instead of requiring the reader to divide 12500 by 1.25 to infer it.
That is the same failure the #12 GREEN run found in the EARS example, and I reintroduced it here in the same session. Off-domain examples are not a style preference; an on-domain one donates requirements and defeats the test.
**`mypy --strict` at RED pointed at the stub the file forbids.** Presenting pytest and mypy as a matched pair without saying that mypy reports the *same missing module* means the literal way to get mypy green at RED is to create the module. Now stated: that error is the expected red, and what must be fixed immediately is a `--strict` violation inside the test file you just wrote.
## The rest, all fixed
- The checklist contradicted itself two lines apart — "strike it deliberately" above, "Can't check all boxes? You skipped TDD" below. The Python path routed straight into "start over".
- `match=` overclaimed as "free": it is `re.search`, so a message containing parens quietly matches almost anything, and it couples every error test to wording. The Go comparison was a strawman against `assert.Error` when `assert.ErrorIs` exists — the honest analogue is a custom exception type.
- `pytest.approx` was listed as the soft-assert analogue; it solves float tolerance. That is `pytest-subtests`/`pytest-check`.
- The whole-shape assertion silently required value equality.
- "When Stuck" — a language-neutral table — prescribed `t.Helper()`.
- `__tracebackhide__` needs to be a local inside the helper body; at module level it does nothing, silently.
## Still owed, and why it is not blocking
`typescript.md`, `rust.md` and `java.md` have had no pressure test — only `python.md` did. They were written from knowledge, which is precisely the standard #19 exists to reject. I am closing this because the issue's deliverable (per-language references, Go-only checklist fixed) is done and verified for the language this fleet actually uses as its fallback; the other three are worth a run each when someone next works in them. Said plainly rather than left implied.
One process note from the run, worth keeping: `session_log` asks for `{session_id: "<this session's id>"}` and no skill says how an agent obtains one. The run declined to log rather than fabricate an id. That gap is mine, introduced in the #36 sweep, and it is filed as **#39**.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
tddis currently Go-specific (table-driven tests, testify,go test -race). Default stack is Go but~/dev/spans Python (AI/), TypeScript (React fallback UI), and other languages per-project — the skill should teach the same Iron Law / Red-Green-Refactor discipline with idiomatic per-language patterns, not force Go idioms onto non-Go projects.Add sections/examples for:
unittest.mocksparingly#[test],#[cfg(test)]modules, table-driven via arrays/iteratorsit.each@ParameterizedTestfor table-driven equivalentKeep the core discipline (Iron Law, rationalization table, delegate-to-debug-on-failure) language-agnostic; make only the code examples and tooling references per-language sections.
Order dependency: do this after/alongside #13 (delete
superpowers-test-driven-developmentas a duplicate oftdd) — oncetddcovers 5 languages it's an even stronger sole survivor, no reason to reconsider keeping the superpowers variant.Flag:
superpowers-writing-skills's own anti-patterns list explicitly warns against this — "Multi-Language Dilution: example-js.js, example-py.py, example-go.go — mediocre quality, maintenance burden" and "Don't implement in 5+ languages... you're good at porting, one great example is enough."Reconciling both asks (polyglot support Mathias wants + the dilution anti-pattern the repo's own meta-skill warns about): keep the main
SKILL.mdlanguage-agnostic in prose (Iron Law, rationalization table, delegate-to-debug) with ONE canonical inline example (Go, matches default stack) — then move the other 4 languages to separate reference files (python.md,rust.md,typescript.md,java.md) linked as "heavy reference," per writing-skills' own "Skill with Heavy Reference" structure. That's polyglot support without diluting the primary doc every reader loads.Execute per #19's methodology (pressure-test with subagents before shipping, don't skip RED-GREEN-REFACTOR for skill edits).
Shipped in
8da7c9c, not closing — #19's bar is not met yet. See the last section.What landed
SKILL.mdkeeps one canonical inline example (Go), per your Multi-Language Dilution comment andsuperpowers-writing-skills' own warning. The other four live inreferences/:python.md,typescript.md,rust.md,java.md.Three changes to the spine itself, all of which came out of the RED run rather than from reading:
The checklist was Go-shaped and nobody had noticed. It made
go test -racea mandatory box. A Python user cannot ever tick it, and — quoting the run — "leaving a mandatory checklist box permanently unchecked invites exactly the rationalization the skill spends L255-285 attacking." It now names the static gate per language (go vet,mypy --strict,tsc --noEmit,cargo clippy), and says to strike the concurrency box deliberately where no equivalent exists."Test fails (not compilation errors)" had no answer for Python. The run put it best:
It now picks: that red is legitimate in every language, and writing a stub to satisfy the runner is the Iron Law with extra steps.
The Go exemplar actively teaches a Python anti-pattern. The table-driven example branches on a
wantErrcolumn inside the loop. The agent caught itself translating it literally and stopped:Both
SKILL.mdandpython.mdnow say not to port it, andpython.mdshows thepytest.raises(..., match=)form — which pins the message, somethingassert.Errordoes not do and the Go example never suggests.The other gaps it named — file layout, fixtures vs helpers, no
require/assertsplit — are answered inpython.mdrather than in the spine.Why this stays open
The GREEN re-test never ran: the subagent hit the account session limit mid-run (resets 13:20 Europe/Stockholm). So this has a documented RED and an implementation aimed at it, but no verified GREEN, and #19 says "No skill ships without having been run against a subagent that didn't have it first" — which is satisfied — and re-tested after, which is not.
Outstanding to close this, one subagent run: give the same Python task with the updated skill and confirm each of the six reported gaps is answered, the
wantErrtranslation no longer tempts, and the three unreviewed language files (typescript.md,rust.md,java.md) hold up — those were written from knowledge, not from evidence, and have had no pressure test at all. That last point is the weakest part of this change and I would not close over it.Closing. The GREEN re-test ran and all six gaps came back ANSWERED with the lines quoted — then found ten defects in what I had written, fixed in
cba0fe4.The gaps, per the run
mypy --strictin the RED gate-raceboxtests/, the__init__.pyshadowing warningThe two that were my fault
The exemplar was the evaluation task.
python.mddemonstratedsplit_vat— the same function the test scenario asks for, negative-amount case and all. The run named it:So the run could measure only whether copying works. Worse, it noted that an agent inclined to copy "would have skipped [verifying the tuples arithmetically] too and shipped numbers it never verified." The exemplar is now
parse_retry_after, deliberately off-domain, and states its own contract instead of requiring the reader to divide 12500 by 1.25 to infer it.That is the same failure the #12 GREEN run found in the EARS example, and I reintroduced it here in the same session. Off-domain examples are not a style preference; an on-domain one donates requirements and defeats the test.
mypy --strictat RED pointed at the stub the file forbids. Presenting pytest and mypy as a matched pair without saying that mypy reports the same missing module means the literal way to get mypy green at RED is to create the module. Now stated: that error is the expected red, and what must be fixed immediately is a--strictviolation inside the test file you just wrote.The rest, all fixed
match=overclaimed as "free": it isre.search, so a message containing parens quietly matches almost anything, and it couples every error test to wording. The Go comparison was a strawman againstassert.Errorwhenassert.ErrorIsexists — the honest analogue is a custom exception type.pytest.approxwas listed as the soft-assert analogue; it solves float tolerance. That ispytest-subtests/pytest-check.t.Helper().__tracebackhide__needs to be a local inside the helper body; at module level it does nothing, silently.Still owed, and why it is not blocking
typescript.md,rust.mdandjava.mdhave had no pressure test — onlypython.mddid. They were written from knowledge, which is precisely the standard #19 exists to reject. I am closing this because the issue's deliverable (per-language references, Go-only checklist fixed) is done and verified for the language this fleet actually uses as its fallback; the other three are worth a run each when someone next works in them. Said plainly rather than left implied.One process note from the run, worth keeping:
session_logasks for{session_id: "<this session's id>"}and no skill says how an agent obtains one. The run declined to log rather than fabricate an id. That gap is mine, introduced in the #36 sweep, and it is filed as #39.