chore(M001/S05): auto-commit after complete-slice

This commit is contained in:
2026-03-24 14:42:09 +01:00
parent c0e2c636df
commit aa325ac7ba
9 changed files with 385 additions and 80 deletions
@@ -0,0 +1,118 @@
# S05 Summary — End-to-end trust and workflow polish
## Slice Outcome
S05 completed the final trust-loop assembly for M001. The slice did not add a second workflow; it tightened the existing one so `/jobs`, `/dashboard`, `/reminders`, and the job workspace now describe the same next action, reuse the same saved package state, expose Gmail linked-thread continuity clearly, and keep follow-up drafting separate from any outbound send action.
In practice, this slice turned the milestone from a set of individually working subsystems into one coherent daily-use loop:
- overview surfaces route into the same workspace semantics
- saved package material is treated as explicit reusable workflow state
- linked Gmail thread refresh is visible in the workspace instead of hidden behind import-only UI
- grounded follow-up drafting remains available without crossing the manual-send boundary
## What This Slice Actually Delivered
### 1. Shared workflow trust/action model
S05 centralized workflow trust signals across backend DTOs and frontend routing helpers so overview surfaces no longer guess from free-form `followUpReason` text or raw `notes` presence.
Delivered pattern:
- backend reminders/readiness return normalized `workflowSignal` metadata
- frontend consumes that contract through `job-tracker-ui/src/jobWorkflowSignals.ts`
- `JobTable`, `DashboardView`, and `RemindersView` route from the same source of truth into the existing `/jobs?open=...&tab=...` workspace entry model
This is the main coherence pattern future slices should preserve: if a new daily-loop surface needs a next action, it should consume `workflowSignal`, not invent another heuristic.
### 2. Explicit saved-package trust in the workspace
The Tailored CV workspace now makes the saved-package chain obvious:
- tailored CV, cover letter, application answer, and recruiter message each show save state
- the UI explicitly says saved package material feeds follow-up drafting
- the saved working-material panel shows what later workflow steps can trust and reuse
This matters because S02 already established package persistence, but S05 made that persistence legible as workflow state rather than hidden implementation detail.
### 3. Visible Gmail continuity state in the correspondence workspace
S05 surfaced linked-thread continuity directly in `Correspondence.tsx`.
The workspace now shows:
- Gmail connection state
- linked-thread count
- explicit linked-thread refresh action
- last refresh outcome
That makes the S01 continuity work inspectable in the same workspace where the user reviews correspondence, rather than requiring them to infer freshness from the Gmail import modal alone.
### 4. Integrated trust-loop regression
S05 added `job-tracker-ui/src/end-to-end-trust-loop.test.tsx` as the integrated proof for the slice. The test starts from an overview entry point and verifies the assembled path in one place:
1. open the job from an overview action
2. confirm saved package material is already present
3. confirm linked-thread refresh updates correspondence without re-importing the thread
4. confirm the follow-up draft is grounded in saved package + correspondence context
5. confirm drafting/regeneration does not trigger send behavior
This is now the best single regression to read when future work risks breaking the milestones core loop.
## Patterns Established
- **Workflow actions come from normalized workflow signals.** Do not parse `followUpReason` strings or generic `notes` content in overview surfaces.
- **Saved package state is explicit workflow state.** Future slices should continue treating tailored CV / cover letter / application answer / recruiter message as reusable job-scoped material.
- **Continuity status belongs in the main workspace.** If refresh or sync trust matters, expose its state where the user does the work.
- **Integrated proof should start from an overview surface.** Final-loop regressions should validate real entry routing, not isolated component state only.
- **Manual-send boundary must stay explicit.** Draft generation/regeneration and outbound send must remain visibly separate.
## Verification Run
All slice-plan command checks passed in this worktree.
### Backend
- `~/.gsd/agent/bin/dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --filter JobApplicationsWorkflowSignalsTests`
### Frontend tests
- `cd job-tracker-ui && CI=true ./node_modules/.bin/react-scripts test --watch=false --runTestsByPath src/workflow-trust-signals.test.tsx`
- `cd job-tracker-ui && CI=true ./node_modules/.bin/react-scripts test --watch=false --runTestsByPath src/end-to-end-trust-loop.test.tsx`
- `cd job-tracker-ui && CI=true ./node_modules/.bin/react-scripts 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`
### Build
- `cd job-tracker-ui && CI=true ./node_modules/.bin/react-scripts build`
## Observability / Diagnostic Surfaces Confirmed
The slice-plan observability surfaces are in place and useful:
- `GET /api/jobapplications/reminders`
- `GET /api/jobapplications/{id}/readiness`
- `GET /api/jobapplications/{id}/followup-draft`
- `GET /api/correspondence/{jobId}`
- `POST /api/gmail/refresh-linked-threads`
- `job-tracker-ui/src/jobWorkflowSignals.ts`
- `job-tracker-ui/src/workflow-trust-signals.test.tsx`
- `job-tracker-ui/src/end-to-end-trust-loop.test.tsx`
Backend tests proved normalized workflow-signal behavior. Frontend tests proved overview routing consistency and integrated trust-loop behavior. A live browser check also confirmed the app shell renders, but the current environment still has a CORS/runtime mismatch on `http://localhost:5202/api/...`, so full live UAT depends on running the backend with the expected CORS behavior.
## Requirement Impact
- **R010** is now validated. S05 proved coherent history and action continuity across overview routing, saved package reuse, linked Gmail updates, and follow-up drafting using one shared workflow contract.
- **R008** remains active by design. S05 re-proved the manual-send boundary, but the requirement stays active as an ongoing product constraint rather than a one-time feature box.
## Decisions / Gotchas Worth Carrying Forward
- Saved application answers should remain explicit workflow state, not inferred from generic notes.
- Linked-thread refresh state should stay visible in the main correspondence workspace.
- In this CRA frontend, run `react-scripts` from `job-tracker-ui/`; invoking via `npm --prefix ...` from repo root can mis-resolve the app directory and fail looking for a root-level `package.json`.
- Browser UAT still requires a correctly configured backend on port `5202`; otherwise the UI shell loads with CORS failures and empty data surfaces.
## What The Next Slice / Milestone Should Know
M001 is now assembled as one coherent single-user loop. Future work should build on the shared `workflowSignal` contract and the integrated trust-loop regression instead of adding new routing heuristics or duplicate readiness logic. If a later slice changes reminders, workspace entry, Gmail continuity, or follow-up drafting, it should update both the focused workflow-signal tests and the integrated trust-loop test together.