Password-gate /replay + /social as URL-only, strip their nav, fix visited-link color, add shared loading state #73

Closed
opened 2026-07-06 05:11:16 +00:00 by coilysiren · 4 comments
Owner

Foundational / cross-cutting. Several other tickets depend on the gate + shared loading component. Touches App.tsx + components/Layout.tsx (shared with the map/users/items tickets - merge main before pushing).

  • Page password. Add a lightweight password gate. The password does not need to be serious - a random string in SSM (e.g. /coilyco/eco-app/page-password), read at the service. A simple page-level password prompt is fine.
  • Gate /replay and /social behind it. Both become URL-only: remove them from the top nav (frontend/src/components/Layout.tsx) and from the Home page. Reachable only by typing the URL.
  • Visited-link color (global): links render purple after you've clicked them, unreadable against the green background. Fix the visited-link color to stay readable in the theme.
  • Shared loading-state component for heavier pages (the map + social tickets will use it).

Files: frontend/src/components/Layout.tsx, frontend/src/App.tsx, frontend/src/pages/Home.tsx, global CSS, src/eco_mcp_app/http_app.py (+ SSM read). Verify ward exec frontend-build + ward exec lint.

**Foundational / cross-cutting.** Several other tickets depend on the gate + shared loading component. Touches `App.tsx` + `components/Layout.tsx` (shared with the map/users/items tickets - merge `main` before pushing). - **Page password.** Add a lightweight password gate. The password does not need to be serious - a random string in SSM (e.g. `/coilyco/eco-app/page-password`), read at the service. A simple page-level password prompt is fine. - **Gate `/replay` and `/social`** behind it. Both become **URL-only**: remove them from the top nav (`frontend/src/components/Layout.tsx`) and from the Home page. Reachable only by typing the URL. - **Visited-link color** (global): links render purple after you've clicked them, unreadable against the green background. Fix the visited-link color to stay readable in the theme. - **Shared loading-state component** for heavier pages (the map + social tickets will use it). Files: `frontend/src/components/Layout.tsx`, `frontend/src/App.tsx`, `frontend/src/pages/Home.tsx`, global CSS, `src/eco_mcp_app/http_app.py` (+ SSM read). Verify `ward exec frontend-build` + `ward exec lint`.
Member

🔒 Reserved by ward agent --driver claude — container engineer-claude-eco-app-73 on host KAI-DESKTOP-TOWER is carrying this issue (reserved 2026-07-06T05:12:02Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); --force overrides.

Do not comment on or edit this issue to steer the run while it is reserved. The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a new issue, dispatched fresh — that is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494).

run seed context — what this run is carrying (ward#609)
  • Resolved: coilyco-gaming/eco-app#73 · branch issue-73 · driver claude · workflow direct-main
  • Run: engineer-claude-eco-app-73 · ward v0.413.0 · dispatched 2026-07-06T05:12:02Z
  • Comment thread: 0 included in the pre-flight read, 0 stripped (ward's own automated comments).

Issue body as seeded:

**Foundational / cross-cutting.** Several other tickets depend on the gate + shared loading component. Touches `App.tsx` + `components/Layout.tsx` (shared with the map/users/items tickets - merge `main` before pushing).

- **Page password.** Add a lightweight password gate. The password does not need to be serious - a random string in SSM (e.g. `/coilyco/eco-app/page-password`), read at the service. A simple page-level password prompt is fine.
- **Gate `/replay` and `/social`** behind it. Both become **URL-only**: remove them from the top nav (`frontend/src/components/Layout.tsx`) and from the Home page. Reachable only by typing the URL.
- **Visited-link color** (global): links render purple after you've clicked them, unreadable against the green background. Fix the visited-link color to stay readable in the theme.
- **Shared loading-state component** for heavier pages (the map + social tickets will use it).

Files: `frontend/src/components/Layout.tsx`, `frontend/src/App.tsx`, `frontend/src/pages/Home.tsx`, global CSS, `src/eco_mcp_app/http_app.py` (+ SSM read). Verify `ward exec frontend-build` + `ward exec lint`.

Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.413.0).

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --driver claude` — container `engineer-claude-eco-app-73` on host `KAI-DESKTOP-TOWER` is carrying this issue (reserved 2026-07-06T05:12:02Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); `--force` overrides. **Do not comment on or edit this issue to steer the run while it is reserved.** The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a **new issue, dispatched fresh** — that is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494). <details><summary>run seed context — what this run is carrying (ward#609)</summary> - **Resolved:** `coilyco-gaming/eco-app#73` · branch `issue-73` · driver `claude` · workflow `direct-main` - **Run:** `engineer-claude-eco-app-73` · ward `v0.413.0` · dispatched `2026-07-06T05:12:02Z` - **Comment thread:** 0 included in the pre-flight read, 0 stripped (ward's own automated comments). **Issue body as seeded:** ``` **Foundational / cross-cutting.** Several other tickets depend on the gate + shared loading component. Touches `App.tsx` + `components/Layout.tsx` (shared with the map/users/items tickets - merge `main` before pushing). - **Page password.** Add a lightweight password gate. The password does not need to be serious - a random string in SSM (e.g. `/coilyco/eco-app/page-password`), read at the service. A simple page-level password prompt is fine. - **Gate `/replay` and `/social`** behind it. Both become **URL-only**: remove them from the top nav (`frontend/src/components/Layout.tsx`) and from the Home page. Reachable only by typing the URL. - **Visited-link color** (global): links render purple after you've clicked them, unreadable against the green background. Fix the visited-link color to stay readable in the theme. - **Shared loading-state component** for heavier pages (the map + social tickets will use it). Files: `frontend/src/components/Layout.tsx`, `frontend/src/App.tsx`, `frontend/src/pages/Home.tsx`, global CSS, `src/eco_mcp_app/http_app.py` (+ SSM read). Verify `ward exec frontend-build` + `ward exec lint`. ``` Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.413.0). </details> <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Owner

🔓 Reservation released by ward container reap — container eco-app (--driver claude) exited at the auth pre-launch gate without launching the agent (ward#222/#264/#609), so the hold it took is retracted. A plain ward agent retry no longer needs --force.

Gate: auth smoke test (claude credentials)

Recovery: Refresh the host claude login (re-run claude on the host to re-auth), then re-dispatch.

error from the gate
auth smoke test: claude -p rejected the credentials (exit 1) - they are unusable in-container (ward#222). Refresh the host claude login (re-run 'claude' on the host) and relaunch; WARD_SMOKE_TEST_SKIP=1 bypasses.

— Claude (she/her), via ward agent

<!-- ward-agent-reservation-released --> 🔓 Reservation released by `ward container reap` — container `eco-app` (`--driver claude`) exited at the **auth** pre-launch gate without launching the agent (ward#222/#264/#609), so the hold it took is retracted. A plain `ward agent` retry no longer needs `--force`. **Gate:** auth smoke test (claude credentials) **Recovery:** Refresh the host claude login (re-run `claude` on the host to re-auth), then re-dispatch. <details><summary>error from the gate</summary> ``` auth smoke test: claude -p rejected the credentials (exit 1) - they are unusable in-container (ward#222). Refresh the host claude login (re-run 'claude' on the host) and relaunch; WARD_SMOKE_TEST_SKIP=1 bypasses. ``` </details> <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Member

🔒 Reserved by ward agent --driver claude — container engineer-claude-eco-app-73 on host KAI-DESKTOP-TOWER is carrying this issue (reserved 2026-07-06T05:35:00Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); --force overrides.

Do not comment on or edit this issue to steer the run while it is reserved. The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a new issue, dispatched fresh — that is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494).

run seed context — what this run is carrying (ward#609)
  • Resolved: coilyco-gaming/eco-app#73 · branch issue-73 · driver claude · workflow direct-main
  • Run: engineer-claude-eco-app-73 · ward v0.413.0 · dispatched 2026-07-06T05:35:00Z
  • Comment thread: 1 included in the pre-flight read, 1 stripped (ward's own automated comments).

Issue body as seeded:

**Foundational / cross-cutting.** Several other tickets depend on the gate + shared loading component. Touches `App.tsx` + `components/Layout.tsx` (shared with the map/users/items tickets - merge `main` before pushing).

- **Page password.** Add a lightweight password gate. The password does not need to be serious - a random string in SSM (e.g. `/coilyco/eco-app/page-password`), read at the service. A simple page-level password prompt is fine.
- **Gate `/replay` and `/social`** behind it. Both become **URL-only**: remove them from the top nav (`frontend/src/components/Layout.tsx`) and from the Home page. Reachable only by typing the URL.
- **Visited-link color** (global): links render purple after you've clicked them, unreadable against the green background. Fix the visited-link color to stay readable in the theme.
- **Shared loading-state component** for heavier pages (the map + social tickets will use it).

Files: `frontend/src/components/Layout.tsx`, `frontend/src/App.tsx`, `frontend/src/pages/Home.tsx`, global CSS, `src/eco_mcp_app/http_app.py` (+ SSM read). Verify `ward exec frontend-build` + `ward exec lint`.

Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.413.0).

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --driver claude` — container `engineer-claude-eco-app-73` on host `KAI-DESKTOP-TOWER` is carrying this issue (reserved 2026-07-06T05:35:00Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); `--force` overrides. **Do not comment on or edit this issue to steer the run while it is reserved.** The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a **new issue, dispatched fresh** — that is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494). <details><summary>run seed context — what this run is carrying (ward#609)</summary> - **Resolved:** `coilyco-gaming/eco-app#73` · branch `issue-73` · driver `claude` · workflow `direct-main` - **Run:** `engineer-claude-eco-app-73` · ward `v0.413.0` · dispatched `2026-07-06T05:35:00Z` - **Comment thread:** 1 included in the pre-flight read, 1 stripped (ward's own automated comments). - included: @coilysiren (2026-07-06T05:12:27Z) - stripped: @coilyco-ops (2026-07-06T05:12:07Z) **Issue body as seeded:** ``` **Foundational / cross-cutting.** Several other tickets depend on the gate + shared loading component. Touches `App.tsx` + `components/Layout.tsx` (shared with the map/users/items tickets - merge `main` before pushing). - **Page password.** Add a lightweight password gate. The password does not need to be serious - a random string in SSM (e.g. `/coilyco/eco-app/page-password`), read at the service. A simple page-level password prompt is fine. - **Gate `/replay` and `/social`** behind it. Both become **URL-only**: remove them from the top nav (`frontend/src/components/Layout.tsx`) and from the Home page. Reachable only by typing the URL. - **Visited-link color** (global): links render purple after you've clicked them, unreadable against the green background. Fix the visited-link color to stay readable in the theme. - **Shared loading-state component** for heavier pages (the map + social tickets will use it). Files: `frontend/src/components/Layout.tsx`, `frontend/src/App.tsx`, `frontend/src/pages/Home.tsx`, global CSS, `src/eco_mcp_app/http_app.py` (+ SSM read). Verify `ward exec frontend-build` + `ward exec lint`. ``` Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.413.0). </details> <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Owner

WARD-OUTCOME: done - page-password gate on /replay + /social (URL-only), shared , global visited-link fix; landed on main as 2dbcf3a.

Honest retro: this one went smoothly, which for a "foundational / cross-cutting" ticket is a little suspicious in a good way. The repo already had every pattern I needed sitting right next to me — species.py's env-then-SSM admin-key lookup was a clean template for page_auth.py, so the backend was mostly transcription with a timing-safe compare bolted on. The gate itself is deliberately a soft speed bump: password verified server-side, never shipped to the client, but the JSON APIs behind those pages stay public, so nobody should mistake it for real auth.

Two things fought back, both minor. ESLint's react-hooks/set-state-in-effect rejected my first cut of PagePassword (synchronous setState in the effect for the "already unlocked" shortcut) — moving that into a lazy useState initializer was the right fix anyway. And the merge: main moved twice under me, the second time (#78's /economy rework) collided in FEATURES.md on the same React-frontend bullet I was editing. Resolved by keeping my side and splicing in their richer /economy sentence — no code conflict, App.tsx/Layout.tsx/Home.tsx all auto-merged.

Confident in the result: 463 py + 89 fe tests green, build + lint + precommit clean, all re-run post-merge on the final tree.

One real follow-up worth filing: the SSM parameter /coilyco/eco-app/page-password still needs to be created (a random string), and the deploy repo (coilyco-bridge/deploy) should wire ECO_PAGE_PASSWORD into the pod env via ExternalSecret — same shape as SENTRY_DSN. Until then the gate stays open in prod (no password configured = render through), which is a safe default but means the surfaces aren't actually gated live yet. That's an operator/deploy-repo action, out of this container's scope.

WARD-OUTCOME: done - page-password gate on /replay + /social (URL-only), shared <Loading>, global visited-link fix; landed on main as 2dbcf3a. Honest retro: this one went smoothly, which for a "foundational / cross-cutting" ticket is a little suspicious in a good way. The repo already had every pattern I needed sitting right next to me — `species.py`'s env-then-SSM admin-key lookup was a clean template for `page_auth.py`, so the backend was mostly transcription with a timing-safe compare bolted on. The gate itself is deliberately a soft speed bump: password verified server-side, never shipped to the client, but the JSON APIs behind those pages stay public, so nobody should mistake it for real auth. Two things fought back, both minor. ESLint's `react-hooks/set-state-in-effect` rejected my first cut of `PagePassword` (synchronous setState in the effect for the "already unlocked" shortcut) — moving that into a lazy `useState` initializer was the right fix anyway. And the merge: `main` moved twice under me, the second time (#78's /economy rework) collided in FEATURES.md on the same React-frontend bullet I was editing. Resolved by keeping my side and splicing in their richer /economy sentence — no code conflict, App.tsx/Layout.tsx/Home.tsx all auto-merged. Confident in the result: 463 py + 89 fe tests green, build + lint + precommit clean, all re-run post-merge on the final tree. One real follow-up worth filing: the SSM parameter `/coilyco/eco-app/page-password` still needs to be *created* (a random string), and the deploy repo (coilyco-bridge/deploy) should wire `ECO_PAGE_PASSWORD` into the pod env via ExternalSecret — same shape as SENTRY_DSN. Until then the gate stays open in prod (no password configured = render through), which is a safe default but means the surfaces aren't actually gated live yet. That's an operator/deploy-repo action, out of this container's scope.
Sign in to join this conversation.
No description provided.