Commit Graph

83 Commits

Author SHA1 Message Date
lilleman 428800fd62 Items 62, 69, 64: group delete in one Keto transaction, dashboard view rename, permissions kept on self-refusals
CI / full-gate (push) Successful in 3m19s
2026-11-08 23:04:18 +01:00
lilleman 3179be0d11 Answer prose round 1: 0 🔴, 10 🟡 (0 misread); define code health, restore the topic index, give each decision a premise of its own
CI / full-gate (push) Successful in 3m39s
2026-11-08 21:09:19 +01:00
lilleman 7ad46d0adf Move the decisions out of AGENTS.md into docs/decisions.md
CI / full-gate (push) Successful in 4m5s
2026-11-08 21:00:53 +01:00
lilleman 77e3d46769 Rename ShellUser.menu to profileLinks, so menu keeps one meaning in the shell
CI / full-gate (push) Successful in 3m29s
Mirror / github-mirror (push) Successful in 5s
2026-11-08 19:35:14 +01:00
lilleman 777c0bd86d Let a plugin add links to the profile menu, and list the setting conflict kind
CI / full-gate (push) Failing after 1m17s
2026-11-08 19:17:57 +01:00
lilleman 404f2584ac Add buildPaginationModel and ctx.assetHref, and bump the plugin contract to 0.5.0
CI / full-gate (push) Failing after 5s
2026-11-08 14:32:05 +01:00
lilleman ccb4d32d39 Answer prose round 1: 0 🔴, 4 🟡 (0 misread); comments say what the forms post where, restating test comments go
CI / full-gate (push) Successful in 3m23s
Mirror / github-mirror (push) Successful in 4s
2026-10-31 12:59:28 +01:00
lilleman ead604f49d Accept a verification or recovery code pasted with whitespace around it
CI / full-gate (push) Failing after 16s
2026-10-31 12:41:11 +01:00
lilleman 3d757d4726 item-34 - Serve every /public/ asset under a content-versioned URL with an immutable Cache-Control 2026-10-31 10:00:03 +01:00
lilleman f4969d5c1f Refuse a stale permission save, confirm or report it, show View to read-only holders, keep an absolute return_to beside a locale
CI / full-gate (push) Failing after 2m53s
2026-10-31 09:34:05 +01:00
lilleman 437a2e8580 Answer stability round 1: 0 🔴, 3 🟡 (0 misread); pin dashboard heading and branding, fix stale comment 2026-10-31 08:41:59 +01:00
lilleman 352de29013 Retire shell-context and render the dashboard from ctx.chrome
CI / full-gate (push) Successful in 3m18s
2026-10-31 08:37:45 +01:00
lilleman 520d2c928d Visual E2E at five viewports, typecheck e2e-tests in the gate, drop unused icons
CI / full-gate (push) Successful in 3m29s
2026-10-31 08:20:16 +01:00
lilleman a190166421 Answer stability round 1: 1 🔴, 6 🟡 (0 misread); hide the theme switch after its base rule, hide inert nav toggles, test the rendered result 2026-10-31 01:32:26 +01:00
lilleman 53ab35bfb8 A page is a document: drop the sticky chrome and the bounded-frame opt-out 2026-09-10 16:16:35 +02:00
lilleman 60aa8a888e Point the contract doc at a heading that exists, and let the table say which axes it scrolls 2026-09-10 16:16:35 +02:00
lilleman cb4f8d6e98 Name the table's local after the class it applies, and let a broken chain show itself 2026-09-10 16:16:35 +02:00
lilleman 696da397e7 Split the fill seam where ownership splits: the shell bounds, the page fills 2026-09-10 16:16:35 +02:00
lilleman 7f2c0cc2c2 Name the bounded frame: fill:true on the shell, and the contract minor that ships it 2026-09-10 16:16:35 +02:00
lilleman cb4468ff77 Regenerate the icon sprite: lucide 1.39.0 redraws circle-check
CI / full-gate (push) Successful in 2m57s
Mirror / github-mirror (push) Successful in 3s
2026-09-10 16:16:31 +02:00
lilleman 54956fe627 Release the gate change as 0.3.0, and start a changelog
CI / full-gate (push) Successful in 2m50s
Mirror / github-mirror (push) Successful in 4s
Release / retag-image (push) Successful in 22s
Release / publish-overview (push) Successful in 3s
2026-09-03 17:58:09 +02:00
lilleman bf146c07e7 Bump the contract for the new gate, and close the ways it could read as open
CI / full-gate (push) Successful in 2m45s
2026-09-02 08:36:16 +02:00
lilleman 43bb004ae7 Keep the control-choosing rule where a caller picks one
CI / full-gate (push) Successful in 2m50s
Mirror / github-mirror (push) Successful in 3s
2026-08-25 09:38:33 +02:00
lilleman f4693af3df Let a multi-select say what a capped list left out, inside the panel
CI / full-gate (push) Successful in 2m52s
2026-08-25 09:15:30 +02:00
lilleman c702a347dc Offer a long filter list as a popover multi-select instead of a wall of chips
CI / full-gate (push) Successful in 2m51s
2026-08-25 09:10:23 +02:00
lilleman fa7cad1d65 Declare plugin settings in the manifest, resolve them from the environment 2026-08-23 13:17:03 +02:00
lilleman a3d9a3df5f Keep the release at v0.1.0 — nothing consumed the old contract 2026-08-22 11:21:42 +02:00
lilleman d545445ea8 Release this as v0.2.0, and give the Hub overview its own job, token and template 2026-08-20 23:32:10 +02:00
lilleman c35ba3fb4e Make the plugin contract version the release version, and publish the Docker Hub overview from CI 2026-08-20 23:16:11 +02:00
lilleman 9cf6c05325 Name the chrome's language menu and guard anchor positioning in the fallback
CI / full-gate (push) Successful in 2m44s
2026-08-05 02:23:50 +02:00
lilleman cfeee10fa8 Wrap each popover menu and give it a caller-named id
CI / full-gate (push) Successful in 2m43s
2026-08-05 01:58:11 +02:00
lilleman 5d9bdebf59 Close the popup menus on an outside click, via the popover API
CI / full-gate (push) Successful in 2m40s
2026-08-05 01:37:58 +02:00
lilleman 3c64621515 Remove the dead Profile link from the sidebar profile menu
CI / full-gate (push) Successful in 2m39s
2026-08-05 01:01:14 +02:00
lilleman 8f7ab55267 Remove the Settings cog and its Preferences menu from the sidebar footer
CI / full-gate (push) Successful in 2m37s
2026-08-05 00:08:35 +02:00
lilleman bd76c981ee Carry the language through sign-in; warn when switching leaves the page; product-review copy fixes
CI / full-gate (push) Successful in 2m40s
2026-08-04 09:59:00 +02:00
lilleman 7e4c6940c9 Escape the values interpolated into the one markup-carrying message
CI / full-gate (push) Successful in 2m37s
2026-08-04 00:42:54 +02:00
lilleman 18e1a8d29d Keep the chrome lazy for error pages, guard the guard-error render, split the recovery link
CI / full-gate (push) Successful in 2m38s
2026-08-04 00:31:19 +02:00
lilleman 93139ea058 Stability round two: no language links on POST-rendered pages, scoped observers, Vary only where it varies
CI / full-gate (push) Successful in 2m37s
2026-08-04 00:10:31 +02:00
lilleman be3bc2bdbb Stability fixes: plugin-scoped contexts for owned pages, absent-href guard, checked locale mounts
CI / full-gate (push) Successful in 2m37s
2026-08-03 23:51:40 +02:00
lilleman b3df7084c4 Reserve the locale param, carry it on breadcrumbs, translate the permissions detail view
CI / full-gate (push) Successful in 2m38s
2026-08-03 23:21:38 +02:00
lilleman 6440c543e5 Architecture review fixes: partials carry the locale, mountable locales/, shared core words
CI / full-gate (push) Successful in 2m36s
2026-08-03 23:12:18 +02:00
lilleman 245d1ad5b5 Add i18n support: per-locale catalogs, URL-driven locale, translated core and examples
CI / full-gate (push) Successful in 2m37s
2026-08-03 22:37:27 +02:00
lilleman 096720904e Rename the coarse gate from role to permission, matching RBAC 2026-08-03 17:41:40 +02:00
lilleman ffeec70f8f Update lockfile and regenerate icons.ejs for lucide-static 1.28.0
CI / full-gate (push) Successful in 2m44s
Mirror / github-mirror (push) Successful in 6s
2026-08-02 15:15:12 +02:00
lilleman e8ea911b80 Move admin screens (users/groups/roles/oauth2-clients) into a drop-in example plugin; add the ctx.system capability surface 2026-07-02 08:01:15 +02:00
lilleman de22f51c12 Organize src/ into concern folders (http, auth, admin, plugin-host, ui); co-locate tests, move plugin-api barrel into plugin-host, sync docs + AGENTS layout 2026-06-24 00:23:55 +02:00
lilleman a9f25a7692 Remove completed todo.md + html-css-foundation mockups; strip dead §N phase refs from comments/docs (simplify visual E2E to drop the mockup-comparison oracle) 2026-06-23 22:49:28 +02:00
lilleman e22d24aa8a §10 - one menu everywhere (buildPluginChrome) + shell on every page; instructional starter dashboard; Kratos-native email docs
Collapse the three nav builders into buildPluginChrome: chrome.bestHref does longest-prefix matching so deep admin routes mark their leaf. Delete adminNav; buildConfirmModel and the admin model builders take the resolved nav. The same role-filtered sidebar now renders signed in or out, collapsing to a burger on narrow screens.

shell.ejs gains menu (default true; menu:false -> single-column .app-bare), docTitle (separate <title> from the topbar, so the body keeps the single <h1>), and hideSignIn (suppress the footer Sign-in on auth pages to avoid a login loop). auth/home/landing now render inside the shell.

Dashboard is a replaceable instructional starter (definePlugin snippet, no mock data). Email stays delegated to Kratos: documented its built-in courier.template_override_path instead of adding web-side SMTP.
2026-06-23 21:26:00 +02:00
lilleman af097a8885 Verification/recovery: guard the OTP code field against a pasted space (numeric inputmode + digits-only pattern + one-time-code autofill); Kratos doesn't trim, so a space-padded code was rejected as 'invalid or already used' 2026-06-21 23:26:23 +02:00
lilleman 1d198acc97 Canonical host via APP_URL: stop login dumping users on /error from a host mismatch
The from-scratch dev login was broken: open the banner's http://localhost:3000, sign
in as the seeded admin, and you landed on http://127.0.0.1:3000/error "Page not found".
Root cause: the banner/APP_URL said localhost but kratos.yml hard-coded 127.0.0.1, and a
host-scoped Kratos CSRF cookie can't cross localhost<->127.0.0.1, so the cross-host login
POST lost it; Kratos redirected to its error sink, which the app had no route for (404).

Make APP_URL the single source of truth for the public host:
- Canonical-host redirect (app.ts): when APP_URL is set, an off-host GET/HEAD visitor is
  308'd to it (path+query kept) before a flow starts, so the browser, the themed forms and
  the cross-origin Kratos POST share one cookie host. After /public/ so static/health
  checks stay host-agnostic; GET/HEAD only so a 308 never replays a cross-host POST.
- Opt-in (no NODE_ENV / no magic default): unset => no redirect, so a prod deploy that
  forgets APP_URL can't bounce real users to a stale default. The dev stack sets it.
- kratos.yml browser URLs default to localhost (match APP_URL's dev value) and derive from
  ${APP_URL} via compose.override.yml; SERVE_PUBLIC_BASE_URL keeps the dev Ory port.
- Real /error page (views/error.ejs) replaces the catch-all 404 for genuine flow errors.

Tests-first: config (opt-in/validated), app (308 on mismatch, no-redirect on match, static
host-agnostic, POST untouched, /error page), updated kratos.test host pins. New devstack
regression (e2e/devstack-login.spec + compose.e2e-devstack.yml) drives the plain
docker-compose-up topology on the host network: login from localhost works and 127.0.0.1 is
canonicalised; wired into scripts/ci.sh. typecheck + 360 units + full ci.sh (visual 10 ·
auth 1 · oauth 2 · full 7 · devstack 2) green.
2026-06-21 21:52:20 +02:00