Spec copy: CarryToken is a method, matching what shipped
2 files changed,
+5
−2
.superpowers/sdd/2026-08-23-idear/progress.md+3 −0docs/superpowers/specs/2026-08-23-idear-design.md+2 −2
diff --git a/.superpowers/sdd/2026-08-23-idear/progress.md b/.superpowers/sdd/2026-08-23-idear/progress.md| index 05abd60..2bb4d3e 100644 |
| --- a/.superpowers/sdd/2026-08-23-idear/progress.md |
| +++ b/.superpowers/sdd/2026-08-23-idear/progress.md |
| @@ -77,3 +77,6 @@ Task 3: fix round 1/5 (7 addressed, 0 open; commits efd00f8..5707e39) |
| Task 3: minor (deferred): classErr's comparability is safe only while every `class` field holds a comparable error type — true as shipped (all are errors.New results), unenforced by the compiler. Worth a doc note or compile-time guard if the taxonomy grows. Final review to triage. |
| Task 3: complete (commits 98288b1..5707e39, review clean) |
| Task 4: dispatched (sonnet), BASE 5707e39 — middleware + the two identity adapters |
| +Task 4: implemented DONE (7fc0ee0). Controller re-verified: suite green, -race green. |
| +Task 4: Ruling (spec/brief conflict on CarryToken): the METHOD form stands, against the spec's literal `idear.CarryToken(...)` package-function snippet. Three reasons: the spec snippet is internally inconsistent (the same section binds `r` to the roster), the method needs Config.Logger to report a form-parse failure and a package function cannot reach it, and Task 5 mounts whatever the plan's Interfaces block names. idear's copy of the spec corrected so the record matches what shipped; rastrillo's merged copy carries the same typo and is not worth a PR on its own — SKILL.md is what users read. Cost if wrong: a one-line signature change and one mount site. |
| +Task 4: fix round 0 — none needed yet; reviewer dispatched. |
diff --git a/docs/superpowers/specs/2026-08-23-idear-design.md b/docs/superpowers/specs/2026-08-23-idear-design.md| index 9adc1d3..2562726 100644 |
| --- a/docs/superpowers/specs/2026-08-23-idear-design.md |
| +++ b/docs/superpowers/specs/2026-08-23-idear-design.md |
| @@ -260,10 +260,10 @@ receives no `*http.Request`, so the token cannot be read from the form |
| inside it. It does receive `r.Context()`. So idear supplies a middleware: |
| ```go |
| -r.Post("/signup", idear.CarryToken(ph.Signup)) |
| +r.Post("/signup", roster.CarryToken(ph.Signup)) |
| ``` |
| -`CarryToken` reads the `invite` field from the posted form and stashes it |
| +`CarryToken` is a **method on the Roster** (it logs a form-parse failure through `Config.Logger`, which a package function could not reach). It reads the `invite` field from the posted form and stashes it |
| in the request context; `Admitting` reads it back. Mounting it is |
| **mandatory** on the password path — without it every invited signup is |
| refused, which is loud and safe rather than quiet and permissive. |