GSD-Unit: M001/S06/T01
13 KiB
S06 Research — Live environment stabilization and integrated acceptance rerun
Summary
S06 is primarily an environment-proof and acceptance-artifact slice, not a new feature slice. The product loop from S01–S05 is already implemented and mostly works against the local seeded dataset once the live backend is actually running and the browser is authenticated. The real blockers for a true live rerun are environmental:
- the frontend hard-calls
http://localhost:5202/apiin localhost dev (job-tracker-ui/src/api.ts), so the UI immediately fails withERR_CONNECTION_REFUSEDif the API is not already up - auth is required in the local dev environment (
JobTrackerApi/appsettings.Development.json), so a live rerun also needs a valid token/session before/jobs,/dashboard, and/remindersare usable - Gmail live continuity cannot be fully re-checked in this environment because Gmail OAuth is only partially configured:
Auth:GoogleClientIdexists, butGoogle:GmailClientSecret/ redirect config are absent, so/api/gmail/statusreportsconnected:falseand/api/admin/systemreportsgmailConfigured:false - the seeded local dataset is minimal (1 job / 1 company) and does not exercise the full S05 trust loop naturally: the sample job opens from reminders and the workspace/follow-up flow works, but the dashboard does not currently expose a useful job-level action card, and correspondence only has one linked external thread message plus one locally logged follow-up
This means S06 should likely split into: environment bring-up/diagnostics, then seed/data conditioning for acceptance, then real browser rerun + recorded artifact.
Active Requirements To Target
R008 — manual-send boundary stays explicit
S06 must re-prove this in the live browser, especially because Follow-up draft already renders a real Send and log email button in JobDetailsDialog while generation remains separate.
R009 — individual-first daily loop
S06 must prove the same job can be worked from overview surfaces without needing admin-only or multi-record complexity. The current local dataset is individual-friendly but too thin to prove all overview semantics.
Skills Discovered
- Existing installed skills used for approach guidance:
debug-like-expert— informed the evidence-first, no-assumption investigation approachagent-browser— informed the browser verification workflow
- Newly installed during research:
gmail(odyssey4me/agent-skills@gmail)
- Tried but not usable for this slice:
jezweb/claude-skills@google-workspacesearch result did not expose a directly installablegoogle-workspaceskill name from that repo
What Exists Now
Runtime and config surfaces
job-tracker-ui/src/api.ts- On
localhost, defaults API traffic tohttp://localhost:5202/api - In production/non-localhost, defaults to
/api - No CRA dev proxy file exists; dev depends on direct cross-origin API access
- On
JobTrackerApi/Program.cs- CORS policy defaults to
http://localhost:3000 app.UseCors("AllowReact")is already wired- auth + migrations + admin seeding happen at startup
- CORS policy defaults to
JobTrackerApi/appsettings.Development.jsonAuth:Require=true- local CORS allowlist includes
http://localhost:3000 - placeholder local admin + JWT values exist
Auth:GoogleClientIdplaceholder exists, which makes Google auth look enabled even when Gmail OAuth is not actually fully configured
README.md- already documents the exact dev topology: UI on
:3000, API on:5202, UI defaulting tohttp://localhost:5202/api
- already documents the exact dev topology: UI on
JobTrackerApi/Controllers/AdminSystemController.cs- best existing operational probe for S06
- exposes database, auth, Gmail-configured, and AI-health status in one call
job-tracker-ui/src/pages/AdminSystemPage.tsx- already renders the above status in the UI
Auth and entry behavior
JobTrackerApi/Controllers/AuthController.cs/api/auth/configtruthfully reportsrequireAuth,googleEnabled,localEnabled,allowRegistration- local login is still standard username/password
job-tracker-ui/src/App.tsx- fetches
/auth/configand redirects to/loginwhen auth is required and no token exists
- fetches
job-tracker-ui/src/pages/LoginPage.tsx- uses
/auth/loginor/auth/register allowRegistrationis only exposed if backend allows it
- uses
job-tracker-ui/src/auth.ts- token key is
authToken
- token key is
Daily-loop/workspace surfaces already in place
job-tracker-ui/src/components/JobTable.tsxjob-tracker-ui/src/components/DashboardView.tsxjob-tracker-ui/src/components/RemindersView.tsxjob-tracker-ui/src/components/JobDetailsDialog.tsxjob-tracker-ui/src/components/Correspondence.tsxjob-tracker-ui/src/end-to-end-trust-loop.test.tsx
The S05 contract is real: the workspace tabs, follow-up generation, reminders open path, and correspondence/follow-up tabs are all present in the running UI.
Evidence From Live Investigation
1. The original frontend blockage is real and immediate
When the browser opened http://localhost:3000/login before the API was up, the first failing request was:
GET http://localhost:5202/api/auth/config → net::ERR_CONNECTION_REFUSED
This matches the carried-forward gotcha exactly: if port 5202 is not serving, the shell UI loads but the real app loop is blocked.
2. Backend works once started correctly
Running from the API project directory with the explicit dotnet path succeeds:
ASPNETCORE_ENVIRONMENT=Development ASPNETCORE_URLS=http://127.0.0.1:5202 /home/pi/.gsd/agent/bin/dotnet run --no-launch-profile
Observed runtime facts:
- API listens on
http://127.0.0.1:5202 - DB migrations are already up to date
- local SQLite DB is present and readable
- the prior bg-shell failure was a process-launch/cwd/runtimeconfig issue, not an application-code crash
Important planning note: the generic bg_shell start cwd is not the user-mandated worktree by default in this harness. Absolute paths or an explicit shell cd are safer when scripting S06 verification.
3. Admin/system status gives the clearest stabilization checklist
GET /api/admin/system returned:
- database: configured + connectable
- auth: required, JWT key present
- Google login configured: true
- Gmail configured: false
- AI healthy: true
- storage has only 1 company / 1 job
This is the most useful pre-UAT gate to run before any browser rerun.
4. Live data is too thin for a full acceptance rerun
Current seeded API state:
GET /api/jobapplicationsreturns exactly 1 job:Acme Browser QA / Backend DeveloperworkflowSignal.actionKey = review-readinessneedsFollowUp = falseGET /api/jobapplications/remindersstill returns the same job under reminders, but only as an “Other reminders” case- dashboard renders analytics and aggregate cards, but with this dataset it does not expose the richer job-level action surface that S04/S05 were meant to re-check
This means the current local DB is enough to prove the app runs, but not enough to strongly prove the milestone’s intended /jobs → workspace → Gmail continuity → follow-up → dashboard/reminders loop.
5. Follow-up drafting and manual-send boundary are live
In the running browser, opening the sample job from /reminders succeeded and the job workspace rendered.
On the Follow-up draft tab, live UI showed:
- generated subject/body from
/api/jobapplications/1/followup-draft - recruiter recipient prefilled (
maria@acme.test) - explicit
Send and log emailbutton - separate generation/loading behavior from the send action
This supports R008: drafting is live, but send is still an explicit separate action.
6. Correspondence continuity UI is only partially exercised locally
Correspondence.tsx does contain the linked-thread continuity panel and manual refresh flow, but the local sample data does not currently expose it meaningfully:
GET /api/correspondence/1has one imported-style external thread message and one locally logged sent-style messageGET /api/gmail/statusreturnsconnected:false- because Gmail is disconnected and the second message lacks external thread metadata, the real linked-thread refresh loop cannot be demonstrated live here
So S06 cannot honestly claim Gmail continuity rerun in this environment until Gmail config + account linking are present.
Implementation Landscape
Natural task seams
Seam 1 — environment bring-up and diagnostics
Focus files/surfaces:
JobTrackerApi/Program.csJobTrackerApi/appsettings.Development.jsonjob-tracker-ui/src/api.tsREADME.mdJobTrackerApi/Controllers/AdminSystemController.csjob-tracker-ui/src/pages/AdminSystemPage.tsx
Goal:
- make the live local topology easy to start and verify before browser UAT begins
- likely produce or tighten a repeatable runbook/checklist rather than large code changes
Seam 2 — acceptance seed/data conditioning
Focus surfaces:
- existing API endpoints / local DB seed path
- possibly task-local scripts or documented setup steps
Goal:
- ensure at least one job truly exercises:
- overview action from
/jobs - meaningful reminder/dashboard action
- saved package state
- linked correspondence state
- follow-up draft grounding
- overview action from
This is the riskiest seam because the current one-job dataset is operational but not acceptance-rich.
Seam 3 — browser rerun and artifact capture
Focus surfaces:
- browser verification itself
.gsdUAT/summary artifact output for S06- likely downstream dependency for S07
Goal:
- record what was actually exercised live
- distinguish clearly between:
- fully live checks
- blocked checks
- mocked/not-possible checks
Recommendation
- Build a hard preflight gate first. Before any browser rerun, check:
- API reachable on
:5202 /api/auth/configreachable- admin/system status healthy for DB + AI
- Gmail-configured status truthfully known
- API reachable on
- Do not start with browser fixes. The main current failure mode is not React routing; it is environment readiness.
- Treat Gmail as an explicit acceptance branch. If Gmail remains unconfigured, S06 should record that the full Gmail continuity rerun is blocked and either:
- add a safe local config/setup task, or
- scope S06 to environment stabilization plus non-Gmail integrated rerun, leaving Gmail closure to a follow-up task/slice
- Augment the local acceptance dataset before claiming success. The present single sample job does not naturally prove dashboard/reminders/job-table coherence strongly enough.
- Use the S05 integrated regression as the contract oracle. If live behavior diverges from
job-tracker-ui/src/end-to-end-trust-loop.test.tsx, investigate the environment/data first before changing UI logic.
Risks / Constraints
- Gmail is the biggest live blocker.
googleConfigured=truedoes not mean Gmail import is usable;gmailConfigured=falsein admin/system is the truer signal for S06. - Auth can block all browser checks. Since dev auth is required, any UAT runbook must include token/login setup.
- The dataset currently biases toward a low-urgency readiness case. This can make dashboard/reminders look less actionable than they were designed to be.
- Do not infer success from shell render. The login page and app shell can render even while API traffic is broken.
Verification Plan
Preflight
- Start API from
JobTrackerApi/and verifyGET /api/auth/config - Verify
GET /api/admin/systemas an admin token/session - Confirm these fields before browser UAT:
database.canConnect = trueai.healthy = trueauth.required = true/falseunderstoodauth.gmailConfigured = trueif Gmail continuity is in scope
Browser rerun
For one chosen acceptance job:
/jobsopens the correct workspace/remindersopens the same job/workspace semantics/dashboardexposes and opens the same job/workspace semantics- Tailored CV shows saved package state clearly
- Correspondence shows linked-thread continuity state
- Follow-up draft shows grounded context and explicit manual-send boundary
- Do not click send unless outbound mail is intentionally pointed at a safe sink
Contract spot checks
Useful endpoints to compare against live UI:
GET /api/jobapplicationsGET /api/jobapplications/remindersGET /api/jobapplications/{id}GET /api/correspondence/{jobId}GET /api/jobapplications/{id}/followup-draftGET /api/gmail/statusGET /api/admin/system
Planner Notes
- This slice is not mainly a coding problem unless the planner finds a missing preflight/diagnostic surface. It is mostly an environment + proof problem.
- The first executable task should probably be a stabilization/proof task, not a product-feature task.
- If the planner wants a high-confidence S06 outcome, it should require a decision on whether Gmail live acceptance is actually achievable in this environment before promising full milestone rerun coverage.
- S07 depends on S06 producing truthful acceptance evidence. If S06 cannot execute Gmail live, that limitation must be recorded explicitly rather than papered over.