Read-only GET of a live Gitea /user/login showed the sign-in button is
<button class="ui primary button"> with NO type=submit attribute, so the seed
".ui.primary.button[type=submit]" would miss. Corrected to ".ui.primary.button"
(the mobile navbar toggle lacks "primary", so it stays unambiguous). Confirmed
during M-B4 rung-1 pre-live-fire prep; change-form selectors remain auth-gated
and self-heal-covered until the live run.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Real account-settings pages (Gitea /user/settings/account, most dashboards) are
reachable only inside an authenticated session, but the engine went straight to
the change URL. Add Site.LoginBeforeChange: when set, Rotate authenticates through
the Login flow with the OLD secret first, so the session cookie carries into the
change-page fetch. Extract the login sequence into a shared r.login() helper reused
by both the pre-change auth (old secret) and Verify (new secret). A login wall we
cannot clear — including where MFA would appear — fails SAFE (old secret kept).
GiteaSite() seeds a curated change-password recipe (LoginBeforeChange on, standard
Gitea selectors, ProofUnproven until run against a real instance — self-heal repairs
any selector drift on first run; SuccessText mismatch only fails safe).
Proven LIVE-VM: TestIntegration_loginBeforeChangeRotation drives real Chromium
through a Gitea-style cookie gate (change page 302s to /login unless authenticated):
login(old)→settings→rotate→verify(new)→old-rejected. Non-browser
TestRotate_loginBeforeChangeOrder asserts login precedes change navigation and the
pre-change login uses the OLD secret. Full suite green.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extends the Phase A-tier-1 site-side rotation engine with an optional Node
browser-sidecar and a deterministic self-heal tier, all proven LIVE-VM against
the local lab change-password form. go-rod stays the default; the sidecar is a
swap-in Driver behind the same Session/Driver/Rotator interfaces — no spine
change, backup + verify-new-before-revoke-old + proof gates all apply unchanged.
M-B1 sidecar parity: internal/browserrot/sidecar/ (index.js JSON-RPC over stdio,
patchright real-fingerprint Chromium, playwright-core fallback) + sidecar.go
Driver/Session. A shared test harness runs go-rod and the sidecar through the
identical live rotation proof.
M-B2 stealth: patchright removes navigator.webdriver; humanized input (Bezier
mouse paths + per-key typing jitter, no ML trajectory generation per plan §5).
M-B3 self-heal: Healer interface + heal-retry fill/click/text wrappers; on a
rotted selector, heal.js relocates the field from DOM structure ONLY (never a
value) and the engine rewrites + persists the recipe (recipes.go RecipeBook)
so the next run is Tier-1 again. Deterministic heuristic is the proven Tier-2;
Stagehand LLM strategy is opt-in + UNPROVEN. Leak-check asserts no secret ever
reaches a heal request (redacted IPC transcript).
Secret seam documented honestly: fill carries base64 secret bytes across exactly
one local stdio boundary, typed and wiped, never logged/persisted/sent to a
model. MFA/CAPTCHA still degrade to the human worklist (Hard Rule 5).
14 tests green, -race clean; lab/lab-provision-browserrot.sh proves both drivers.
M-B4 (first REAL self-owned site) deliberately NOT started — needs per-credential
authorization (safe-candidate ladder).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Deterministic, headless browser-driven password rotation:
discover change page via RFC 8615 / links, inject old+new over CDP
(no model in the loop), submit, and re-login to verify the new
password before commit. Implements rotate.Rotator so the mandatory
backup gate, verify-before-revoke ordering, and proof gate apply
unchanged; RevokeOld is a no-op (the site invalidates the old pw).
Proof-as-data per Site: the engine is LIVE-VM (real headless
Chromium vs a real local change-password form, via
lab-provision-browserrot.sh / TestIntegration_realBrowserRotation);
real-site selector tables stay UNPROVEN and nothing auto-registers
into production rotate yet. 14 packages, -race clean.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>