chore: auto-commit after execute-task

GSD-Unit: M001/S06/T01
This commit is contained in:
2026-03-27 08:54:34 +01:00
parent 7a44ebbd77
commit bdc47dde7f
31 changed files with 2017 additions and 966 deletions
+5 -66
View File
@@ -1,73 +1,12 @@
# S05: End-to-end trust and workflow polish
**Goal:** Prove the full daily-use loop as one trustworthy workflow by tightening shared next-action/readiness signals, then validating overview → workspace → package → Gmail continuity → follow-up behavior without weakening the manual-send boundary.
**Demo:** Starting from the table, dashboard, or reminders, the user can open the same job workspace, see trustworthy action/readiness cues, reuse saved package state, refresh linked Gmail correspondence on that job, generate a grounded follow-up draft, and confirm that no recruiter email is sent unless the user explicitly chooses the send/log action.
S05 does not newly own an active requirement, but it is the milestone slice that must **support and re-prove active requirements R008 and R010 together**. R008 matters because `POST /api/jobapplications/{id}/send-followup` is a real outbound boundary and the final loop must keep that action explicitly manual. R010 matters because the remaining milestone risk is heuristic drift: table, dashboard, reminders, workspace readiness, Gmail continuity, and follow-up drafting can each work alone while still feeling like separate systems.
The work is grouped into two tasks because the slice has two different risks. First, the workflow needs one shared trust/action model so the overview surfaces stop guessing from free-form `followUpReason` text or raw `notes` presence. Second, the milestone still needs one integrated proof path that exercises the real loop end to end and only polishes the UI where that proof exposes ambiguity. Doing contract/polish first and integrated proof second keeps the task count small while making sure every task delivers user-visible progress.
## Must-Haves
- Table, dashboard, reminders, and workspace readiness use a shared workflow trust model instead of drifting string/notes heuristics.
- The job workspace clearly preserves the saved-package → Gmail-correspondence → follow-up-draft chain for one job.
- Final proof exercises the full loop without auto-sending email or inventing a second workflow.
## Proof Level
- This slice proves: final-assembly
- Real runtime required: yes
- Human/UAT required: yes
## Verification
- `dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --filter JobApplicationsWorkflowSignalsTests`
- `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/workflow-trust-signals.test.tsx`
- `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/end-to-end-trust-loop.test.tsx`
- `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/correspondence-gmail-import.test.tsx src/job-details-generated-drafts.test.tsx src/job-details-followup-drafts.test.tsx src/daily-control-loop.test.tsx`
- `CI=true npm --prefix job-tracker-ui run build`
- Browser UAT: from `/jobs`, `/dashboard`, and `/reminders`, open the same job workspace, confirm saved package material is reused in follow-up drafting, confirm linked-thread refresh shows new correspondence without thread re-import, and stop before `send-followup` unless the environment is configured to a safe sink/stub.
- Failure-path check: the integrated UI regression must prove that follow-up drafting remains available without triggering `/jobapplications/{id}/send-followup`, and the focused workflow-signal tests must fail if overview surfaces drift from the shared routing/readiness contract.
## Observability / Diagnostics
- Runtime signals: explicit workflow trust/action fields for overview surfaces, workspace readiness state, linked-thread refresh status, and follow-up grounding/manual-send affordances.
- Inspection surfaces: `GET /api/jobapplications/reminders`, `GET /api/jobapplications/{id}/readiness`, `GET /api/jobapplications/{id}/followup-draft`, `GET /api/correspondence/{jobId}`, `job-tracker-ui/src/jobWorkflowSignals.ts`, and the focused/integrated UI tests.
- Failure visibility: broken action routing, stale package-readiness inference, missing Gmail continuity state, or accidental send coupling should surface as failing targeted tests and as incorrect workspace state during browser UAT.
- Redaction constraints: do not add logs that expose private correspondence bodies, recruiter email contents, or secret Gmail/auth configuration.
## Integration Closure
- Upstream surfaces consumed: `JobTrackerApi/Controllers/JobApplicationsController.cs`, `JobTrackerApi/Controllers/GmailController.cs`, `job-tracker-ui/src/components/JobTable.tsx`, `job-tracker-ui/src/components/DashboardView.tsx`, `job-tracker-ui/src/components/RemindersView.tsx`, `job-tracker-ui/src/components/JobDetailsDialog.tsx`, `job-tracker-ui/src/components/Correspondence.tsx`, and the existing focused tests from S01-S04.
- New wiring introduced in this slice: one shared workflow-signal contract/helper for overview routing and readiness, plus one integrated trust-loop regression that composes package persistence, Gmail continuity, and grounded follow-up drafting in the same workspace path.
- What remains before the milestone is truly usable end-to-end: nothing beyond running the final live-safe browser/UAT loop against real configured services.
**Demo:** After this: The full loop works cleanly in a real environment: import job → generate package → apply externally → import/update correspondence automatically from linked Gmail threads → draft follow-up/reply → track progress confidently.
## Tasks
- [x] **T01: Centralize workflow trust signals across overview and readiness surfaces** `est:5h`
- Why: S05 cannot prove coherence while table, dashboard, reminders, and readiness still infer next actions from separate brittle rules.
- Files: `JobTrackerApi/Controllers/JobApplicationsController.cs`, `JobTrackerApi.Tests/JobApplicationsWorkflowSignalsTests.cs`, `job-tracker-ui/src/types.ts`, `job-tracker-ui/src/jobWorkflowSignals.ts`, `job-tracker-ui/src/components/JobTable.tsx`, `job-tracker-ui/src/components/DashboardView.tsx`, `job-tracker-ui/src/components/RemindersView.tsx`, `job-tracker-ui/src/workflow-trust-signals.test.tsx`
- Do: add explicit workflow trust/action fields or normalized routing metadata at the controller/DTO layer, introduce a shared UI helper that consumes those fields instead of parsing free-form strings or raw `notes`, and update table/dashboard/reminders to route from the same source of truth without breaking the existing shared `/jobs?open=...&tab=...` workspace entry pattern.
- [x] **T01: Centralize workflow trust signals across overview and readiness surfaces**
- Files: JobTrackerApi/Controllers/JobApplicationsController.cs, JobTrackerApi.Tests/JobApplicationsWorkflowSignalsTests.cs, job-tracker-ui/src/types.ts, job-tracker-ui/src/jobWorkflowSignals.ts, job-tracker-ui/src/components/JobTable.tsx, job-tracker-ui/src/components/DashboardView.tsx, job-tracker-ui/src/components/RemindersView.tsx, job-tracker-ui/src/workflow-trust-signals.test.tsx
- Verify: `dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --filter JobApplicationsWorkflowSignalsTests` and `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/workflow-trust-signals.test.tsx`
- Done when: the overview surfaces and readiness logic describe the same next action for the same job without depending on ad-hoc string matching or treating all `notes` content as generic package readiness.
- [x] **T02: Add integrated trust-loop proof and workspace polish** `est:5h`
- Why: the milestone still needs one trustworthy proof path that composes the existing package, Gmail, and follow-up slices and exposes any remaining trust gaps in the real workspace.
- Files: `job-tracker-ui/src/components/JobDetailsDialog.tsx`, `job-tracker-ui/src/components/Correspondence.tsx`, `job-tracker-ui/src/end-to-end-trust-loop.test.tsx`, `job-tracker-ui/src/daily-control-loop.test.tsx`, `.gsd/milestones/M001/slices/S05/S05-UAT.md`
- Do: add a focused integrated UI regression that starts from an overview entry surface and walks through saved package reuse, linked-thread continuity, and grounded follow-up drafting; patch only the workspace/continuity UI needed to make that path trustworthy and explicit; and capture a live-safe UAT script that preserves the manual-send boundary.
- [x] **T02: Add integrated trust-loop proof and workspace polish**
- Files: job-tracker-ui/src/components/JobDetailsDialog.tsx, job-tracker-ui/src/components/Correspondence.tsx, job-tracker-ui/src/end-to-end-trust-loop.test.tsx, job-tracker-ui/src/daily-control-loop.test.tsx, .gsd/milestones/M001/slices/S05/S05-UAT.md
- Verify: `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/end-to-end-trust-loop.test.tsx`, `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/correspondence-gmail-import.test.tsx src/job-details-generated-drafts.test.tsx src/job-details-followup-drafts.test.tsx src/daily-control-loop.test.tsx`, and `CI=true npm --prefix job-tracker-ui run build`
- Done when: one integrated regression proves the end-to-end trust loop, focused regressions still pass, and the live-UAT instructions let a human verify real services without accidentally sending recruiter email.
## Files Likely Touched
- `JobTrackerApi/Controllers/JobApplicationsController.cs`
- `JobTrackerApi.Tests/JobApplicationsWorkflowSignalsTests.cs`
- `job-tracker-ui/src/types.ts`
- `job-tracker-ui/src/jobWorkflowSignals.ts`
- `job-tracker-ui/src/components/JobTable.tsx`
- `job-tracker-ui/src/components/DashboardView.tsx`
- `job-tracker-ui/src/components/RemindersView.tsx`
- `job-tracker-ui/src/components/JobDetailsDialog.tsx`
- `job-tracker-ui/src/components/Correspondence.tsx`
- `job-tracker-ui/src/workflow-trust-signals.test.tsx`
- `job-tracker-ui/src/end-to-end-trust-loop.test.tsx`
- `.gsd/milestones/M001/slices/S05/S05-UAT.md`
@@ -2,83 +2,21 @@
id: T01
parent: S05
milestone: M001
provides:
- Shared workflow trust/action signals for overview and readiness surfaces
key_files:
- JobTrackerApi/Controllers/JobApplicationsController.cs
- JobTrackerApi.Tests/JobApplicationsWorkflowSignalsTests.cs
- job-tracker-ui/src/jobWorkflowSignals.ts
- job-tracker-ui/src/components/JobTable.tsx
- job-tracker-ui/src/components/DashboardView.tsx
- job-tracker-ui/src/components/RemindersView.tsx
- job-tracker-ui/src/workflow-trust-signals.test.tsx
key_decisions:
- Treated saved application answers as explicit workflow state via WorkflowSignal instead of inferring package readiness from generic notes text.
patterns_established:
- Overview surfaces must derive routing, labels, and grouping from workflowSignal plus jobWorkflowSignals.ts, not from followUpReason string matching.
observability_surfaces:
- GET /api/jobapplications/reminders
- GET /api/jobapplications/{id}/readiness
- job-tracker-ui/src/jobWorkflowSignals.ts
- job-tracker-ui/src/workflow-trust-signals.test.tsx
- JobTrackerApi.Tests/JobApplicationsWorkflowSignalsTests.cs
duration: 2h 10m
verification_result: passed
completed_at: 2026-03-24T14:02:04+01:00
provides: []
requires: []
affects: []
key_files: []
key_decisions: []
patterns_established: []
drill_down_paths: []
observability_surfaces: []
duration: ""
verification_result: ""
completed_at: 2026-03-27T07:30:18.616Z
blocker_discovered: false
---
# T01: Centralize workflow trust signals across overview and readiness surfaces
**Unified workflow trust signals across the API, table, dashboard, and reminders.**
## What Happened
I verified the local controller and UI code first, found that the backend already had the beginnings of a `WorkflowSignal` contract, and confirmed the remaining drift was on the consumer side: `JobTable`, `DashboardView`, and `RemindersView` still fell back to `followUpReason` parsing or raw `notes`/`tailoredCvText` heuristics.
On the backend, I fixed the broken `RulesEngine.Decision` type references so the controller compiled again, kept the saved-application-answer block parsing as the package-readiness source of truth, and added focused tests proving two things: generic notes do not satisfy saved-answer readiness, and reminders/readiness now expose normalized workflow routing metadata for both package work and follow-up work.
On the frontend, I completed the shared type contract by adding `WorkflowSignal` to `job-tracker-ui/src/types.ts`, extended `ReadinessResponse` to surface that signal, and rewrote `job-tracker-ui/src/jobWorkflowSignals.ts` as the one shared helper for overview routing, labels, and reminder grouping.
I then updated the three overview surfaces to consume that helper directly. `JobTable` now drives urgency chips, primary actions, and the readiness filter from `workflowSignal` instead of raw `notes` or `followUpReason`. `DashboardView` now chooses reminder labels/routes from the same helper. `RemindersView` now groups jobs and opens workspace tabs from `workflowSignal` rather than parsing reason text.
To keep the existing integrated coverage useful, I also updated `src/daily-control-loop.test.tsx` to the new contract so the broader slice-level regression continues to validate the overview loop instead of enforcing the old heuristic behavior.
## Verification
I ran the focused T01 backend and frontend checks from the task plan and both passed. I also ran the slice-level verification commands relevant at this stage: the broader focused UI regression bundle now passes, the production build passes, and the only remaining slice-level failure is the missing `src/end-to-end-trust-loop.test.tsx`, which belongs to T02 and is expected for this intermediate task.
## Verification Evidence
| # | Command | Exit Code | Verdict | Duration |
|---|---------|-----------|---------|----------|
| 1 | `dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --filter JobApplicationsWorkflowSignalsTests` | 0 | ✅ pass | 3.62s |
| 2 | `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/workflow-trust-signals.test.tsx` | 0 | ✅ pass | 3.37s |
| 3 | `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/end-to-end-trust-loop.test.tsx` | 1 | ❌ fail | 0.62s |
| 4 | `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/correspondence-gmail-import.test.tsx src/job-details-generated-drafts.test.tsx src/job-details-followup-drafts.test.tsx src/daily-control-loop.test.tsx` | 0 | ✅ pass | 4.62s |
| 5 | `CI=true npm --prefix job-tracker-ui run build` | 0 | ✅ pass | 12.73s |
## Diagnostics
Inspect `GET /api/jobapplications/reminders` and `GET /api/jobapplications/{id}/readiness` to confirm `workflowSignal.actionKey`, `workspaceTab`, `followMode`, and package/interview/follow-up booleans. On the UI side, inspect `job-tracker-ui/src/jobWorkflowSignals.ts` and run `src/workflow-trust-signals.test.tsx` to catch any routing/grouping drift. Failures now surface as deterministic targeted test failures instead of silent string-parsing mismatches.
## Deviations
I also corrected a pre-existing controller compile issue (`RulesEngine.Decision` vs. `FollowUpDecision`) and updated the existing `src/daily-control-loop.test.tsx` regression so it validates the new shared workflow contract instead of the retired heuristic behavior.
## Known Issues
- `src/end-to-end-trust-loop.test.tsx` does not exist yet, so that slice-level verification command still fails until T02 adds the integrated trust-loop proof.
- The React test runs emit React Router future-flag warnings, but they are warnings only and did not affect pass/fail outcomes.
## Files Created/Modified
- `JobTrackerApi/Controllers/JobApplicationsController.cs` — fixed the follow-up decision type usage while preserving and exposing the normalized workflow signal contract.
- `JobTrackerApi.Tests/JobApplicationsWorkflowSignalsTests.cs` — added focused backend proofs for package-gap vs. generic-notes handling and normalized reminder routing metadata.
- `job-tracker-ui/src/types.ts` — added the shared `WorkflowSignal` type and extended readiness responses to carry it.
- `job-tracker-ui/src/jobWorkflowSignals.ts` — centralized workflow routing, labels, and reminder grouping for overview surfaces.
- `job-tracker-ui/src/components/JobTable.tsx` — switched next-action chips/buttons and readiness filtering to the shared workflow signal.
- `job-tracker-ui/src/components/DashboardView.tsx` — switched reminder labels/routes to the shared workflow signal helper.
- `job-tracker-ui/src/components/RemindersView.tsx` — switched grouping and open-action routing to workflow signal metadata.
- `job-tracker-ui/src/workflow-trust-signals.test.tsx` — added focused frontend regression coverage proving overview surfaces stay aligned.
- `job-tracker-ui/src/daily-control-loop.test.tsx` — updated the broader loop regression to the shared workflow contract.
No summary recorded.
@@ -2,76 +2,21 @@
id: T02
parent: S05
milestone: M001
provides:
- Integrated trust-loop regression covering overview entry, saved package reuse, linked Gmail continuity, and grounded follow-up drafting
key_files:
- job-tracker-ui/src/end-to-end-trust-loop.test.tsx
- job-tracker-ui/src/components/JobDetailsDialog.tsx
- job-tracker-ui/src/components/Correspondence.tsx
- .gsd/milestones/M001/slices/S05/S05-UAT.md
key_decisions:
- Exposed linked-thread refresh status directly in the correspondence workspace instead of hiding continuity feedback inside the Gmail import modal.
patterns_established:
- Integrated workflow proof should open the real job workspace from an overview action, then verify package reuse, correspondence continuity, and follow-up draft/manual-send separation in one test.
observability_surfaces:
- job-tracker-ui/src/end-to-end-trust-loop.test.tsx
- job-tracker-ui/src/components/JobDetailsDialog.tsx
- job-tracker-ui/src/components/Correspondence.tsx
- .gsd/milestones/M001/slices/S05/S05-UAT.md
- GET /api/jobapplications/{id}/followup-draft
- GET /api/correspondence/{jobId}
- POST /api/gmail/refresh-linked-threads
duration: 33m
verification_result: passed
completed_at: 2026-03-24T14:35:40+01:00
provides: []
requires: []
affects: []
key_files: []
key_decisions: []
patterns_established: []
drill_down_paths: []
observability_surfaces: []
duration: ""
verification_result: ""
completed_at: 2026-03-27T07:30:18.617Z
blocker_discovered: false
---
# T02: Add integrated trust-loop proof and workspace polish
**Added an end-to-end trust-loop regression, surfaced saved-package and Gmail continuity trust state in the workspace, and documented a live-safe UAT runbook.**
## What Happened
I verified the existing S01-S04 tests and workspace code first, then added a new focused React regression at `job-tracker-ui/src/end-to-end-trust-loop.test.tsx` that starts from the real `/jobs` overview action path and proves the composed loop in one place: open the workspace from the overview, confirm saved package material is already present, confirm linked Gmail thread refresh brings in new correspondence without re-importing the thread, and confirm the grounded follow-up draft remains available without calling `send-followup`.
To make that integrated path trustworthy in the actual UI, I limited code changes to the two planned components. In `JobDetailsDialog.tsx`, I tightened the package-reuse copy and added an explicit manual-send boundary panel in the follow-up workspace so draft generation/regeneration cannot be mistaken for sending. In `Correspondence.tsx`, I added a linked-thread continuity panel to the main workspace so Gmail connection state, linked-thread count, and last refresh outcome are visible without opening the import modal.
I also wrote `.gsd/milestones/M001/slices/S05/S05-UAT.md` as the live-safe runbook for the final human loop. It tells a human how to verify `/jobs`, `/dashboard`, and `/reminders` against real services while stopping before `Send and log email` unless outbound mail is explicitly pointed at a safe sink/stub.
## Verification
I ran the full slice command suite: the backend workflow-signal tests, the focused workflow-signal React suite, the new integrated trust-loop regression, the existing Gmail/package/follow-up/daily-loop bundle, and the production build. All command-based verification passed.
I also attempted a real browser sanity pass by starting the local UI and navigating to `http://localhost:3000/jobs`. The browser reached the app shell, but the live verification could not proceed because an already-running process on port `5202` responded without the expected CORS headers, so the UI could not load API data. I did not treat that as a slice blocker because it is an environment/runtime collision outside the T02 code changes, and the live-safe UAT runbook is now ready for a correctly configured environment.
## Verification Evidence
| # | Command | Exit Code | Verdict | Duration |
|---|---------|-----------|---------|----------|
| 1 | `dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --filter JobApplicationsWorkflowSignalsTests` | 0 | ✅ pass | 4.79s |
| 2 | `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/workflow-trust-signals.test.tsx` | 0 | ✅ pass | 3.85s |
| 3 | `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/end-to-end-trust-loop.test.tsx` | 0 | ✅ pass | 3.58s |
| 4 | `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/correspondence-gmail-import.test.tsx src/job-details-generated-drafts.test.tsx src/job-details-followup-drafts.test.tsx src/daily-control-loop.test.tsx` | 0 | ✅ pass | 6.54s |
| 5 | `CI=true npm --prefix job-tracker-ui run build` | 0 | ✅ pass | 15.55s |
## Diagnostics
Use `job-tracker-ui/src/end-to-end-trust-loop.test.tsx` as the single integrated proof for the slice. Inspect `job-tracker-ui/src/components/JobDetailsDialog.tsx` for the saved-package reuse and manual-send boundary copy, and inspect `job-tracker-ui/src/components/Correspondence.tsx` for linked-thread continuity state. For live verification, follow `.gsd/milestones/M001/slices/S05/S05-UAT.md`. If the real browser flow fails, inspect `GET /api/jobapplications/{id}/followup-draft`, `GET /api/correspondence/{jobId}`, and `POST /api/gmail/refresh-linked-threads` together with browser network/CORS diagnostics.
## Deviations
I did not need to update `job-tracker-ui/src/daily-control-loop.test.tsx` because the shared entry semantics from T01 still held once the integrated regression was added.
## Known Issues
- A live browser sanity attempt against `http://localhost:3000/jobs` was blocked by a pre-existing process bound to port `5202` that did not return the expected CORS headers for `http://localhost:3000`, so the app shell loaded but API-backed job data did not. The code changes in this task were still verified through the full automated command suite.
- React Router future-flag warnings still appear during test runs, but they are warnings only and did not affect pass/fail outcomes.
## Files Created/Modified
- `job-tracker-ui/src/end-to-end-trust-loop.test.tsx` — added the integrated overview → workspace → package reuse → Gmail continuity → follow-up/manual-send regression.
- `job-tracker-ui/src/components/JobDetailsDialog.tsx` — clarified saved-package reuse and added explicit manual-send boundary copy in the follow-up workspace.
- `job-tracker-ui/src/components/Correspondence.tsx` — surfaced linked-thread continuity and last-refresh status directly in the main correspondence workspace.
- `.gsd/milestones/M001/slices/S05/S05-UAT.md` — documented the live-safe final human verification flow and send-safety guardrails.
- `.gsd/milestones/M001/slices/S05/S05-PLAN.md` — marked T02 complete.
No summary recorded.