feat: complete release readiness work #28
@@ -3,10 +3,11 @@
|
||||
Updated: 2026-08-09
|
||||
|
||||
- Progress report: `docs/verification/mail-001-job-email-hub.md`
|
||||
- Commands/results: `docs/audits/verification-log.md` V-126–V-131
|
||||
- Commands/results: `docs/audits/verification-log.md` V-126–V-132
|
||||
- Hub/legacy-route tests: `job-tracker-ui/src/correspondence-inbox-page.test.tsx`
|
||||
- Reused review decision tests: `job-tracker-ui/src/gmail-review-page.test.tsx`
|
||||
- Provider-neutral API tests: `JobTrackerApi.Tests/EmailControllerTests.cs`
|
||||
- Saved-copy/tenant tests: `JobTrackerApi.Tests/CorrespondenceControllerTests.cs`
|
||||
- Implementation commits: `6008b4a`, `536d403`, `a20775c`
|
||||
- Send-ledger tests: `JobTrackerApi.Tests/EmailSendAttemptStoreTests.cs`
|
||||
- Implementation commits: `6008b4a`, `536d403`, `a20775c`, `653f011`
|
||||
- Mocked provider data only; no real email, provider connection, private content, production service or external request was used.
|
||||
|
||||
@@ -163,3 +163,4 @@ Output was reduced to filenames and commit counts. The token artifact appears un
|
||||
| V-129 | Bounded `rg`/`Get-Content` of `IEmailProvider`, Gmail/Graph/IMAP services/scopes/controllers, correspondence model/controller and follow-up draft/send path | Repository root | Revalidate provider capabilities and every existing send boundary before MAIL-001 design | PASS/PARTIAL — the neutral provider seam is registered but previously consumed only by Gmail; all three mailbox contracts are read-only. Follow-up send bypasses connected providers through application SMTP, has no explicit confirmation/idempotency ledger, and logs a sent correspondence after a void sender call | Source inspection only; vulnerable/failed behavior was not relabeled as runtime reproduction. No provider, SMTP or email was invoked | Confirmed contract gaps plus external verification blocker |
|
||||
| V-130 | `dotnet test ... --filter FullyQualifiedName~EmailControllerTests --no-restore`; focused hub/review Jest; full backend/frontend; `npm.cmd run build`; `git diff --check` | Repository root / `job-tracker-ui` | Verify owner-scoped neutral status/search/detail, honest read-only capability UI and regression/build hygiene | PASS — provider controller 3/3; hub/review 5/5; backend 604/604; frontend 49/49 suites and 186/186 tests; production build and patch check pass | Provider tests use fakes; frontend uses mocked provider data. Full Jest took 170.377s and retained its existing force-exit/open-handle notice | Browser/provider/production verification remains |
|
||||
| V-131 | Focused `EmailControllerTests|CorrespondenceControllerTests`; focused correspondence-inbox Jest; full backend/frontend; `npm.cmd run build`; `git diff --check` | Repository root / `job-tracker-ui` | Verify plain-text provider detail, owner-scoped saved fallback, malformed metadata tolerance, stale-request guard, full regressions and TypeScript | PASS — backend focused 5/5 and full 605/605; frontend focused 5/5 and full 49/49 suites, 188/188 tests; production build and patch check pass | Provider response is mocked and saved data synthetic. Full Jest took 81.434s and retains the existing force-exit/open-handle notice | Browser/real-provider/production verification remains |
|
||||
| V-132 | `EmailSendAttemptStoreTests`; backend build/full tests; `dotnet ef migrations has-pending-model-changes`; SQLite/MariaDB up/down scripts; disposable SQLite upgrade/insert/rollback; cleanup verification | Repository root | Verify inert tenant send ledger, idempotency/state safety, additive provider migration and rollback | PASS — focused 3/3; backend 608/608; model current; bounded provider SQL; SQLite unique index/FK/sample row/rollback pass; temp files removed | First MariaDB script exposed SQLite-scaffolded types and was rejected; explicit provider branch corrected it. One parallel test/build attempt contended on compiler output; serial test passed. MariaDB SQL generated only, not executed | Provider/runtime limitation and corrected verification setup |
|
||||
|
||||
@@ -37,12 +37,21 @@ Status: `IN PROGRESS`. Canonical hub routing and provider-neutral read capabilit
|
||||
- Rapid selection changes invalidate older requests so late provider responses cannot appear under the wrong message.
|
||||
- Inbox label and attachment counts now reflect parsed metadata arrays rather than treating every non-null JSON field as one item.
|
||||
|
||||
## Implemented inert send-ledger increment
|
||||
|
||||
- Added tenant-owned `EmailSendAttempts` with pending/sending/sent/failed/uncertain states and a unique owner/client-request key.
|
||||
- A request ID can be reused only for the same SHA-256 payload hash. Different content under an old request ID is rejected.
|
||||
- Only pending attempts may enter sending, and only sending attempts may become terminal. Failed or uncertain attempts cannot be restarted blindly.
|
||||
- The ledger stores provider/idempotency/status/timing metadata only; recipient, subject and message body are intentionally absent.
|
||||
- Deleting the owning job cascades the ledger row. The global owner filter protects direct attempt IDs.
|
||||
- The additive migration has provider-specific SQLite/MariaDB types and reversible up/down SQL. No send route, OAuth scope or provider call was enabled.
|
||||
|
||||
## Verification
|
||||
|
||||
- Focused provider/correspondence controllers: 5/5 tests; focused hub detail: 5/5 tests.
|
||||
- Full backend: 605/605; full frontend: 49/49 suites, 188/188 tests.
|
||||
- Focused send ledger: 3/3; provider/correspondence controllers: 5/5; hub detail: 5/5.
|
||||
- Full backend: 608/608; full frontend: 49/49 suites, 188/188 tests.
|
||||
- Production build/TypeScript and `git diff --check`: pass.
|
||||
- Implementation commits: `6008b4a`, `536d403`, `a20775c`.
|
||||
- Implementation commits: `6008b4a`, `536d403`, `a20775c`, `653f011`.
|
||||
|
||||
## Remaining MAIL-001 work
|
||||
|
||||
@@ -50,6 +59,7 @@ Status: `IN PROGRESS`. Canonical hub routing and provider-neutral read capabilit
|
||||
- Surface provider identity, reauthorization, read/unread, pin/read-later/archive/spam/trash only where the provider supports it.
|
||||
- Share thread detail and link/unlink actions between hub and job workspace.
|
||||
- Design editable provider drafts with recipient/subject/thread/provider review and explicit confirmed, idempotent send; uncertain failures must not be retried blindly.
|
||||
- Include non-sensitive send-attempt metadata in user export and verify account/job deletion coverage before enabling the send API.
|
||||
- Preserve minimal audit metadata without sensitive body logging; verify Free non-AI access and Pro-only AI assistance.
|
||||
- Complete link/unlink/dismiss/draft/send/failure/two-user/application-embed tests plus browser/production provider gates. No real email may be sent during repository verification.
|
||||
|
||||
@@ -59,4 +69,4 @@ The first focused Jest invocation exhibited the repository's open-handle delay.
|
||||
|
||||
## Rollback
|
||||
|
||||
Revert `a20775c` for message detail, `536d403` for the neutral API/status, then `6008b4a` for canonical routing. Persisted email/correspondence data and provider scopes remain unchanged.
|
||||
Revert `653f011` (after downgrading the additive migration) for the send ledger, `a20775c` for message detail, `536d403` for neutral reads, then `6008b4a` for routing. Provider scopes remain unchanged.
|
||||
|
||||
@@ -399,3 +399,13 @@
|
||||
- **Consequences:** users can distinguish live and saved content availability, malformed legacy metadata cannot break detail, and late responses cannot populate another selected row. The saved copy may be stale and is labeled as such when live access fails.
|
||||
- **User approval required:** No; this is local read-only behavior with synthetic/mocked tests and no provider invocation.
|
||||
- **Reversible:** Yes. Revert `a20775c`; no schema, dependency, provider scope or persisted data changes.
|
||||
|
||||
## DEC-041 — Delivery idempotency is a content-free tenant ledger
|
||||
|
||||
- **Date:** 2026-08-09
|
||||
- **Decision:** Persist one `EmailSendAttempt` per owner/client UUID with a SHA-256 payload hash and strict pending → sending → sent/failed/uncertain transitions. Terminal and uncertain attempts cannot restart; a new explicit review must use a new request UUID. Store no recipient, subject or body.
|
||||
- **Reason/evidence:** SMTP/provider calls cannot be made atomic with a database commit. A crash or transport interruption after acceptance is inherently uncertain, so retrying the same attempt can duplicate email. The ledger must exist before any provider scope/button is enabled and must preserve only the metadata needed for deduplication/audit.
|
||||
- **Alternatives considered:** rely on disabled buttons; store request IDs on correspondence; reuse AI operations; retry on every timeout; save full draft content in the audit row; add a message outbox that assumes provider idempotency. These do not prevent concurrent/direct-API duplicates, conflate domains, risk duplicate sends/private-data retention or promise atomicity the providers do not offer.
|
||||
- **Consequences:** API integration can reserve a unique attempt before external I/O and fail closed on pending/uncertain records. A provider success followed by database failure remains reconcilable rather than blindly retried. User export must include the non-sensitive metadata; job/account deletion cascades it. The migration is additive and EF-owned with explicit SQLite/MariaDB types.
|
||||
- **User approval required:** No; the approved MAIL-001 programme requires idempotent/uncertain send safety. This increment is inert and used no provider.
|
||||
- **Reversible:** Yes. Before reverting `653f011`, stop send admission, reconcile/drain attempts and downgrade `20260809195014_AddEmailSendAttempts`. No production migration has been applied.
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
Updated: 2026-08-09
|
||||
|
||||
- **Overall programme status:** Active. Six packages are locally verified; nineteen packages through CAREER-002 are implemented with automated/runtime evidence but blocked from applicable browser/provider/production gates; MAIL-001 is in progress with three pushed increments.
|
||||
- **Current work package:** `MAIL-001` — consolidated job-email hub and explicit sending (`IN PROGRESS`); canonical routing, neutral read status/API and safe plain-text message detail with saved fallback are pushed. A safe provider-send ledger remains.
|
||||
- **Overall programme status:** Active. Six packages are locally verified; nineteen packages through CAREER-002 are implemented with automated/runtime evidence but blocked from applicable browser/provider/production gates; MAIL-001 is in progress with four pushed increments.
|
||||
- **Current work package:** `MAIL-001` — consolidated job-email hub and explicit sending (`IN PROGRESS`); routing, neutral reads, safe detail and an inert durable send ledger are pushed. Provider delivery/re-consent and explicit-send API/UI remain.
|
||||
- **Completed work packages:** None are `DONE`; all repository security/AI packages still have applicable browser, provider and/or production gates.
|
||||
- **Locally verified work:** SEC-001, SEC-002, SEC-003, SEC-005A, CORE-001 and PROD-002 (`VERIFIED LOCALLY`).
|
||||
- **Implemented, verification incomplete:** SEC-004, SEC-005B, SEC-008, CORE-002, BG-001, OPS-001A/B/C, POL-001/002, AI-001/002/003/004, UX-001/002, QA-001, CAREER-001 and CAREER-002 (`IMPLEMENTED — NOT VERIFIED`). CAREER-002 now protects unsaved edits and provides tested structured custom-entry, profile-override and preview-error interactions; all automated/build gates pass.
|
||||
@@ -12,7 +12,7 @@ Updated: 2026-08-09
|
||||
- **Deferred work:** None. Conditional multi-replica coordination, model deletion, realtime operation delivery and unrelated production changes remain outside current packages.
|
||||
- **Next five work packages:** MAIL-001 consolidated email experience; JOBS-001 job-search/application redesign; HOME-001 homepage/Pro promotion; UX-003 authentication/profile polish; PRODUCT-001 homepage/Pro claims. SEC-006/007 resume after package-index permission.
|
||||
- **Status counts:** 6 `VERIFIED LOCALLY`; 19 `IMPLEMENTED — NOT VERIFIED`; 1 `IN PROGRESS`; 8 `NOT STARTED`; 5 `BLOCKED`; 0 `DONE`; 0 `DEFERRED`.
|
||||
- **Test status:** backend 605/605; frontend 49/49 suites and 188/188 tests; MAIL-001 provider/correspondence 5/5 and hub detail 5/5; CAREER-002 focused 17/17 and CAREER-001 16/16; production build and patch check pass. Jest open-handle/slow-run behavior is recorded in V-127/V-128/V-130/V-131.
|
||||
- **Test status:** backend 608/608; frontend 49/49 suites and 188/188 tests; MAIL-001 ledger 3/3, provider/correspondence 5/5 and hub detail 5/5; migration model/up/down/SQLite rehearsal pass; production build and patch check pass. Jest open-handle/slow-run behavior is recorded in V-127/V-128/V-130/V-131.
|
||||
- **Deployment status:** No deployment performed. No production migrations were run. AI operation worker remains disabled by default.
|
||||
- **Production status:** Unchanged and unverified. No provider/model call, model pull, external request or paid API occurred.
|
||||
- **Known regressions:** None found by automated suites. Jest still needs `--forceExit` and reports its existing open-handle notice. Email-provider tests are fake/local only; no send capability is claimed. Direct clean EF-only SQLite migration still hits the pre-existing historical blank-chain defect before later migrations; normal startup owns reconciliation. Cross-feature monthly AI usage accounting remains a rollout gap.
|
||||
|
||||
@@ -651,9 +651,9 @@ Ordering differences from the suggested list:
|
||||
- **Required production verification:** provider read/draft/send requires explicit authorized synthetic account; never real unsolicited email.
|
||||
- **Status:** `IN PROGRESS`.
|
||||
- **Blocker:** real provider verification external; mocked/local implementation not blocked after dependencies.
|
||||
- **Evidence:** `docs/verification/mail-001-job-email-hub.md`; V-126–V-131. Provider/correspondence focused 5/5; hub detail 5/5; backend 605/605; frontend 49/49 suites and 188/188 tests plus build.
|
||||
- **Commit:** `6008b4a` (canonical hub), `536d403` (neutral read API/status), `a20775c` (plain-text detail and saved fallback).
|
||||
- **Remaining work:** extend shared thread navigation/application embedding; reauth/capability actions; editable explicit/idempotent provider draft/send and audit; tenant/free/pro/application tests; browser/production. Existing provider scopes are read-only and legacy follow-up uses application SMTP; do not mislabel either. No real email; uncertain sends need manual reconciliation.
|
||||
- **Evidence:** `docs/verification/mail-001-job-email-hub.md`; V-126–V-132. Send ledger 3/3; provider/correspondence 5/5; hub detail 5/5; backend 608/608; frontend 49/49 suites and 188/188 tests plus build.
|
||||
- **Commit:** `6008b4a` (hub), `536d403` (neutral reads), `a20775c` (safe detail), `653f011` (inert durable send ledger).
|
||||
- **Remaining work:** provider send/re-consent adapters and safe classification; explicit confirmed API/UI using the ledger; export/deletion coverage; shared thread/application actions; tenant/free/pro/provider failure tests; browser/production. Existing provider scopes are read-only and legacy follow-up uses application SMTP; do not mislabel either. No real email; uncertain sends need manual reconciliation.
|
||||
|
||||
### JOBS-001 — Job-search source and assessment redesign
|
||||
|
||||
|
||||
@@ -2,17 +2,17 @@
|
||||
|
||||
Updated: 2026-08-09
|
||||
|
||||
- **Exact current task:** MAIL-001 — design the explicit provider-send/re-consent/idempotency/uncertain-delivery ledger without sending real email, then implement the smallest fake-tested contract slice.
|
||||
- **Last completed step:** plain-text live message detail, owner-scoped saved fallback, malformed-metadata tolerance and stale-request protection were committed/pushed as `a20775c`; neutral API/status is `536d403`, canonical routing `6008b4a`.
|
||||
- **Exact current task:** MAIL-001 — implement fake-transport Gmail/Graph delivery adapters and re-consent capability without external calls, then connect an explicit confirmed API to the durable ledger.
|
||||
- **Last completed step:** inert tenant-owned send states/idempotency and additive provider migration were committed/pushed as `653f011`; no route/provider send capability is enabled.
|
||||
- **Files currently modified:** MAIL-001 verification/log/master tracking documents only. Application code/tests are committed and pushed.
|
||||
- **Commands already run:** Phase 9/provider architecture and complete legacy send trace; provider/correspondence and hub-detail focused tests; full backend/frontend; production build; diff/secret review; three implementation commits/pushes. See V-126–V-131.
|
||||
- **Test results:** MAIL-001 provider/correspondence 5/5; hub detail 5/5; backend 605/605; frontend 49/49 suites and 188/188 tests; production build/TypeScript and patch check pass. Latest full Jest required force exit and took 81.434s.
|
||||
- **Commands already run:** complete provider/send trace; read/detail/ledger focused and full tests; TypeScript build; EF model parity; SQLite/MariaDB up/down SQL; disposable SQLite migration insert/rollback and safe temp cleanup; four implementation commits/pushes. See V-126–V-132.
|
||||
- **Test results:** MAIL-001 ledger 3/3, provider/correspondence 5/5, hub detail 5/5; backend 608/608; frontend 49/49 suites and 188/188 tests; migration model/up/down/SQLite rehearsal and production build pass.
|
||||
- **Services currently running:** none started intentionally. Exact task-owned hung Jest/build Node processes were stopped; Codex browser runtimes were not touched. Pre-existing Docker services were not changed.
|
||||
- **Temporary files or processes:** none. No provider account, private email, external model, paid service or production service was accessed.
|
||||
- **Production changes currently active:** none. No deployment, migration, provider connection/sync/send or production payload occurred.
|
||||
- **Rollback status:** revert `a20775c` for message detail, `536d403` for neutral API/status and `6008b4a` for hub routing; no schema/config/dependency/data migration. CAREER rollback records remain current. Production is unchanged.
|
||||
- **Rollback status:** downgrade `20260809195014_AddEmailSendAttempts` then revert `653f011`; revert `a20775c`, `536d403`, `6008b4a` for prior MAIL increments. No production migration/deploy occurred. Production is unchanged.
|
||||
- **Uncommitted changes:** MAIL-001 evidence/tracking documents only; commit/push before the next application increment.
|
||||
- **Known failures:** full thread navigation, provider state actions and explicit idempotent send remain; Gmail is the only mature review UI; Gmail/Graph OAuth scopes and the IMAP contract are read-only; legacy follow-up uses application SMTP without explicit confirmation/idempotency and must not be called provider send. Real provider/SMTP/MariaDB/production unavailable; Jest open handles; SEC-006 needs internet/package-index permission; parser isolation remains SEC-007.
|
||||
- **Exact next action:** commit/push this evidence, then define the minimum provider-send contract and durable send-attempt states (confirmed, pending, sent, failed-before-delivery, uncertain) including OAuth scope/re-consent and duplicate-request behavior; implement only a fake-tested repository slice that cannot send real email.
|
||||
- **Known failures:** provider delivery/re-consent, explicit-send API/UI, export coverage, full thread actions and non-Gmail review remain; OAuth scopes and IMAP are read-only; legacy follow-up SMTP remains unsafe/mislabeled for this purpose. Real provider/SMTP/MariaDB/production unavailable; Jest open handles; SEC-006 needs internet/package-index permission; parser isolation remains SEC-007.
|
||||
- **Exact next action:** commit/push this evidence, then extend Gmail/Graph services and neutral capabilities behind fake HTTP transports with explicit send scopes and deterministic rejected-versus-uncertain error classification. Do not expose a send route until those tests and ledger integration exist.
|
||||
- **Work that can continue independently:** remaining MAIL-001 repository work and later UX packages. SEC-006/007 await package-index permission; PROD-001/003/004 await production access.
|
||||
- **Decisions still required from the user:** none for synthetic/code-inspected repository work. Any provider connection or send test, internet/package upgrades, private data, external/paid providers and production actions retain explicit approval/safety gates; SEC-009 retention/legal policy remains unresolved.
|
||||
|
||||
Reference in New Issue
Block a user