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

This commit is contained in:
2026-03-24 14:05:21 +01:00
parent 95c5a62919
commit 64b4a07cc3
5 changed files with 198 additions and 0 deletions
+1
View File
@@ -16,3 +16,4 @@
| D008 | M001/S01 planning | gmail-sync | How linked Gmail threads stay current in S01 | Use a job-scoped refresh flow over already-imported Gmail thread IDs, triggered from the job workspace/API, instead of building inbox-wide Gmail watch/history cursor infrastructure in M001. | The codebase already persists ExternalThreadId per correspondence and lacks Gmail history/watch infrastructure. Fetching known linked threads for one job keeps scope bounded, fits the single-user workspace model, supports duplicate-safe import of new inbound and sent replies, and creates a trustworthy continuity loop without adding brittle webhook/cursor state before the milestone proves value. | Yes — if real usage shows job-scoped pull refresh is too slow or misses important continuity cases. | agent | | D008 | M001/S01 planning | gmail-sync | How linked Gmail threads stay current in S01 | Use a job-scoped refresh flow over already-imported Gmail thread IDs, triggered from the job workspace/API, instead of building inbox-wide Gmail watch/history cursor infrastructure in M001. | The codebase already persists ExternalThreadId per correspondence and lacks Gmail history/watch infrastructure. Fetching known linked threads for one job keeps scope bounded, fits the single-user workspace model, supports duplicate-safe import of new inbound and sent replies, and creates a trustworthy continuity loop without adding brittle webhook/cursor state before the milestone proves value. | Yes — if real usage shows job-scoped pull refresh is too slow or misses important continuity cases. | agent |
| D009 | M001/S01 closure | gmail-matching | Where Gmail candidate aggregation and ranking logic should live for job-aware import | Keep Gmail query-hit aggregation, dedupe, matched-query traces, and ranking reasons in the backend contract instead of recreating that logic in the React workspace. | The correspondence workspace needs explanatory candidate ranking plus duplicate visibility, and putting the logic in the API keeps one source of truth for scoring/import state while preventing browser-side heuristic drift. | Yes | agent | | D009 | M001/S01 closure | gmail-matching | Where Gmail candidate aggregation and ranking logic should live for job-aware import | Keep Gmail query-hit aggregation, dedupe, matched-query traces, and ranking reasons in the backend contract instead of recreating that logic in the React workspace. | The correspondence workspace needs explanatory candidate ranking plus duplicate visibility, and putting the logic in the API keeps one source of truth for scoring/import state while preventing browser-side heuristic drift. | Yes | agent |
| D010 | M001/S03 closeout | followup-drafting | How follow-up grounding should be exposed to the workspace | Return explicit follow-up grounding fields (`contextSummary`, `contextSignals`, `threadSubject`, and last-correspondence metadata) from the backend DTO instead of making the React workspace infer them client-side. | The slice needed draft trust, not just draft text. Putting grounding signals in the API contract gives the UI a durable explanation surface, keeps thread/package inference in one place with generation logic, and makes backend/frontend tests assert the same source of truth. | Yes | agent | | D010 | M001/S03 closeout | followup-drafting | How follow-up grounding should be exposed to the workspace | Return explicit follow-up grounding fields (`contextSummary`, `contextSignals`, `threadSubject`, and last-correspondence metadata) from the backend DTO instead of making the React workspace infer them client-side. | The slice needed draft trust, not just draft text. Putting grounding signals in the API contract gives the UI a durable explanation surface, keeps thread/package inference in one place with generation logic, and makes backend/frontend tests assert the same source of truth. | Yes | agent |
| D011 | M001/S05 planning | workflow-trust | How S05 should represent daily-loop readiness and next-action state across overview surfaces | Introduce explicit workflow trust/action signals from the backend/UI contract and reuse them across the table, dashboard, reminders, and shared workspace instead of continuing to infer behavior from free-form `followUpReason` strings or raw `notes` presence in each component. | S05 is an end-to-end polish slice where the remaining risk is fragmented trust, not missing subsystems. Centralizing workflow signals avoids heuristic drift between overview surfaces, respects the saved application-answer notes-block constraint, and gives the final integrated regression one source of truth for R010 while preserving the explicit manual-send boundary required by R008. | Yes | agent |
+4
View File
@@ -64,3 +64,7 @@
{"ts":"2026-03-24T12:56:42.956Z","flowId":"374e2aaa-39f6-4f8b-b7e5-d107156397eb","seq":2,"eventType":"dispatch-match","rule":"planning (no research, not S01) → research-slice","data":{"unitType":"research-slice","unitId":"M001/S05"}} {"ts":"2026-03-24T12:56:42.956Z","flowId":"374e2aaa-39f6-4f8b-b7e5-d107156397eb","seq":2,"eventType":"dispatch-match","rule":"planning (no research, not S01) → research-slice","data":{"unitType":"research-slice","unitId":"M001/S05"}}
{"ts":"2026-03-24T12:56:42.962Z","flowId":"374e2aaa-39f6-4f8b-b7e5-d107156397eb","seq":3,"eventType":"unit-start","data":{"unitType":"research-slice","unitId":"M001/S05"}} {"ts":"2026-03-24T12:56:42.962Z","flowId":"374e2aaa-39f6-4f8b-b7e5-d107156397eb","seq":3,"eventType":"unit-start","data":{"unitType":"research-slice","unitId":"M001/S05"}}
{"ts":"2026-03-24T13:00:19.768Z","flowId":"374e2aaa-39f6-4f8b-b7e5-d107156397eb","seq":4,"eventType":"unit-end","data":{"unitType":"research-slice","unitId":"M001/S05","status":"completed","artifactVerified":true},"causedBy":{"flowId":"374e2aaa-39f6-4f8b-b7e5-d107156397eb","seq":3}} {"ts":"2026-03-24T13:00:19.768Z","flowId":"374e2aaa-39f6-4f8b-b7e5-d107156397eb","seq":4,"eventType":"unit-end","data":{"unitType":"research-slice","unitId":"M001/S05","status":"completed","artifactVerified":true},"causedBy":{"flowId":"374e2aaa-39f6-4f8b-b7e5-d107156397eb","seq":3}}
{"ts":"2026-03-24T13:02:04.569Z","flowId":"9a9419e5-3975-4382-a2e4-b1323aa878eb","seq":1,"eventType":"iteration-start","data":{"iteration":1}}
{"ts":"2026-03-24T13:02:04.657Z","flowId":"9a9419e5-3975-4382-a2e4-b1323aa878eb","seq":2,"eventType":"dispatch-match","rule":"planning → plan-slice","data":{"unitType":"plan-slice","unitId":"M001/S05"}}
{"ts":"2026-03-24T13:02:04.662Z","flowId":"9a9419e5-3975-4382-a2e4-b1323aa878eb","seq":3,"eventType":"unit-start","data":{"unitType":"plan-slice","unitId":"M001/S05"}}
{"ts":"2026-03-24T13:05:20.939Z","flowId":"9a9419e5-3975-4382-a2e4-b1323aa878eb","seq":4,"eventType":"unit-end","data":{"unitType":"plan-slice","unitId":"M001/S05","status":"completed","artifactVerified":true},"causedBy":{"flowId":"9a9419e5-3975-4382-a2e4-b1323aa878eb","seq":3}}
@@ -0,0 +1,73 @@
# 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.
## Tasks
- [ ] **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.
- 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.
- [ ] **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.
- 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`
@@ -0,0 +1,60 @@
---
estimated_steps: 4
estimated_files: 8
skills_used:
- aspnet-core
- react-best-practices
- test
---
# T01: Centralize workflow trust signals across overview and readiness surfaces
**Slice:** S05 — End-to-end trust and workflow polish
**Milestone:** M001
## Description
Replace the remaining brittle workflow heuristics with one shared trust/action model so the table, dashboard, reminders, and readiness surfaces all describe the same next step for the same job.
## Steps
1. Audit the current reminder/readiness/action logic in `JobApplicationsController.cs`, `JobTable.tsx`, `DashboardView.tsx`, and `RemindersView.tsx`, with special attention to `followUpReason` string parsing and the saved application-answer notes-block constraint.
2. Add explicit workflow trust/action fields or normalized route metadata to the backend DTOs and cover that behavior in a focused backend test.
3. Introduce a shared UI helper that consumes the new contract and update the overview surfaces to route from it instead of duplicating local heuristics.
4. Add focused frontend coverage proving that the same job produces the same next action across table, dashboard, and reminders.
## Must-Haves
- [ ] The workflow contract distinguishes package-work gaps from follow-up work without treating all `notes` text as generic readiness state.
- [ ] Table, dashboard, and reminders open the shared workspace from one trust/action source of truth.
- [ ] Backend and frontend focused tests fail if workflow signal drift reappears.
## 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`
## Observability Impact
- Signals added/changed: normalized workflow trust/action fields and readiness-derived routing metadata used by overview surfaces.
- How a future agent inspects this: read `JobTrackerApi/Controllers/JobApplicationsController.cs` and `job-tracker-ui/src/jobWorkflowSignals.ts`, then run the focused backend/frontend tests.
- Failure state exposed: mismatched overview actions, package-readiness drift, or fallback to string parsing becomes visible as deterministic test failures instead of silent UI inconsistency.
## Inputs
- `JobTrackerApi/Controllers/JobApplicationsController.cs` — current reminders/readiness logic and DTO shaping.
- `job-tracker-ui/src/components/JobTable.tsx` — current next-action and readiness heuristics.
- `job-tracker-ui/src/components/DashboardView.tsx` — current dashboard reminder routing.
- `job-tracker-ui/src/components/RemindersView.tsx` — current reminders grouping and routing.
- `job-tracker-ui/src/types.ts` — current DTO shapes available to the UI.
## Expected Output
- `JobTrackerApi/Controllers/JobApplicationsController.cs` — explicit workflow trust/action fields or normalized route metadata.
- `JobTrackerApi.Tests/JobApplicationsWorkflowSignalsTests.cs` — backend proof for the normalized workflow contract.
- `job-tracker-ui/src/types.ts` — updated UI contract for the new trust/action fields.
- `job-tracker-ui/src/jobWorkflowSignals.ts` — shared workflow helper used by overview surfaces.
- `job-tracker-ui/src/components/JobTable.tsx` — table actions driven from the shared trust/action model.
- `job-tracker-ui/src/components/DashboardView.tsx` — dashboard attention actions driven from the shared trust/action model.
- `job-tracker-ui/src/components/RemindersView.tsx` — reminders grouping/routing driven from the shared trust/action model.
- `job-tracker-ui/src/workflow-trust-signals.test.tsx` — focused UI proof that overview surfaces stay aligned.
@@ -0,0 +1,60 @@
---
estimated_steps: 4
estimated_files: 5
skills_used:
- react-best-practices
- agent-browser
- test
---
# T02: Add integrated trust-loop proof and workspace polish
**Slice:** S05 — End-to-end trust and workflow polish
**Milestone:** M001
## Description
Compose the milestones existing package, Gmail, and follow-up flows into one integrated UI proof path, then make the smallest workspace polish changes needed so that path feels trustworthy and keeps outbound send explicitly manual.
## Steps
1. Build a focused integrated React test that starts from an overview entry path and exercises package reuse, linked-thread continuity, and grounded follow-up drafting inside the shared workspace.
2. Update `JobDetailsDialog.tsx` and `Correspondence.tsx` only where the integrated proof exposes unclear state, missing trust copy, or continuity ambiguity.
3. Re-run the focused S01-S04 regressions to confirm the integrated path did not break the narrower package, Gmail, follow-up, or daily-loop contracts.
4. Write a live-safe UAT runbook that tells a human how to verify the full loop against real services without triggering accidental recruiter email.
## Must-Haves
- [ ] A single integrated UI regression proves overview → workspace → saved package → linked Gmail thread refresh → grounded follow-up draft.
- [ ] The workspace keeps the manual-send boundary explicit and does not couple draft generation to `send-followup`.
- [ ] A human can run the final live-UAT flow safely using the documented guardrails.
## Verification
- `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`
## Observability Impact
- Signals added/changed: clearer workspace trust state around saved package reuse, linked-thread refresh outcomes, and follow-up draft/manual-send separation.
- How a future agent inspects this: run `src/end-to-end-trust-loop.test.tsx`, inspect `JobDetailsDialog.tsx` and `Correspondence.tsx`, and follow `.gsd/milestones/M001/slices/S05/S05-UAT.md` for live verification.
- Failure state exposed: broken loop composition, stale correspondence continuity, or accidental send coupling surfaces in one integrated test instead of requiring four separate slice tests to infer the regression.
## Inputs
- `job-tracker-ui/src/jobWorkflowSignals.ts` — shared workflow action helper from T01.
- `job-tracker-ui/src/components/JobDetailsDialog.tsx` — package workspace, follow-up drafting, and readiness surfaces.
- `job-tracker-ui/src/components/Correspondence.tsx` — Gmail import and linked-thread continuity workspace.
- `job-tracker-ui/src/daily-control-loop.test.tsx` — current routed overview proof from S04.
- `job-tracker-ui/src/correspondence-gmail-import.test.tsx` — current Gmail continuity proof from S01.
- `job-tracker-ui/src/job-details-generated-drafts.test.tsx` — current package save/reuse proof from S02.
- `job-tracker-ui/src/job-details-followup-drafts.test.tsx` — current follow-up grounding/manual-send proof from S03.
## Expected Output
- `job-tracker-ui/src/components/JobDetailsDialog.tsx` — polished workspace trust state for package reuse and follow-up/manual-send separation.
- `job-tracker-ui/src/components/Correspondence.tsx` — polished linked-thread continuity state used by the integrated loop.
- `job-tracker-ui/src/end-to-end-trust-loop.test.tsx` — integrated UI proof for the full trust loop.
- `job-tracker-ui/src/daily-control-loop.test.tsx` — updated overview proof if the shared trust-loop entry semantics change.
- `.gsd/milestones/M001/slices/S05/S05-UAT.md` — live-safe end-to-end verification runbook.