docs: Added docs/s07-uat.md to close S07 with imported acceptance-run e…
- "docs/s07-uat.md" - ".gsd/milestones/M001/slices/S07/tasks/T01-SUMMARY.md" GSD-Task: S07/T01
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
---
|
||||
id: S06
|
||||
parent: M001
|
||||
milestone: M001
|
||||
provides:
|
||||
- A repeatable localhost preflight + seed + acceptance-run workflow for the M001 trust loop.
|
||||
- A deterministic live acceptance fixture (`S06 Acceptance Labs` / `S06 Acceptance Backend Engineer`) that surfaces saved package state, recruiter-thread correspondence, follow-up readiness, and dashboard/reminder visibility.
|
||||
- A recorded live acceptance artifact that downstream closure/UAT work can reference instead of reconstructing the environment from scratch.
|
||||
- Fresh live proof that the manual-send boundary still holds in the real stack.
|
||||
requires:
|
||||
- slice: S05
|
||||
provides: The shared workflow-signal contract, integrated trust-loop regression, and manual-send-boundary behavior that S06 re-verified in the real environment.
|
||||
affects:
|
||||
- S07
|
||||
key_files:
|
||||
- scripts/s06-preflight.sh
|
||||
- scripts/s06-acceptance-data.sh
|
||||
- scripts/s06-acceptance-data.test.sh
|
||||
- scripts/s06-acceptance-run.sh
|
||||
- docs/s06-acceptance-run.md
|
||||
- .gsd/DECISIONS.md
|
||||
- .gsd/KNOWLEDGE.md
|
||||
- .gsd/PROJECT.md
|
||||
key_decisions:
|
||||
- D013: seed the acceptance fixture through the live API contract with deterministic identifiers so reruns are idempotent and prove real code paths.
|
||||
- D014: allow the acceptance runner to mint a localhost-only admin JWT from checked-in dev JWT settings plus the local SQLite admin user when `AUTH_TOKEN` is absent.
|
||||
- D015: treat `/api/auth/config` reachability plus an auth-limited `/api/admin/system` probe as a guided partial-pass, and never echo bearer tokens in preflight output.
|
||||
patterns_established:
|
||||
- Use a preflight gate before browser UAT so backend/CORS/auth blockers fail fast with readable guidance instead of surfacing later as ambiguous frontend runtime errors.
|
||||
- Seed live acceptance fixtures through the same authenticated HTTP endpoints the UI uses, with deterministic company/title/thread/message identifiers, so reruns prove the real contract and stay idempotent.
|
||||
- Persist a single acceptance-run artifact (`docs/s06-acceptance-run.md`) that refreshes shell evidence without destroying the guided browser-observation section, so later slices can build on one stable handoff document.
|
||||
- Record manual-send-boundary evidence as both UI observation and network evidence; for this slice, drafting may call `GET .../followup-draft` but must not trigger `POST .../send-followup` without an explicit human action.
|
||||
observability_surfaces:
|
||||
- `scripts/s06-preflight.sh` console output for auth/db/gmailConfigured/ai readiness signals and clear failure guidance.
|
||||
- `scripts/s06-acceptance-data.sh` seed summary output (`seed.result`, job/company ids, workflow action, readiness level, reminder state).
|
||||
- `docs/s06-acceptance-run.md` plus `docs/artifacts/s06-acceptance/logs/*` for shell-step evidence and blocker guidance.
|
||||
- Recorded browser artifacts referenced from the acceptance doc (jobs/workspace, follow-up draft, reminders/dashboard, trace, timeline).
|
||||
drill_down_paths:
|
||||
- .gsd/milestones/M001/slices/S06/tasks/T01-SUMMARY.md
|
||||
- .gsd/milestones/M001/slices/S06/tasks/T02-SUMMARY.md
|
||||
- .gsd/milestones/M001/slices/S06/tasks/T03-SUMMARY.md
|
||||
duration: ""
|
||||
verification_result: passed
|
||||
completed_at: 2026-03-27T08:29:02.335Z
|
||||
blocker_discovered: false
|
||||
---
|
||||
|
||||
# S06: Live environment stabilization and integrated acceptance rerun
|
||||
|
||||
**Stabilized the live localhost stack with a repeatable preflight + seed + acceptance runner flow and re-proved the `/jobs` → workspace → reminders/dashboard loop with recorded manual-send-boundary evidence.**
|
||||
|
||||
## What Happened
|
||||
|
||||
S06 turned the previously fragile live environment into a repeatable acceptance target instead of a one-off debugging session. The slice added a preflight gate that checks the real API contract before UI work starts, an idempotent live-data seed that creates or refreshes a deterministic acceptance fixture through the same HTTP endpoints the app uses in normal operation, and a single acceptance runner that ties preflight, seeding, the integrated trust-loop regression, and the live evidence document together. The resulting live run now proves that the seeded job appears on `/jobs`, opens the real workspace with saved Tailored CV and package state, shows deterministic recruiter-thread correspondence, appears on `/reminders` with the expected `Follow up` / `Waiting 14d` signals, and contributes to `/dashboard` analytics without frontend runtime failures. The slice also re-proved the manual-send boundary in the actual stack: opening or regenerating the follow-up draft issued `GET /api/jobapplications/3/followup-draft` but no `POST /api/jobapplications/3/send-followup`, so drafting stayed assistive and did not cross into autonomous sending. The main remaining live gap is Gmail-connected continuity: the seeded correspondence is visible, but this localhost run did not have a connected Gmail session and therefore did not execute a linked-thread refresh request. That gap is now explicit in the acceptance artifact instead of being mistaken for a fully proven live Gmail refresh.
|
||||
|
||||
## Verification
|
||||
|
||||
Verified the assembled slice in the live worktree with the real backend and frontend running on the expected localhost origins. Commands run: `bash scripts/s06-preflight.sh` (exit 0, expected auth-limited partial-pass when `/api/admin/system` requires a token), `TEST_AUTH_TOKEN="$TOKEN" AUTH_TOKEN="$TOKEN" bash scripts/s06-acceptance-data.test.sh` (exit 0; missing-token, bad-token, and double-rerun cases all passed), `AUTH_TOKEN="$TOKEN" bash scripts/s06-acceptance-data.sh` (exit 0; `seed.result=success`, stable company/job fixture, `seed.workflow.action=follow-up`, `seed.readiness.level=Ready`, `seed.reminders=Waiting 14d`), and `bash scripts/s06-acceptance-run.sh && test -s docs/s06-acceptance-run.md` (exit 0). The recorded live browser evidence in `docs/s06-acceptance-run.md` confirms `/jobs`, workspace, `/reminders`, and `/dashboard` behavior plus the manual-send boundary and a clean dashboard reload with no console errors or failed requests.
|
||||
|
||||
## Requirements Advanced
|
||||
|
||||
- R008 — S06 re-proved the manual-send boundary in the live stack: follow-up drafting remained assistive, and the recorded network evidence showed no send endpoint call during draft review/regeneration.
|
||||
- R009 — S06 re-checked the individual-first loop in the real environment by proving one seeded job behaves coherently across `/jobs`, the per-job workspace, `/reminders`, and `/dashboard`.
|
||||
|
||||
## Requirements Validated
|
||||
|
||||
None.
|
||||
|
||||
## New Requirements Surfaced
|
||||
|
||||
None.
|
||||
|
||||
## Requirements Invalidated or Re-scoped
|
||||
|
||||
None.
|
||||
|
||||
## Deviations
|
||||
|
||||
Added two bounded implementation choices beyond the original plan to keep reruns repeatable in this real environment: a localhost-only JWT fallback inside the acceptance runner because the checked-in dev password no longer authenticates against the current SQLite snapshot, and an explicit preflight partial-pass path for the auth-limited `/api/admin/system` case so browser/UAT work is blocked only by true environment failures. Gmail continuity was recorded as not configured/not refreshed in this run rather than being overstated as a proven live success.
|
||||
|
||||
## Known Limitations
|
||||
|
||||
This slice does not prove a real Gmail-connected linked-thread refresh in the local environment. The seeded recruiter correspondence is present and the workspace loop is otherwise live, but the browser run did not expose connected Gmail state or issue `POST /api/gmail/refresh-linked-threads`. The acceptance data fixture is intentionally deterministic and single-user; it is suitable for localhost reruns, not for multi-user or production seeding.
|
||||
|
||||
## Follow-ups
|
||||
|
||||
S07 should turn this rerunnable acceptance flow into the final daily-loop UAT closure artifact, ideally in an environment where Gmail is actually connected so linked-thread refresh can be observed live. If the Gmail account remains unavailable locally, S07 should keep the limitation explicit rather than weakening the trust claim. If future slices rely on the S06 fixture, preserve the deterministic identifiers and rerun-safe update behavior instead of adding duplicate seed records.
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
- `scripts/s06-preflight.sh` — Provides the live API/auth/CORS preflight gate with readable failure guidance and an auth-limited partial-pass path.
|
||||
- `scripts/s06-acceptance-data.sh` — Seeds or refreshes the deterministic acceptance fixture through the live API and prints readiness/reminder output.
|
||||
- `scripts/s06-acceptance-data.test.sh` — Exercises missing-token, bad-token, and idempotent rerun cases for the acceptance seeding flow.
|
||||
- `scripts/s06-acceptance-run.sh` — Orchestrates preflight, seeding, the integrated trust-loop regression, log capture, and the acceptance document refresh.
|
||||
- `docs/s06-acceptance-run.md` — Records the live S06 acceptance rerun, browser observations, manual-send-boundary evidence, and the remaining Gmail continuity gap.
|
||||
- `.gsd/DECISIONS.md` — Captured S06 environment decisions, including live-API seeding, local JWT fallback, and preflight auth handling.
|
||||
- `.gsd/KNOWLEDGE.md` — Captured the auth-limited preflight behavior and the local admin/JWT rerun pattern for future agents.
|
||||
- `.gsd/PROJECT.md` — Updated project state to reflect S06 completion and the remaining S07 closure focus.
|
||||
@@ -0,0 +1,209 @@
|
||||
# S06: Live environment stabilization and integrated acceptance rerun — UAT
|
||||
|
||||
**Milestone:** M001
|
||||
**Written:** 2026-03-27T08:29:02.335Z
|
||||
|
||||
# S06 UAT — Live environment stabilization and integrated acceptance rerun
|
||||
|
||||
## Goal
|
||||
|
||||
Prove that the real localhost environment can be started, preflighted, seeded with acceptance-ready data, and used to rerun the integrated daily loop for the deterministic acceptance fixture without crossing the manual-send boundary.
|
||||
|
||||
The concrete fixture for this slice is:
|
||||
|
||||
- Company: `S06 Acceptance Labs`
|
||||
- Job: `S06 Acceptance Backend Engineer`
|
||||
- Expected workflow state: `Follow up`, `Ready`, `Waiting 14d`
|
||||
|
||||
## Preconditions
|
||||
|
||||
1. Backend is running at `http://localhost:5202` and frontend is running at `http://localhost:3000`.
|
||||
2. The worktree contains the S06 scripts and `docs/s06-acceptance-run.md`.
|
||||
3. If running the seed script directly, a valid bearer token is available in `AUTH_TOKEN`.
|
||||
4. If running only `bash scripts/s06-acceptance-run.sh`, the default localhost dev JWT fallback is allowed to mint a local token from the checked-in dev JWT settings plus the local SQLite admin user.
|
||||
5. Do **not** click `Send And Log Email` unless outbound mail is intentionally pointed at a safe sink.
|
||||
|
||||
---
|
||||
|
||||
## Test Case 1 — Preflight catches the real environment state before browser work
|
||||
|
||||
### Steps
|
||||
|
||||
1. Run `bash scripts/s06-preflight.sh`.
|
||||
2. Review the printed readiness lines.
|
||||
|
||||
### Expected
|
||||
|
||||
- The script prints `Preflight target: http://localhost:5202/api`.
|
||||
- The script prints the required origin pair `UI http://localhost:3000 -> API http://localhost:5202/api`.
|
||||
- The script reports `auth.requireAuth=true` and the auth config surface is reachable.
|
||||
- If `/api/admin/system` is not called with an admin token, the script still exits successfully with the guided partial-pass message instead of failing ambiguously.
|
||||
|
||||
### Edge checks
|
||||
|
||||
- If the API is down or `API_BASE` is wrong, the script exits non-zero with a clear start-the-API hint.
|
||||
- If the API returns malformed JSON, the script prints the raw body and fails.
|
||||
|
||||
---
|
||||
|
||||
## Test Case 2 — Acceptance seeding produces the deterministic live fixture
|
||||
|
||||
### Steps
|
||||
|
||||
1. Export a valid token to `AUTH_TOKEN`.
|
||||
2. Run `bash scripts/s06-acceptance-data.sh`.
|
||||
3. Review the seed summary output.
|
||||
4. Run the script a second time.
|
||||
|
||||
### Expected
|
||||
|
||||
- The script prints `seed.result=success`.
|
||||
- The script prints stable `seed.company.id` / `seed.job.id` values and does not create duplicate jobs on rerun.
|
||||
- The script prints `seed.workflow.action=follow-up`.
|
||||
- The script prints `seed.readiness.level=Ready`.
|
||||
- The script prints `seed.reminders=Waiting 14d`.
|
||||
- The job has saved Tailored CV / package state and recruiter-thread correspondence prepared for later browser verification.
|
||||
|
||||
### Edge checks
|
||||
|
||||
- Running without `AUTH_TOKEN` fails immediately with guidance.
|
||||
- Running with a bad token fails clearly as an auth issue.
|
||||
- Re-running the seed does not create duplicate deterministic correspondence for the same external message id.
|
||||
|
||||
---
|
||||
|
||||
## Test Case 3 — The acceptance runner refreshes the artifact and keeps evidence on disk
|
||||
|
||||
### Steps
|
||||
|
||||
1. Run `bash scripts/s06-acceptance-run.sh`.
|
||||
2. Confirm `docs/s06-acceptance-run.md` exists and is non-empty.
|
||||
3. Open the generated markdown and review the shell summary table.
|
||||
|
||||
### Expected
|
||||
|
||||
- The runner reports `acceptance.result=pass`.
|
||||
- The runner records `Preflight`, `Seed acceptance data`, and `UI trust-loop test` as pass states.
|
||||
- The markdown contains a current run id, timestamp, auth-token-source category, and log paths under `docs/artifacts/s06-acceptance/logs/`.
|
||||
- The guided browser section remains present after rerun and is not overwritten by the shell refresh.
|
||||
|
||||
### Edge checks
|
||||
|
||||
- If preflight fails because the backend is unreachable, the runner exits non-zero and records the failure instead of proceeding.
|
||||
- If Gmail is not configured, the document calls that out as a live limitation rather than pretending Gmail continuity was proven.
|
||||
|
||||
---
|
||||
|
||||
## Test Case 4 — `/jobs` opens the seeded workspace with saved package state
|
||||
|
||||
### Steps
|
||||
|
||||
1. Open `http://localhost:3000/jobs` in the live app.
|
||||
2. Locate the row for `S06 Acceptance Labs • S06 Acceptance Backend Engineer`.
|
||||
3. Confirm the row shows `Follow up`, `CV ready`, and `Waiting` style signals.
|
||||
4. Open the job workspace from that row.
|
||||
5. Go to **Tailored CV**.
|
||||
|
||||
### Expected
|
||||
|
||||
- The workspace opens for the seeded job, not a different row.
|
||||
- The Tailored CV area contains the saved seeded text beginning `Saved acceptance tailored CV highlighting ASP.NET Core delivery...`.
|
||||
- The saved package state is visible in the real workspace rather than only in test data or logs.
|
||||
|
||||
### Edge checks
|
||||
|
||||
- Re-opening the same job should show the same saved package state; it should not disappear or duplicate on revisit.
|
||||
|
||||
---
|
||||
|
||||
## Test Case 5 — Follow-up drafting stays manual and does not auto-send
|
||||
|
||||
### Steps
|
||||
|
||||
1. From the same seeded job workspace, open **Follow up**.
|
||||
2. Wait for the draft to load or regenerate it if needed.
|
||||
3. Review the available actions.
|
||||
4. Inspect the network log if available.
|
||||
5. Stop **before** clicking `Send And Log Email`.
|
||||
|
||||
### Expected
|
||||
|
||||
- The follow-up draft loads successfully from the live backend.
|
||||
- The UI shows separate `Copy Draft` and `Send And Log Email` actions.
|
||||
- Draft loading/regeneration calls `GET /api/jobapplications/{id}/followup-draft`.
|
||||
- No `POST /api/jobapplications/{id}/send-followup` request occurs during draft review/regeneration alone.
|
||||
- The manual-send boundary remains explicit and intact.
|
||||
|
||||
### Edge checks
|
||||
|
||||
- Editing or regenerating the draft should not add a sent item to correspondence by itself.
|
||||
- If recruiter contact data is incomplete, drafting may still work while send remains the explicit guarded action.
|
||||
|
||||
---
|
||||
|
||||
## Test Case 6 — `/reminders` and `/dashboard` reflect the same seeded job coherently
|
||||
|
||||
### Steps
|
||||
|
||||
1. Open `http://localhost:3000/reminders`.
|
||||
2. Find the seeded job under the follow-up grouping.
|
||||
3. Confirm the job shows `Follow up`, `Waiting 14d`, and `Follow-up: 10/03/2026`.
|
||||
4. Open `http://localhost:3000/dashboard`.
|
||||
5. Confirm the dashboard analytics include the seeded job/company state.
|
||||
6. Reload `/dashboard` and review browser diagnostics.
|
||||
|
||||
### Expected
|
||||
|
||||
- `/reminders` shows the same seeded job that was opened from `/jobs`.
|
||||
- `/dashboard` includes `S06 Acceptance Labs` in the activity/company view.
|
||||
- The dashboard reload completes without console errors or failed network requests.
|
||||
- The app behaves as one coherent single-user loop across all three surfaces.
|
||||
|
||||
### Edge checks
|
||||
|
||||
- If the job is missing from `/reminders`, the seed dates may no longer be beyond the active follow-up threshold and should be rechecked.
|
||||
- If `/dashboard` loads but records failed requests, treat the slice as not stabilized.
|
||||
|
||||
---
|
||||
|
||||
## Test Case 7 — Gmail continuity status is reported honestly
|
||||
|
||||
### Steps
|
||||
|
||||
1. In the seeded job workspace, open **Correspondence**.
|
||||
2. Confirm the deterministic recruiter-thread message is present.
|
||||
3. Check whether the workspace exposes connected Gmail state and whether any linked-thread refresh request runs.
|
||||
4. Compare the observation with `docs/s06-acceptance-run.md`.
|
||||
|
||||
### Expected
|
||||
|
||||
- The recruiter-thread message seeded by S06 is visible.
|
||||
- If Gmail is connected in the environment, a linked-thread refresh can be observed and reported.
|
||||
- If Gmail is **not** connected, the acceptance artifact explicitly records that Gmail continuity was not proven live in this run.
|
||||
|
||||
### Edge checks
|
||||
|
||||
- Do not claim success for Gmail continuity merely because seeded correspondence is present.
|
||||
- Absence of `POST /api/gmail/refresh-linked-threads` in the live run means the slice only proved seeded correspondence visibility, not live Gmail refresh.
|
||||
|
||||
---
|
||||
|
||||
## Pass Criteria
|
||||
|
||||
S06 passes when all of the following are true:
|
||||
|
||||
- The localhost stack is startable on the expected UI/API origins.
|
||||
- Preflight provides a readable go/no-go result instead of failing with opaque CORS/runtime symptoms.
|
||||
- The deterministic acceptance fixture can be seeded repeatably without duplicate drift.
|
||||
- The seeded job appears coherently across `/jobs`, the workspace, `/reminders`, and `/dashboard`.
|
||||
- Follow-up drafting remains manual and does not auto-send.
|
||||
- `docs/s06-acceptance-run.md` contains current shell evidence and honest browser observations, including any remaining Gmail continuity limitation.
|
||||
|
||||
## Failure Clues
|
||||
|
||||
- `scripts/s06-preflight.sh` fails because the API is unreachable or returns malformed JSON.
|
||||
- Seeding creates duplicate fixture data or no longer lands in `follow-up` / `Waiting 14d` state.
|
||||
- `/jobs`, workspace, `/reminders`, and `/dashboard` disagree about the seeded job’s next action.
|
||||
- Opening or regenerating a follow-up draft triggers a send request.
|
||||
- The acceptance artifact hides Gmail configuration limitations instead of recording them.
|
||||
- Dashboard reload still produces console errors or failed requests.
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"taskId": "T03",
|
||||
"unitId": "M001/S06/T03",
|
||||
"timestamp": 1774599867411,
|
||||
"passed": true,
|
||||
"discoverySource": "task-plan",
|
||||
"checks": [
|
||||
{
|
||||
"command": "bash scripts/s06-acceptance-run.sh",
|
||||
"exitCode": 0,
|
||||
"durationMs": 5549,
|
||||
"verdict": "pass"
|
||||
},
|
||||
{
|
||||
"command": "test -s docs/s06-acceptance-run.md",
|
||||
"exitCode": 0,
|
||||
"durationMs": 5,
|
||||
"verdict": "pass"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user