Skip to content

Commit 0835284

Browse files
committed
fix: recover saved repositories without losing authenticated sessions
1 parent ae6569b commit 0835284

12 files changed

Lines changed: 430 additions & 40 deletions

‎docs/CONTEXT.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ and external AI CLIs require a direct user request. Never merge old work implici
8282
- Existing Commons run 49092854-f9bd-4b7a-8d12-4ac5ea0e5f70 retains the approved,
8383
unmerged safe-timer change from job 811bdb98-bcbb-4b65-80b9-f19693aef6b4.
8484
Preserve it. 29 earlier lab experiments were verified before this release work.
85-
- Public source: antropos17/commit-zero at 5f9f88e; full CI passed, browser retry failed. Repair pending; preserve separate histories.
85+
- Public source: antropos17/commit-zero at ae6569b; all three CI jobs passed after Commons retry repair. Preserve separate histories.
8686
README GIF is a 15.8s condensed walkthrough of retained Sequence Kit work,
8787
not a continuous live recording. Static fallback included; desktop/mobile and all
8888
three CI jobs passed. Evidence: runtime/verification/github-readme-gif-2026-10-19.json.

‎docs/DEVELOPMENT.md‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ output under `.cache/tmp`. Child processes receive TEMP/TMP/TMPDIR explicitly.
8080
On Windows, a local Chrome installation can be used without downloading a
8181
Playwright browser by setting `CZ_BROWSER_EXECUTABLE` to its absolute executable
8282
path. `CZ_CAPTURE_BROWSER=1` saves catalog desktop/narrow captures under
83-
`runtime/verification`. `npm run test:ui` runs three serial groups with fresh
83+
`runtime/verification`. `npm run test:ui` runs four serial groups with fresh
8484
disposable in-memory services to preserve scenario independence and keep the
8585
normal 180-request/minute API limiter active. `scripts/test-ui.mjs`
8686
checks that each browser spec is listed exactly once. Playwright global setup
@@ -90,6 +90,10 @@ output under `.cache/tmp`. Child processes receive TEMP/TMP/TMPDIR explicitly.
9090
The initial Commons retry test pauses polling with Playwright's clock and holds
9191
the retry response until busy/disabled assertions pass. Resume its clock before
9292
axe analysis, which needs browser timers; do not add sleeps or automatic retries.
93+
Account recovery uses held real GET responses to check bookmark writes and
94+
session changes. Navigate by hash inside those fixtures so a page reload does
95+
not cancel the stale response being tested. `CZ_CAPTURE_ACCOUNT_RECOVERY=1`
96+
captures its actual desktop and full-page narrow failure states.
9397

9498
Use `npm run dev` for React Fast Refresh while developing. `npm start` serves
9599
compiled `dist` and requires a rebuild after UI changes. They share port 4173:

‎docs/DISTRIBUTION.md‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,14 +94,14 @@ announcement posted elsewhere.
9494
Before publishing a release, replace the candidate version with an actual tag,
9595
link its exact commit and CI run, re-run the documented gates, and record real
9696
browser/model/sandbox coverage separately. No release was created by this note.
97-
Current implemented-code checkpoint: public `5f9f88e`, [CI run 39217991578](https://github.com/antropos17/commit-zero/actions/runs/39217991578)
98-
passed the full gate and runtime dependency audit but failed the initial Commons
99-
retry browser fixture. It is not a release candidate. Local frozen gate at
100-
`af403ac` passed 72/72 Node tests, DOM/axe 2/2, build and serving with source
101-
hash `ec03fa28c6c8fbdb5282f6de6913c94e61c7b489ab9e833d038d6ebdedb42871`;
102-
separate local Chrome coverage passed 12/12. A deterministic retry/busy-state
103-
repair is in progress. Verify the final candidate revision before creating a
104-
release. The checked capture set is already published at `98389bd`.
97+
Current implemented-code checkpoint: public `ae6569b`, [CI run 39220678511](https://github.com/antropos17/commit-zero/actions/runs/39220678511)
98+
passed the full gate, Chromium and runtime dependency audit after the Commons
99+
retry repair. Local frozen gate at `3bfcc8d` passed 72/72 Node tests, DOM/axe 2/2,
100+
build and serving with source hash
101+
`26cf7d425e0bc517e4e67b52aa530f315823736ffc268f940052dd7474f47c73`;
102+
separate local Chrome coverage passed 12/12. The account-recovery addition awaits
103+
its full gate. Verify the final candidate revision before creating a release.
104+
The checked capture set is already published at `98389bd`.
105105

106106
## Show HN fact sheet for a human author
107107

‎docs/FIRST-RUN.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ do not establish runtime correctness. [Complete workflow](COMMONS.md).
5555
| Health request fails | Check gateway and provider terminals, then select **Check model** again. The draft remains in the form. |
5656
| Project address is already in use | The form retains its name and description; choose another address and submit again. No duplicate project is created. |
5757
| Saving a scenario repository is rate limited | The repository shows a persistent message beside **Save**. Wait briefly and select **Save** again; a failed request does not add a bookmark. |
58+
| Saved repositories are unavailable after sign-in | Your sign-in succeeded. Restore the service and select **Refresh saved repositories** on **My profile**. An unknown list is not shown as empty; a previously loaded list remains visible if refresh fails. |
5859
| Task fails or is cancelled | Inspect its retained timeline and raw receipt. Retry by explicitly starting a new task; a restarted server does not silently retry jobs. |
5960
| Provider setup is unavailable | Continue exploring the deterministic example and model-free Commons forms. Do not interpret these as actual model contributions. |
6061

@@ -75,3 +76,10 @@ comes from an actual Chrome run with one routed HTTP 503 on the initial state
7576
read. The same test reaches the real local service with HTTP 200 after keyboard
7677
Retry, verifies focus returns to main and keeps all navigation visible. It uses
7778
disposable services and starts no model work.
79+
80+
The [saved-list failure capture](media/account-unavailable-2026-10-19.png) shows
81+
an actual Chrome registration against disposable identity services, followed by
82+
one routed HTTP 503 for the optional list. Registration still succeeds; keyboard
83+
Refresh then receives HTTP 200. Separate held-response fixtures check that a
84+
completed bookmark write and a different user's list cannot be overwritten by
85+
an older read. No retained account data or model activity is used.

‎docs/HANDOFF-2026-10-19.md‎

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@ tracks dated decisions and receipts; this file is the operational entry point.
88
## Repositories and state
99

1010
- Working repository: `X:\ai-github`, branch `codex/development-foundation`,
11-
latest fully checked local commit `af403ac` at this checkpoint. The local data and model
11+
latest fully checked local commit `3bfcc8d` at this checkpoint. The local data and model
1212
installation are here. Recheck status before acting; this file can age.
1313
- Public repository: [antropos17/commit-zero](https://github.com/antropos17/commit-zero),
14-
`main` at `5f9f88e66d48f560e8099a39c5308999bd6b291e` after a normal push.
14+
`main` at `ae6569ba672dfed53cefe8967aa516764473feae` after a normal push.
1515
Its separate checkout is `.cache/publication`. The histories are unrelated;
16-
the public tree matches local `af403ac` (`f0e02e6c4249d91dc5bb9da9a8768a5cabadab59`).
17-
A Commons retry/busy-state repair is in progress after the public browser failure.
16+
the public tree matches local `3bfcc8d` (`46b22e1534ce4a2a2c520dc973e256e054f52f5e`).
17+
An account saved-list recovery/session-race unit is currently awaiting final gates.
1818
Do not merge histories, reset the local branch or force push. Recheck remote
1919
before publishing anything else.
20-
- Public CI [run 39217991578](https://github.com/antropos17/commit-zero/actions/runs/39217991578)
21-
passed the full gate and runtime dependency audit for `5f9f88e`, but Chromium
22-
failed the initial Commons retry fixture. Do not treat this as a green candidate.
20+
- Public CI [run 39220678511](https://github.com/antropos17/commit-zero/actions/runs/39220678511)
21+
passed full gate, Chromium and runtime dependency audit for `ae6569b`. The
22+
preceding retry-fixture failure at `5f9f88e` is preserved in the mission log.
2323
- This mission has not run local or hosted model inference, spawned product
2424
agents, submitted promotional posts or created a new release. Prior retained
2525
real model activity is historical and must remain distinct from fixtures.
@@ -101,10 +101,19 @@ Timer proposal from job `811bdb98-bcbb-4b65-80b9-f19693aef6b4`. Preserve it.
101101

102102
## Evidence and limits
103103

104-
- Latest local frozen full gate at `af403ac`: 72/72 Node tests, compiled DOM/axe
104+
The pending account unit separates successful authentication from saved-list
105+
loading. `AccountProvider` scopes reads to the active identity and invalidates
106+
older reads after a bookmark write. `MyProfile` has known/loading/error states
107+
and explicit Refresh, with keyboard focus restored only if the user has not
108+
chosen another control. Three focused Chrome tests passed, including a held
109+
prior-account response. [Actual failure capture](media/account-unavailable-2026-10-19.png).
110+
Grouped Chrome passed 15/15 and `check:identity` passed 10/10; the frozen full
111+
gate remains before this unit is committed.
112+
113+
- Latest local frozen full gate at `3bfcc8d`: 72/72 Node tests, compiled DOM/axe
105114
2/2, build and static serving passed. Stable source hash
106-
`ec03fa28c6c8fbdb5282f6de6913c94e61c7b489ab9e833d038d6ebdedb42871`;
107-
receipt `runtime/verification/model-identity-full-2026-10-19.json` (ignored by Git).
115+
`26cf7d425e0bc517e4e67b52aa530f315823736ffc268f940052dd7474f47c73`;
116+
receipt `runtime/verification/commons-retry-full-2026-10-19.json` (ignored by Git).
108117
- Installed Chrome browser suite passed 12/12 at desktop and 390px. Real captures
109118
are `runtime/verification/commons-first-run-{desktop,narrow}-2026-10-19.png`,
110119
`commons-provider-offline-desktop-2026-10-19.png` and catalog captures. Tests
@@ -172,7 +181,7 @@ Timer proposal from job `811bdb98-bcbb-4b65-80b9-f19693aef6b4`. Preserve it.
172181

173182
## Next work, in order
174183

175-
1. Complete the Commons retry repair: run focused UI, grouped Chrome and `npm run check` on frozen source,
184+
1. Complete account recovery: run grouped Chrome and `npm run check` on frozen source,
176185
commit it, copy the unpublished local commit into the separate public
177186
checkout, compare Git trees, push without force and inspect public CI.
178187
Record exact SHA and receipt.
@@ -205,7 +214,7 @@ Timer proposal from job `811bdb98-bcbb-4b65-80b9-f19693aef6b4`. Preserve it.
205214
> `docs/HANDOFF-2026-10-19.md`, and `docs/MISSION-2026-10-19.md`. Recheck Git
206215
> state and `npm run doctor`; use `npm run map -- <area>`. Preserve all runtime
207216
> data, credentials, earlier model receipts, and separate Git histories.
208-
> First inspect public CI for `5f9f88e` and complete any dirty Commons retry or
217+
> First confirm public CI for `ae6569b` and complete any dirty account recovery or
209218
> handoff unit. Then reproduce and improve one
210219
> concrete browser or transaction journey, using focused checks and the full
211220
> `npm run check` on frozen source. Keep model-backed catalog roles disabled;

‎docs/MISSION-2026-10-19.md‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Start: 03:46:17 UTC. Deadline: 15:46:17 UTC. Final integration reserve begins 14
1212

1313
## Current action
1414

15-
Repair the published Commons retry browser failure and its observed settled-busy defect. Then reproduce saved-list failure after registration and delayed account reads. Keep all new profiles disabled. The final integration reserve still begins at 14:16:17 UTC.
15+
Finish account saved-list recovery and stale-response guards. Registration, keyboard refresh and two held-response races pass in Chrome; run grouped browser and frozen full gates, then publish through the existing separate checkout. Keep all new profiles disabled. The final integration reserve still begins at 14:16:17 UTC.
1616

1717
## Decisions and limits
1818

@@ -76,6 +76,9 @@ Repair the published Commons retry browser failure and its observed settled-busy
7676
- 07:59 UTC: read the failed public browser log and downloaded its trace under runtime/verification/ci-39217991578-browser-failures. The fixture removed its route before waiting for the initial failed request to settle, allowing polling/load to remove Retry before clicking. A deterministic clock-controlled reproduction also exposed Commons' aria-busy remaining true after failure; its actual failing trace is under runtime/verification/commons-retry-baseline-2026-10-19. A focused correction passed once; stronger pending-request coverage is in progress. No model inference or retained-store write.
7777
- 08:05 UTC: focused UI passed DOM/axe 2/2, build and serving. An intermediate DOM run failed while selecting a PR; loading state is now limited to initial reads rather than re-rendering the room on every background poll, and the next focused run passed. The initial retry fixture now holds its second request and checks disabled/busy state before HTTP 200. A paused browser clock cannot run axe timers; that fixture now resumes the clock before its recovered-state axe check. Full grouped browser and frozen gate remain.
7878

79+
- 08:08 UTC: Commons retry committed locally as `3bfcc8d` after full gate 72/72, stable source hash `26cf7d425e0bc517e4e67b52aa530f315823736ffc268f940052dd7474f47c73`; receipt `runtime/verification/commons-retry-full-2026-10-19.json`. Normal publication produced `ae6569b` with identical tree `46b22e1534ce4a2a2c520dc973e256e054f52f5e`. [CI run 39220678511](https://github.com/antropos17/commit-zero/actions/runs/39220678511) passed all three jobs, including the formerly failing retry browser fixture.
80+
- 08:13 UTC: real Chrome reproduced registration HTTP 200 followed by saved-list HTTP 503 leaving the signup page without a visible error; baseline trace is under `runtime/verification/account-recovery-baseline-2026-10-19`. Authentication now completes independently of the optional list. The profile distinguishes unknown/loading/failed/known lists and has explicit Refresh. Generation and owner guards reject delayed reads after a bookmark write or session change. Three focused Chrome tests passed, including keyboard focus recovery and preserving a different focus choice while pending. Focused UI passed DOM/axe 2/2, build and serving. Final grouped/browser and full gates remain; retained account stores are untouched.
81+
7982
## Next checkpoint
8083

81-
Grouped Chrome passed 12/12 including the controlled Commons retry. Run the frozen full gate, then publish with tree comparison and inspect CI. Continue the account-recovery journey after this repair. Keep the final 90-minute reserve from 14:16:17 UTC.
84+
Account recovery passed identity 10/10 and all 15 grouped Chrome tests. Run the frozen full gate, commit and publish, then measure and address workspace temporary-output handling in browser tools. Keep the final 90-minute reserve from 14:16:17 UTC.
83 KB
Loading

‎prototype/app/pages/account.jsx‎

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from "react";
1+
import React, { useLayoutEffect, useRef, useState } from "react";
22
import { useAccount, useWorkspace, useResource } from "../hooks.mjs";
33
import { request } from "../api.mjs";
44
import { PageHeading, Repositories } from "../components/ui.jsx";
@@ -261,6 +261,19 @@ export function MyProfile({ notify }) {
261261
{ data } = useWorkspace();
262262
const [tab, setTab] = useState("saved"),
263263
[signingOut, setSigningOut] = useState(false);
264+
const refreshTrigger = useRef(null);
265+
useLayoutEffect(() => {
266+
if (account.bookmarksLoading) return;
267+
const pending = refreshTrigger.current;
268+
refreshTrigger.current = null;
269+
if (
270+
pending &&
271+
pending.owner === account.user?.id &&
272+
pending.node.isConnected &&
273+
document.activeElement === document.body
274+
)
275+
pending.node.focus({ preventScroll: true });
276+
}, [account.bookmarksLoading, account.user?.id]);
264277
if (!account.checked)
265278
return (
266279
<>
@@ -321,7 +334,9 @@ export function MyProfile({ notify }) {
321334
onClick={() => setTab("saved")}
322335
>
323336
Saved repositories{" "}
324-
<span className="count">{account.bookmarks.length}</span>
337+
{account.bookmarksKnown && (
338+
<span className="count">{account.bookmarks.length}</span>
339+
)}
325340
</button>
326341
<button
327342
className="btn"
@@ -339,7 +354,28 @@ export function MyProfile({ notify }) {
339354
<p className="page-intro">
340355
Save a repository from its code page to find it here.
341356
</p>
342-
{data && (
357+
<button
358+
className="btn"
359+
disabled={account.bookmarksLoading}
360+
onClick={(event) => {
361+
refreshTrigger.current = {
362+
node: event.currentTarget,
363+
owner: account.user.id,
364+
};
365+
void account.refreshBookmarks();
366+
}}
367+
>
368+
Refresh saved repositories
369+
</button>
370+
{account.bookmarksLoading && (
371+
<p role="status">Loading saved repositories…</p>
372+
)}
373+
{account.bookmarksError && (
374+
<p className="inline-error" role="alert">
375+
Saved repositories are unavailable. {account.bookmarksError}
376+
</p>
377+
)}
378+
{data && account.bookmarksKnown && (
343379
<Repositories
344380
repos={data.repos.filter((r) =>
345381
account.bookmarks.includes(r.id),
@@ -353,6 +389,7 @@ export function MyProfile({ notify }) {
353389
</p>
354390
)}
355391
{data &&
392+
account.bookmarksKnown &&
356393
account.bookmarks.some(
357394
(id) => !data.repos.some((r) => r.id === id),
358395
) && (

0 commit comments

Comments
 (0)