The door's button says Sign in; a quiet Title hint; /add's back link is the breadcrumb
Paul, 2026-10-01: the sign-in door's submit button says "Sign in", not "Email me a link" (Memoria supplies the label). Polish audit r3 B7: the Title hint was the label's bold; it is "(optional)", muted and regular. C5: /add's back link was a paragraph with a section rule under it; it is the breadcrumb nav the document page uses.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 files changed,
+33
−8
internal/memoria/handlers.go+2 −2internal/memoria/static/memoria.css+3 −0internal/memoria/templates/add.html+3 −3internal/memoriatest/chrome_test.go+20 −0internal/memoriatest/signin_door_test.go+5 −3
CI passed — run details
CI log
=== vet === go vet ./... === fmt === === test === go test ./... ? amadan.net/oficina/memoria/cmd/memoria [no test files] ok amadan.net/oficina/memoria/internal/memoria 6.476s ok amadan.net/oficina/memoria/internal/memoria/chunk (cached) ok amadan.net/oficina/memoria/internal/memoria/fact (cached) ? amadan.net/oficina/memoria/internal/memoria/icons [no test files] ok amadan.net/oficina/memoria/internal/memoria/index (cached) ok amadan.net/oficina/memoria/internal/memoria/notion (cached) ok amadan.net/oficina/memoria/internal/memoria/provider (cached) ok amadan.net/oficina/memoria/internal/memoria/query (cached) ok amadan.net/oficina/memoria/internal/memoria/seal (cached) ok amadan.net/oficina/memoria/internal/memoria/sibling (cached) ok amadan.net/oficina/memoria/internal/memoriatest 3.457s ? amadan.net/oficina/memoria/scripts/writeestilo [no test files] ? amadan.net/oficina/memoria/tools/bench [no test files] ? amadan.net/oficina/memoria/tools/drive [no test files] ? amadan.net/oficina/memoria/tools/seed [no test files] ? amadan.net/oficina/memoria/tools/vendorassets [no test files] === migration-check === go run github.com/carlosframework/rastrillo/cmd/rastrillo migration check rastrillo migration check: models and migrations agree
diff --git a/internal/memoria/handlers.go b/internal/memoria/handlers.go| index 8804b57..4670d5e 100644 |
| --- a/internal/memoria/handlers.go |
| +++ b/internal/memoria/handlers.go |
| @@ -399,7 +399,7 @@ func newDropZone() dropZone { |
| MaxFiles: maxDropFiles, |
| SniffBytes: sniffBytes, |
| - TitleHint: "(Optional. Gives a title to pasted text)", |
| + TitleHint: "(optional)", |
| FileLabel: "…or upload text files", |
| // Derived, so the hint cannot come to disagree with the caps it |
| // describes — nor with the refusals, which say them in the same |
| @@ -1261,7 +1261,7 @@ func (a *app) localSignin(w http.ResponseWriter, r *http.Request) { |
| Action: "/auth/begin", |
| AddressLabel: "Email address", |
| Help: signinHelp, |
| - Submit: "Email me a link", |
| + Submit: "Sign in", // Paul, 2026-10-01: the door says "Sign in" |
| OpenSource: &chrome.Link{Href: "/help/open-source", Label: "Open source"}, |
| } |
| if hasReturn { |
diff --git a/internal/memoria/static/memoria.css b/internal/memoria/static/memoria.css| index 5ada8c7..13c4bdc 100644 |
| --- a/internal/memoria/static/memoria.css |
| +++ b/internal/memoria/static/memoria.css |
| @@ -49,6 +49,9 @@ html { scrollbar-gutter: stable; } |
| [rst-stack] [rst-form-bar] { position: static; margin-top: 1rem; } |
| [rst-stack] { display: flex; flex-direction: column; gap: 0.35rem; } |
| [rst-stack] label { font-weight: 560; margin-top: 0.6rem; } |
| +/* A hint inside a label is quiet: muted and regular weight, not the |
| + * label's 560 (polish audit r3 B7). */ |
| +[rst-hint] { font-weight: 400; } |
| /* border-box: the fields are width 100% PLUS their padding otherwise, |
| * which ran 22px past the column at 1440 and off the screen at 390 |
| * (polish audit §B6). Password fields are here too: the Notion token |
diff --git a/internal/memoria/templates/add.html b/internal/memoria/templates/add.html| index d67b390..2687f85 100644 |
| --- a/internal/memoria/templates/add.html |
| +++ b/internal/memoria/templates/add.html |
| @@ -5,11 +5,11 @@ |
| here unchanged; POST /documents still receives them, and now redirects |
| back HERE with its outcome rather than to the index. The index keeps |
| search and the document list, and links here. */}} |
| -<p><a href="/">← Back to search</a></p> |
| -<section rst-section> |
| +<nav rst-breadcrumb><a href="/">← Back to search</a></nav> |
| +<section> |
| <h1>Add content</h1> |
| <form method="post" action="/documents" enctype="multipart/form-data" rst-stack> |
| - <label for="title">Title <span rst-muted>{{.Drop.TitleHint}}</span></label> |
| + <label for="title">Title <span rst-muted rst-hint>{{.Drop.TitleHint}}</span></label> |
| <input type="text" id="title" name="title"> |
| <label for="body">Paste text</label> |
| <textarea id="body" name="body" rows="8" placeholder="Paste a document, notes, minutes…"></textarea> |
diff --git a/internal/memoriatest/chrome_test.go b/internal/memoriatest/chrome_test.go| index e266538..933856a 100644 |
| --- a/internal/memoriatest/chrome_test.go |
| +++ b/internal/memoriatest/chrome_test.go |
| @@ -576,3 +576,23 @@ func TestEstilosChromeUsesOnlyDefinedTokens(t *testing.T) { |
| t.Fatalf("only %d token references in estilo's chrome; the walk is broken", seen) |
| } |
| } |
| + |
| +// polish audit r3 B7 and C5: the Title hint read as bold label text, and |
| +// /add put a section rule between "← Back to search" and its h1, where the |
| +// document page uses the breadcrumb nav. |
| +func TestTheAddPageReadsLikeTheDocumentPage(t *testing.T) { |
| + b := get(t, newApp(t), "/add").Body.String() |
| + if !strings.Contains(b, `<label for="title">Title <span rst-muted rst-hint>(optional)</span></label>`) { |
| + t.Error("the Title hint is not a quiet \"(optional)\"") |
| + } |
| + if !strings.Contains(b, `<nav rst-breadcrumb><a href="/">← Back to search</a></nav>`) { |
| + t.Error("/add's back link is not the breadcrumb the document page uses") |
| + } |
| + if regexp.MustCompile(`(?s)<section rst-section>\s*<h1>Add content</h1>`).MatchString(b) { |
| + t.Error("a section rule still sits between the back link and the h1") |
| + } |
| + css, _ := os.ReadFile(filepath.Join("..", "memoria", "static", "memoria.css")) |
| + if !regexp.MustCompile(`\[rst-hint\] \{[^}]*font-weight: 400`).Match(css) { |
| + t.Error("the hint inherits the label's weight") |
| + } |
| +} |
diff --git a/internal/memoriatest/signin_door_test.go b/internal/memoriatest/signin_door_test.go| index d94155c..1aceb81 100644 |
| --- a/internal/memoriatest/signin_door_test.go |
| +++ b/internal/memoriatest/signin_door_test.go |
| @@ -45,16 +45,18 @@ func TestSigninPageIsTheDoor(t *testing.T) { |
| "We’ll email you a link that signs you in. It works once and expires in 15 minutes.", |
| `href="/help/open-source"`, |
| `action="/auth/begin"`, |
| - `>Email me a link</button>`, |
| + // Paul, 2026-10-01: the door's button says "Sign in". |
| + `>Sign in</button>`, |
| } { |
| if !strings.Contains(html.UnescapeString(body), html.UnescapeString(want)) { |
| t.Errorf("the sign-in page lacks %q", want) |
| } |
| } |
| - // Retired (§9.2): the lede "Memoria holds your team's work…", and the |
| + // Retired (§9.2): "Email me a link" (Paul, 2026-10-01), the lede |
| + // "Memoria holds your team's work…", and the |
| // footer's egress claim, which is about searching and is said only to |
| // somebody signed in. |
| - for _, gone := range []string{"holds your team", "<footer", "leaves this instance"} { |
| + for _, gone := range []string{"Email me a link", "holds your team", "<footer", "leaves this instance"} { |
| if strings.Contains(body, gone) { |
| t.Errorf("the sign-in page still carries %q", gone) |
| } |