Files
jobtrackingapp/.gsd/milestones/M001/slices/S03/S03-SUMMARY.md
T

9.0 KiB

id, parent, milestone, provides, requires, affects, key_files, key_decisions, patterns_established, observability_surfaces, drill_down_paths, duration, verification_result, completed_at
id parent milestone provides requires affects key_files key_decisions patterns_established observability_surfaces drill_down_paths duration verification_result completed_at
S03 M001 M001
Context-grounded follow-up drafting that combines imported correspondence, saved application package material, and explicit manual send/log behavior inside the job workspace.
slice provides
S01 Imported correspondence records, linked Gmail thread metadata, and ongoing thread refresh continuity tied to a job.
slice provides
S02 Saved tailored CV, cover letter, recruiter message, and marker-delimited application-answer draft state reused by follow-up drafting.
S04
JobTrackerApi/Controllers/JobApplicationsController.cs
JobTrackerApi.Tests/JobApplicationsFollowUpDraftTests.cs
JobTrackerApi.Tests/JobTrackerApi.Tests.csproj
job-tracker-ui/src/components/JobDetailsDialog.tsx
job-tracker-ui/src/types.ts
job-tracker-ui/src/job-details-followup-drafts.test.tsx
Expose follow-up grounding (`contextSummary`, `contextSignals`, thread subject, and last-correspondence metadata) directly from the backend DTO so the workspace explains why the draft exists instead of inferring context client-side.
Preserve the manual-send boundary by keeping follow-up generation separate from explicit send/log submission.
Assemble thread/package grounding once in the backend and return it as part of the draft contract, then render the same grounding verbatim in the workspace.
Reuse the S02 notes marker block for saved application-answer context instead of inventing a second persistence path for follow-up drafting.
GET /api/jobapplications/{id}/followup-draft
POST /api/jobapplications/{id}/send-followup
GET /api/correspondence/{jobId}
JobTrackerApi.Tests/JobApplicationsFollowUpDraftTests.cs
job-tracker-ui/src/job-details-followup-drafts.test.tsx
.gsd/milestones/M001/slices/S03/tasks/T01-SUMMARY.md
.gsd/milestones/M001/slices/S03/tasks/T02-SUMMARY.md
2-task slice; planned 8h implementation plus closeout verification passed 2026-03-24

S03: Reply and follow-up drafting from real thread context

Follow-up drafting now reuses imported thread history plus saved package material, shows that grounding in the job workspace, and keeps outbound email behind an explicit manual send/log action.

What Happened

S03 closed the gap between the correspondence workspace built in S01 and the saved application package workspace built in S02. Before this slice, follow-up generation mostly behaved like a generic prompt over job summary text. After this slice, JobApplicationsController assembles follow-up context from the latest imported correspondence, recruiter details, saved tailored CV / cover letter / recruiter message material, and the marker-delimited application-answer draft saved in notes. The API now returns not only a draft subject/body, but also the grounding metadata the UI needs to explain why the draft was generated and what informed it.

On the frontend, JobDetailsDialog.tsx now treats follow-up drafting as part of the same per-job working loop rather than a blind compose form. The Follow-up tab shows thread subject, latest sender, context summary, and context signals; keeps the body editable before send; and makes the manual-send boundary explicit in the helper text and button flow. The UI posts the edited draft through the existing send/log endpoint instead of silently dispatching anything.

During closeout, the slice-level backend verification command in the plan was restored as a first-class path by repairing missing framework/package references in JobTrackerApi.Tests/JobTrackerApi.Tests.csproj. That means future agents can use the filtered dotnet test ... --filter JobApplicationsFollowUpDraftTests command directly in this worktree instead of relying on the older isolated harness workaround recorded during task execution.

Net effect: imported correspondence, saved package drafts, and the follow-up compose/send-log loop now form one coherent job-level workspace path. S04 can build overview and urgency surfaces on top of a follow-up flow that is already grounded and manually controlled.

Verification

  • Passed: $HOME/.dotnet/dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --filter JobApplicationsFollowUpDraftTests
  • Passed: CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/job-details-followup-drafts.test.tsx
  • Passed: $HOME/.dotnet/dotnet build JobTrackerApi/JobTrackerApi.csproj
  • Passed: CI=true npm --prefix job-tracker-ui run build
  • Observability surfaces confirmed through code/test contracts:
    • GET /api/jobapplications/{id}/followup-draft now exposes grounding metadata (contextSummary, contextSignals, thread subject, last-correspondence details)
    • POST /api/jobapplications/{id}/send-followup remains the explicit manual send/log boundary
    • GET /api/correspondence/{jobId} remains the authoritative timeline surface for confirming logged outbound follow-up entries

New Requirements Surfaced

  • none

Deviations

The written plan expected the filtered backend command to be the slice-level proof path, but task execution had fallen back to an isolated harness because JobTrackerApi.Tests.csproj was missing required ASP.NET Core / Identity / xUnit references. Closeout repaired the test project so the plan-level verification command now passes directly in this worktree.

Known Limitations

  • The slice materially strengthened follow-up drafting, but it still does not introduce a separate rich reply-specific workflow beyond thread-aware subject/context reuse; deeper reply-mode specialization can still be expanded later if usage demands it.
  • This closeout did not re-run a full live Gmail + browser UAT loop end to end; the trusted evidence for S03 in this worktree is the focused backend/frontend verification plus the production frontend build.
  • Follow-up quality still depends on upstream data quality from S01 and S02: weak imported thread metadata or missing saved package material will reduce how specific the draft can be.

Follow-ups

  • S04 should consume the new follow-up grounding/status signals to show which jobs are ready for follow-up, missing context, or need attention from overview surfaces.
  • S05 should re-run the full live loop with real Gmail continuity plus follow-up drafting to reconfirm milestone trust end to end.

Files Created/Modified

  • JobTrackerApi/Controllers/JobApplicationsController.cs — assembled correspondence-aware follow-up context, exposed draft grounding metadata, and improved fallback/reply-style subject behavior.
  • JobTrackerApi.Tests/JobApplicationsFollowUpDraftTests.cs — added focused backend proof that imported thread state plus saved package material change the follow-up draft.
  • JobTrackerApi.Tests/JobTrackerApi.Tests.csproj — restored missing framework/package references so filtered backend verification commands run directly again.
  • job-tracker-ui/src/components/JobDetailsDialog.tsx — exposed follow-up grounding in the workspace, kept drafts editable, and clarified the manual-send boundary.
  • job-tracker-ui/src/types.ts — added the richer FollowUpDraft contract used by the workspace.
  • job-tracker-ui/src/job-details-followup-drafts.test.tsx — proved the Follow-up tab renders context grounding and only sends/logs after explicit user action.

Forward Intelligence

What the next slice should know

  • S03 made the follow-up flow depend on three upstream context sources at once: imported correspondence, saved package fields, and the marker-delimited application-answer draft in JobApplication.Notes. If S04 wants actionable table/dashboard indicators, it should reuse the backend grounding signals instead of trying to infer readiness from scattered raw fields in the browser.

What's fragile

  • JobApplication.Notes marker parsing for <<<APPLICATION_ANSWER_DRAFT>>> ... <<<END_APPLICATION_ANSWER_DRAFT>>> — if another slice starts appending free-form notes around that block incorrectly, follow-up context quality will silently degrade because saved application-answer reuse depends on parsing that exact marker format.

Authoritative diagnostics

  • GET /api/jobapplications/{id}/followup-draft and JobTrackerApi.Tests/JobApplicationsFollowUpDraftTests.cs — the endpoint payload is the single source of truth for what grounding the backend believes it has, and the focused backend test is the fastest trustworthy check when prompt assembly or DTO shape changes.
  • job-tracker-ui/src/job-details-followup-drafts.test.tsx — this is the most reliable UI-level diagnostic for the manual-send boundary and edited-draft payload because it asserts the exact send/log request body after user edits.

What assumptions changed

  • “The slice may need an isolated backend harness because the filtered test command is not trustworthy.” — no longer true in this worktree; closeout repaired JobTrackerApi.Tests.csproj, so the plan-level filtered backend command now passes directly and should replace the older workaround.