12 KiB
12 KiB
Decisions Register
| # | When | Scope | Decision | Choice | Rationale | Revisable? | Made By |
|---|---|---|---|---|---|---|---|
| D001 | M001 | scope | Product entry point | External job discovery, then import into the app | The user finds jobs on job sites first; the app begins when a role is imported. | No | collaborative |
| D002 | M001 | pattern | AI action model | Assistive drafting and analysis only; no autonomous sending | The user wants AI help but explicitly does not want auto-send or auto-apply behavior. | No | collaborative |
| D003 | M001 | scope | Primary user | Individual job seeker | The product is designed for individuals managing their own search, not recruiter or team workflows. | Yes — if product direction changes later | collaborative |
| D004 | M001 | pattern | Daily navigation hierarchy | Job table first, then follow-up/dashboard, then individual job workspace | The user explicitly described this as the intended control flow for daily use. | Yes — if real usage disproves the hierarchy | collaborative |
| D005 | M001 | roadmap | First milestone focus | Prioritize Gmail import quality and AI draft quality before broader expansion | The user identified Gmail import and AI drafts as the weakest current areas and the first bar for daily use. | Yes — if execution proves another blocker is more fundamental | collaborative |
| D006 | M001/S02 | workspace-persistence | How the saved application answer draft should persist inside the job workspace before a dedicated field exists | Store the application answer draft in a replaceable notes block and make SaveApplicationDrafts overwrite notes when notes are explicitly provided | The existing append-only notes behavior made the Tailored CV workspace untrustworthy because repeated saves duplicated the application answer indefinitely. A replaceable notes block preserves current schema compatibility while giving the workspace a stable saved/read-back loop for later slices. | Yes | agent |
| D007 | M001/S01 | gmail-continuity | What “good Gmail import” now means for M001 | Treat Gmail import as full-thread continuity: the user must be able to import the whole relevant thread, and already-linked Gmail threads must refresh automatically so later inbound messages and user-sent replies appear on the job without manual re-import. This supersedes the narrower one-time-import interpretation inside D005’s Gmail-import focus. | The user explicitly asked whether the app can bring the whole email thread and automatically show their reply later without re-pulling/importing again. That changes the trust bar from “find and import the right message” to “keep the linked thread current over time,” while still preserving the no-auto-send boundary from D002. | Yes — if Gmail API or product constraints later require a different sync model | human |
| 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 |
| 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 |
| D012 | M001/S05 | workspace-observability | Where linked Gmail thread continuity status should be exposed in the final trust loop | Show linked-thread refresh state directly in the correspondence workspace, including linked thread count and last refresh outcome, instead of hiding continuity feedback inside the Gmail import modal only. | The end-to-end trust loop depends on users being able to verify that already-linked Gmail threads stay current without re-importing. Surfacing continuity state in the main workspace keeps the job timeline trustworthy, supports final UAT, and avoids making thread refresh feel like a hidden one-off import behavior. | Yes | agent |
| D013 | M001/S06/T02 | seeding | How acceptance-ready job data is created for S06 live reruns | Seed the acceptance fixture through the live companies/jobapplications/correspondence API plus the dedicated tailored-cv, application-drafts, and followup endpoints, using deterministic company/title/thread/message identifiers for idempotent reruns. | The slice goal is a repeatable live environment check, so seeding through the same HTTP contract the UI uses proves the real backend surface, keeps package/readiness behavior aligned with production code paths, and avoids brittle direct DB mutations or duplicate correspondence on reruns. | Yes | agent |
| D014 | M001/S06/T03 | acceptance-run | How the S06 live acceptance runner should authenticate seeding and protected UI verification without requiring manual token export every rerun. | Allow the S06 acceptance runner to mint a localhost-only admin JWT from the checked-in dev JWT settings plus the local SQLite admin record when AUTH_TOKEN is missing. | The current DB snapshot contains an admin user but the placeholder development password is not reliable, and the task’s verification command must stay repeatable. A localhost-only signed JWT fallback keeps the run fully local, avoids secret prompts, does not print token material, and still exercises the real protected API/UI paths. | Yes | agent |
| D015 | M001/S06 | environment | S06 preflight auth handling | 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. | S06 needs a repeatable go/no-go gate before browser UAT. The live stack can be healthy even when admin-only diagnostics require an extra token, so the preflight should fail hard only for unreachable/malformed API responses while still surfacing clear AUTH_TOKEN guidance and protecting secrets on shared terminals. | Yes | agent |
| D016 | M001/S07 | uat-artifact | How S07 daily-loop closure should capture acceptance evidence | Keep docs/s06-acceptance-run.md as the canonical execution log and use S07 closure artifacts to summarize/import the cross-surface proof rather than duplicating raw runner output. | S07's job is to prove one seeded job stays coherent across /jobs, workspace, /reminders, and /dashboard while preserving the manual-send boundary. Reusing the S06 runner output as the canonical source keeps reruns idempotent, prevents drift between generated logs and human summary text, and gives downstream slices one stable place for detailed evidence plus one concise dependency summary. | Yes | agent |
| D017 | M005 planning | delivery | How M005 execution should be staged and published | Execute M005 one slice at a time, verify each slice independently, push each slice on its own git branch, then continue to the next slice only after the prior slice is stable. | The CV intelligence/export milestone is high-risk and multi-layered. Slice-by-slice branching and push discipline will keep extraction, tailored draft, and PDF rendering changes reviewable and reduce regression blast radius. | Yes | human |
| D018 | M005 planning | verification | What document corpus should drive universal CV extraction verification | Use the real CV files placed in /home/pi/cvs as a regression corpus for universal extractor work, alongside synthetic/unit fixtures. | A universal CV extractor cannot be validated only against synthetic fixtures. Real CVs with different layouts, OCR quality, and structure are required to test extraction, review UX, and rendering assumptions. | Yes | human |
| D019 | M011/S01 | frontend-platform | How to handle frontend build-tool risk during the initial platform hardening slice | Remediate the direct critical frontend dependency immediately, keep the CRA baseline for the next hardening slice, and defer the broader frontend build-tool migration to a later dedicated implementation step. | The audit showed one critical direct dependency issue (axios) and a large remaining body of transitive risk concentrated behind react-scripts. Upgrading the direct dependency removed the critical finding with low change surface, restored a reproducible local and Docker build baseline, and avoids coupling S02 auth/session work to a framework migration. The remaining CRA transitive debt is still real, but it is now a contained follow-on migration concern rather than an immediate blocker. |
Yes | agent |
| D020 | M011/S02 | authentication | What session transport should replace browser-stored bearer tokens in the frontend and API | Use an HttpOnly cookie-backed app session for the primary local auth path, have the API read the local app JWT from a secure cookie instead of browser storage, keep Google credential exchange server-side, and add CSRF protection for state-changing requests. | The current design stores the app bearer token in localStorage/sessionStorage and attaches it via an Authorization header on every request, which leaves the primary local auth path exposed to XSS-driven token theft. A cookie-backed session keeps the app token out of browser storage, lets the API enforce the local auth path centrally, preserves existing JWT-based authorization semantics on the server, and gives the frontend a cleaner source of truth through /auth/me and explicit unauthorized responses. Adding CSRF protection alongside the cookie keeps state-changing requests safe under the new transport. |
Yes | agent |
| D021 | M011/S03/T01 | frontend-architecture | How to centralize degraded-state handling for the core frontend views in S03. | Use a lightweight shared frontend async-view-state pattern for S03 instead of introducing a new global data-fetching framework in this slice. | The current risk is not lack of a full query library; it is that core views swallow request failures into empty arrays or nulls and then render normal empty states. A small shared abstraction for loading/empty/error/retry state can retire that product risk quickly across the highest-traffic views without broadening S03 into a framework migration or destabilizing the existing app. | Yes | agent |