rastrillo / idear Public

Update SKILL.md section references after renumbering

The document sections were renumbered: old §7 (EmailForSubject/token reconciliation) is now §5, and old §8 (Owner break-glass/rebinding) is now §6. Update all text references in comments, log messages, and documentation to point at the correct sections.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Paul Campbell pushed by paul@keymail.dev 26e950d255652d432826a113868cdcff2304b80a parent 0dac40c
3 files changed, +13 −13
  • docs/superpowers/specs/2026-08-23-idear-design.md +3 −3
  • example/app_test.go +8 −8
  • handlers_test.go +2 −2
diff --git a/docs/superpowers/specs/2026-08-23-idear-design.md b/docs/superpowers/specs/2026-08-23-idear-design.md
index 3d8ddec..9bbfb2f 100644
--- a/docs/superpowers/specs/2026-08-23-idear-design.md
+++ b/docs/superpowers/specs/2026-08-23-idear-design.md
@@ -52,7 +52,7 @@ So idear ships as its own module, versioned separately, and the
dependency arrow points one way: **idear imports rastrillo; rastrillo
never imports idear.** Inside this repo the change is a documentation
page, its nav entry, a pointer in `SKILL.md`, and one small seam in
-`password` that §5 forces and §8 pays for.
+`password` that §5 forces and §6 pays for.
### The tenancy ruling survives intact
@@ -321,7 +321,7 @@ password the Subject is an opaque user id, so the implementation matched
nothing and the code comment's claim of parity with admission was false.
`Config.EmailForSubject` is the optional hook that lets the app resolve its
own id, and with it set the match is made; left nil, reconciliation under
-password trusts possession of the token alone, which SKILL.md §3 and §7 now
+password trusts possession of the token alone, which SKILL.md §3 and §5 now
say in as many words.
Both public routes are rate-limited; `GET` is an unauthenticated lookup
@@ -345,7 +345,7 @@ over, because a reader will otherwise assume the guarantee is uniform:
their address is already registered — which is simply false. This design
therefore adds `password.ErrRefused` to the **core** package: `Signup`
checks `errors.Is(err, password.ErrRefused)` and renders the refusal's
-own message at 403. That makes §8 more than the three files the first
+own message at 403. That makes §6 more than the three files the first
draft promised, and the seam is worth it — anything gating signup needs
it.
diff --git a/example/app_test.go b/example/app_test.go
index 7c7d703..e9cf729 100644
--- a/example/app_test.go
+++ b/example/app_test.go
@@ -573,16 +573,16 @@ func TestInvitedSignupSurvivesAValidationFailure(t *testing.T) {
}
// ---------------------------------------------------------------
-// SKILL.md §8 break-glass: rebinding a subject.
+// SKILL.md §6 break-glass: rebinding a subject.
// ---------------------------------------------------------------
// TestBreakGlassRebindsASubject executes the rebind block from
-// SKILL.md §8 — READ OUT OF THE FILE, not restated here — against a
+// SKILL.md §6 — READ OUT OF THE FILE, not restated here — against a
// database built by this app's own migrations, and then proves the
// result end to end: sign in over real HTTP as the new subject and
// perform an Owner-only action with it.
//
-// Documented recovery SQL that nobody has run is a guess. §8's other
+// Documented recovery SQL that nobody has run is a guess. §6's other
// block, the ownership transfer, was verified this way and the review
// found `deactivated_at = NULL` in it load-bearing; this one carries
// the same clause for the same reason, plus the unique index on
@@ -590,7 +590,7 @@ func TestInvitedSignupSurvivesAValidationFailure(t *testing.T) {
//
// Reading the SQL from the document rather than copying it here is the
// point of the test. A copy can go stale silently; this cannot — edit
-// §8's block into something that does not work and this test is what
+// §6's block into something that does not work and this test is what
// says so.
func TestBreakGlassRebindsASubject(t *testing.T) {
ta := newTestApp(t)
@@ -665,7 +665,7 @@ func TestBreakGlassRebindsASubject(t *testing.T) {
}
}
-// TestBreakGlassRebindClearsDeactivation is the OTHER half of the §8
+// TestBreakGlassRebindClearsDeactivation is the OTHER half of the §6
// rebind, and it is why `deactivated_at = NULL` is in that statement.
//
// The realistic shape: somebody was offboarded (correctly — §7 says
@@ -718,7 +718,7 @@ func TestBreakGlassRebindClearsDeactivation(t *testing.T) {
}
}
-// breakGlassRebind returns SKILL.md §8's rebind block with its
+// breakGlassRebind returns SKILL.md §6's rebind block with its
// placeholders replaced. The block is located by a placeholder rather
// than by a heading or an index, so reordering the document does not
// silently point this at some other SQL.
@@ -796,7 +796,7 @@ func runSQLScript(t *testing.T, ta *testApp, script string) string {
}
res, err := conn.ExecContext(ctx, stmt)
if err != nil {
- t.Fatalf("SKILL.md §8 statement failed: %v\n%s", err, stmt)
+ t.Fatalf("SKILL.md §6 statement failed: %v\n%s", err, stmt)
}
switch verb := strings.ToUpper(bare(stmt)); {
case strings.HasPrefix(verb, "BEGIN"), strings.HasPrefix(verb, "COMMIT"):
@@ -835,7 +835,7 @@ func query(t *testing.T, ctx context.Context, conn *sql.Conn, stmt string) strin
t.Helper()
rows, err := conn.QueryContext(ctx, stmt)
if err != nil {
- t.Fatalf("SKILL.md §8 query failed: %v\n%s", err, stmt)
+ t.Fatalf("SKILL.md §6 query failed: %v\n%s", err, stmt)
}
defer rows.Close()
cols, err := rows.Columns()
diff --git a/handlers_test.go b/handlers_test.go
index 983344b..96cae25 100644
--- a/handlers_test.go
+++ b/handlers_test.go
@@ -1062,7 +1062,7 @@ func TestReconciliationWithEmailForSubjectRefusesAnotherAddressesToken(t *testin
// With no Config.EmailForSubject, idear has no way to turn a decimal
// user id into an address, so reconciliation asks only for a live
// token. A signed-in orphan holding one issued to somebody else
-// redeems it, at that token's role. That is what SKILL.md §7 says
+// redeems it, at that token's role. That is what SKILL.md §5 says
// happens, and this test is what keeps the two of them honest: change
// the behaviour and this goes red, which is the moment to change the
// documentation with it.
@@ -1078,7 +1078,7 @@ func TestReconciliationWithoutEmailForSubjectTrustsTheTokenAlone(t *testing.T) {
}
m := memberBySubject(t, app, "7")
if m == nil {
- t.Fatal("the permissive path admitted nobody; SKILL.md §7 says the token alone is enough here")
+ t.Fatal("the permissive path admitted nobody; SKILL.md §5 says the token alone is enough here")
}
if m.Role != idear.RoleAdmin {
t.Errorf("the orphan landed at %s, want the token's own admin — the risk being documented is exactly that it is the TOKEN's role", m.Role)