Files
jobtrackingapp/docs/audits/verification-log.md
T
cesnimda dc511296a4
CI and Deploy / test (pull_request) Successful in 5m18s
CI and Deploy / deploy (pull_request) Has been skipped
test(auth): prove email token lifecycle
Reject verification-link replay and cover real Identity token expiry, replay, email change, and custom username preservation on SQLite.
2026-08-15 20:06:08 +02:00

217 lines
90 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# JobTracker verification log
Audit date: 2026-08-02
Only non-destructive commands are run. Commands that restore dependencies may populate local caches or existing build-output directories but do not modify declared dependencies or application source.
| ID | Exact command | Directory | Purpose | Result | Relevant errors or warnings | Failure classification |
|---|---|---|---|---|---|---|
| V-001 | `dotnet --info` | Repository root | Capture .NET toolchain | PASS — SDK 10.0.201; SDK 9.0.200 also installed; target runtime 9.0.2 present | No `global.json`; normal builds therefore selected SDK 10 | N/A |
| V-002 | `node --version; npm --version` | Repository root | Capture frontend toolchain | PASS — Node 22.23.1, npm 10.9.8 | CI/container use Node 20 | N/A |
| V-003 | `python --version; tools\\summarizer\\.venv\\Scripts\\python.exe --version` | Repository root | Capture Python toolchain | PASS — Python 3.12.3 for both | Docker uses floating `python:3.11` | N/A |
| V-004 | `docker version --format '{{.Client.Version}} client / {{.Server.Version}} server'; docker compose version` | Repository root | Capture container tooling | PASS — Docker 29.6.1; Compose 5.2.0 | None | N/A |
| V-005 | `dotnet restore "Job tracker.sln"` | Repository root | Restore declared NuGet dependencies | PASS — all projects up to date | Package cache/`obj` may be refreshed | N/A |
| V-006 | `npm ci --dry-run --ignore-scripts --no-audit --no-fund` | `job-tracker-ui` | Validate npm lock/install plan without replacing current `node_modules` | PASS — dry run resolved the lockfile | Reported 59 platform/optional packages it would add | N/A |
| V-007 | `.\\.venv\\Scripts\\python.exe -m pip install --dry-run -r requirements-dev.txt` | `tools/summarizer` | Validate Python requirement resolution without changes | PASS — runtime requirements satisfied; declared pytest would be restored | Detected pytest version drift | N/A |
| V-008 | `.\\.venv\\Scripts\\python.exe -m pip install -r requirements-dev.txt` | `tools/summarizer` | Restore the declared local test dependency | PASS — project-local ignored venv restored from pytest 9.1.1 to declared 8.3.5 | Local ignored venv changed; no manifest/source change | N/A |
| V-009 | `dotnet build "Job tracker.sln" --configuration Release --no-restore` | Repository root | Release build and compiler/static-analysis baseline | PASS — 0 warnings, 0 errors | None | N/A |
| V-010 | `dotnet test JobTrackerApi.Tests\\JobTrackerApi.Tests.csproj --configuration Release --no-build -- xUnit.parallelizeTestCollections=false xUnit.maxParallelThreads=1` | Repository root | Full backend suite, deterministic order | PASS — 462/462, 0 skipped | None | N/A |
| V-011 | `npx tsc --noEmit` | `job-tracker-ui` | Standalone strict TypeScript check including test sources | FAIL | `src/nginx-config.test.ts:7` uses regex `s` flag while target is ES2017 | Application/tooling-related |
| V-012 | `npm test -- --watchAll=false --runInBand` | `job-tracker-ui` | Full frontend Jest/RTL suite | PASS — 43 suites, 148 tests | None | N/A |
| V-013 | `npm run build` | `job-tracker-ui` | Production Next.js static-export build | PASS | Build's TypeScript pass did not catch the failing test-source check | N/A |
| V-014 | `.\\.venv\\Scripts\\python.exe -m pytest -q` | `tools/summarizer` | AI-sidecar test suite | PASS — 17 tests | Five SWIG deprecation warnings | N/A |
| V-015 | `dotnet format "Job tracker.sln" --verify-no-changes --no-restore` | Repository root | Formatting check without rewriting | FAIL — 1,301 whitespace diagnostics across 16 files | Formatting is not enforced in CI | Application/tooling-related |
| V-016 | `docker compose config --no-interpolate --quiet` | Repository root | Validate Compose structure without reading/interpolating secret values | PASS | None | N/A |
| V-017 | `$env:AI_SERVICE_TOKEN='audit-placeholder-not-a-secret'; $env:AUTH_JWT_KEY='audit-placeholder-not-a-secret'; docker compose --env-file .env.example config --quiet` | Repository root | Validate full Compose interpolation using safe placeholders | PASS | External network existence is not checked by `config` | N/A |
| V-018 | `dotnet ef migrations list --no-connect --no-build --configuration Release` | `JobTrackerApi` | List migrations without connecting to or changing a database | PASS — 19 migrations listed | Applied status intentionally unavailable under `--no-connect` | N/A |
| V-019 | `dotnet ef migrations has-pending-model-changes --no-build --configuration Release` | `JobTrackerApi` | Compare current EF model with snapshot without applying migrations | PASS — no pending model changes | Design-time host initialization only | N/A |
| V-020 | `dotnet list "Job tracker.sln" package --vulnerable --include-transitive` | Repository root | NuGet advisory audit | PASS — no known vulnerable packages in either project | Queried NuGet.org | N/A |
| V-021 | `npm audit --audit-level=low` | `job-tracker-ui` | npm production and development advisory audit | FAIL — two moderate vulnerabilities | Documented React Router redirect/SSR advisories; suggested fix is a breaking major change | Application/supply-chain-related |
| V-022 | `pipx run pip-audit -r requirements.txt` | `tools/summarizer` | Python advisory audit in an isolated audit-tool environment | FAIL — 119 advisory records affecting 6 packages | `transformers`, `torch`, `pillow`, `pypdf`, `python-multipart`, and transitive `starlette`; applicability/severity requires path-level assessment | Application/supply-chain-related |
| V-023 | `docker build --check --file JobTrackerApi\\Dockerfile .` | Repository root | Backend Dockerfile static check | PASS — no warnings | Loaded base-image metadata only | N/A |
| V-024 | `docker build --check --file Dockerfile .` | `job-tracker-ui` | Frontend Dockerfile static check | PASS — no warnings | Loaded base-image metadata only | N/A |
| V-025 | `docker build --check --file Dockerfile .` | `tools/summarizer` | AI Dockerfile static check | PASS — no warnings | Loaded base-image metadata only | N/A |
| V-026 | `npm run test:e2e` | `job-tracker-ui` | Isolated Chromium browser smoke suite | PASS — 4/4 | Covered login, saved-job create, Career Workspace load, anonymous public CV/PDF | N/A |
| V-027 | `git status --short --branch` | Repository root | Confirm audit preserved source worktree | PASS | Only pre-existing `.agent.md`/`AGENTS.md` plus `docs/audits/` are visible | N/A |
| V-028 | `dotnet list "Job tracker.sln" package --deprecated --include-transitive` | Repository root | Identify deprecated NuGet packages | WARN — API none; test project xUnit 2.9.2/transitives marked legacy | Migration to xUnit v3 is available but not required for this audit | Maintenance |
| V-029 | `npm outdated --json` | `job-tracker-ui` | Inventory version drift without changing packages | WARN — exited 1 because updates exist | React Router 7, MUI 9, testing-library, Node types, TypeScript, and web-vitals include major updates | Maintenance |
| V-030 | `curl.exe -sS -o NUL -w '%{http_code} %{time_total}' http://127.0.0.1:5402/health` and equivalent frontend request | Repository root | Verify disposable API/UI startup | PASS — API and frontend returned 200 | First development responses were about 2.2 s and 2.5 s; not production startup measurements | N/A |
| V-031 | Bounded `curl.exe -b <synthetic-cookie-jar> -w '%{http_code}'` requests for copied User A job/company/correspondence/attachment/CV/workspace IDs | Repository root | Direct-ID two-user isolation test | PASS/PARTIAL — meaningful job/company/message/attachment/profile/checklist results denied B; CV/AI/workspace/timeline/interview paths partly blocked by 500 defects | Exact status matrix in `evidence/two-user-isolation.md` | Application blockers on partial paths |
| V-032 | Authenticated `curl.exe` requests to `/api/cv/variants`, `/api/profile-cv/runs`, `/api/jobapplications/1/ai/history`, `/api/ai/usage`, `/api/jobapplications/1/workspace`, `/timeline`, and `/interview-prep` | Repository root | Exercise default SQLite career/application workspace APIs | FAIL — listed DateTimeOffset paths and the two ambiguous routes returned 500 | Sibling checklist/analysis/match paths returned 200 | Application-related |
| V-033 | Reset synthetic job fields in disposable SQLite; restart Release API; query row after hosted-service initial delays | Repository root / `JobTrackerApi` | Verify rules/enrichment workers see tenant data | FAIL — old Applied status and null tags/summary remained | Runtime agrees with deny-on-null query-filter execution path | Application-related |
| V-034 | Copy built-in SQLite backup to a new disposable restore path; `PRAGMA integrity_check`; start a second API with restored DB plus copied `Attachments/` and `keys/`; request `/health`, login, job, and attachment | Repository root / `JobTrackerApi` | Safe restoration rehearsal | PASS/PARTIAL — DB integrity/counts and restored application/file access passed | Complete recovery requires files/keys/config outside DB; MariaDB unavailable | Environmental/provider limitation |
| V-035 | Login; copy synthetic cookie jar; POST `/api/auth/logout` with CSRF header; request `/api/auth/me` with cleared and copied jars | Repository root | Verify logout revocation semantics | FAIL — cleared jar 401, copied pre-logout session 200 | Server session was not revoked | Application-related |
| V-036 | Start isolated API with `Auth__RequireEmailVerification=true`; register synthetic user; query stored `EmailConfirmed`; request `/api/auth/me` | Repository root / `JobTrackerApi` | Verify initial verification gate | FAIL — register 200, stored confirmation false, immediate authenticated request 200 | Email sender disabled; no mail sent | Application-related |
| V-037 | Mark only the disposable account confirmed; login; `PUT /api/auth/profile` with a new synthetic email; query identity row | Repository root | Verify email-change verification lifecycle | FAIL — update 204 and new address remained confirmed | No verification challenge | Application-related |
| V-038 | Ten warm `curl.exe` samples for `/health`, paged jobs, and companies; compute mean/p95 | Repository root | Safe local API timing baseline | PASS — 11.3/17.8/6.5 ms means respectively | One-row SQLite dataset; no capacity claim | N/A |
| V-039 | `Get-ChildItem job-tracker-ui\out\_next\static -Recurse -File` and sum `.js`/`.css` lengths | Repository root | Static-export size inventory | PASS — 49 JS chunks, 2,762,618 uncompressed bytes; CSS 293 bytes | Aggregate is not initial-route transfer size | N/A |
| V-040 | Import mandatory `browser-client.mjs` through the skill-required browser runtime | Browser skill runtime | Start interactive browser audit | BLOCKED — module absent from installed plugin bundle | Skill forbids fallback browser automation; no screenshots/manual viewport checks | Environmental/plugin packaging |
| V-041 | `pipx run pip-audit -r requirements.txt -f json` with local summary by package/unique advisory/fix version | `tools/summarizer` | Sceptically validate Python advisory reachability | FAIL — active PDF/image/multipart parsers have numerous crafted-input DoS/memory advisories | Model-loading advisories separated from user-upload reachability | Application/supply-chain-related |
| V-042 | `npm audit --json` with title/range/fix extraction | `job-tracker-ui` | Validate npm advisory scope | FAIL — four moderate advisory entries across two installed packages | Audit fix requires React Router 7.18.2 major for remaining issues | Application/supply-chain-related |
| V-043 | Resolve listeners with `Get-NetTCPConnection`; validate command lines with `Get-CimInstance`; stop exact PIDs; re-run `git status --short --branch` | Repository root | Clean up audit runtime and reconfirm source preservation | PASS — audit ports closed; only pre-existing and audit-report changes visible | Temporary disposable evidence retained outside repository | N/A |
| V-044 | `dotnet test JobTrackerApi.Tests\JobTrackerApi.Tests.csproj --no-restore --filter "FullyQualifiedName~AuthAndSystemControllerTests\|FullyQualifiedName~AuthSessionRevocationTests"` | Repository root | SEC-005B focused registration/email/session checks | PASS — 35/35 | None | N/A |
| V-045 | `dotnet test JobTrackerApi.Tests\JobTrackerApi.Tests.csproj --no-restore` | Repository root | Full backend regression after SEC-005B | PASS — 501/501 | None | N/A |
| V-046 | `npm run build`; `npm test -- --runInBand` | `job-tracker-ui` | Frontend build and full regression after registration/profile/confirmation UI | PASS — build; 43 suites and 151/151 tests | First regression run exposed a stale nginx filename/alias test from SEC-002; test was corrected to the deployed template contract and the complete rerun passed | Application test-maintenance issue resolved |
| V-047 | `dotnet ef migrations script 20260731115022_AddStripeBillingState 20260802205800_AddPendingEmailChange --project JobTrackerApi\JobTrackerApi.csproj --startup-project JobTrackerApi\JobTrackerApi.csproj --no-build` with SQLite and MariaDB design-time configuration; `dotnet ef database update ...` against disposable SQLite | Repository root | Validate SEC-005B migration SQL and safe upgrade | PASS/PARTIAL — provider SQL and upgrade pass; fresh empty migration chain fails before SEC-005B | Pre-existing `AddJobEntityAndProspectStages` expects missing `LastReminderEmailSentAt`; MariaDB execution unavailable | Application CORE-001 / provider limitation |
| V-048 | Isolated `dotnet run --no-build --no-launch-profile --project JobTrackerApi\JobTrackerApi.csproj --urls http://127.0.0.1:5302`; synthetic `Invoke-WebRequest` registration/login with email disabled | Repository root | Runtime verification-required registration boundary | PASS — register 202/typed flag/no `Set-Cookie`/zero cookies; login 403 `email_not_verified`/zero cookies | Synthetic disposable account only; no email sent | N/A |
| V-049 | Browser skill runtime `getForUrl("http://localhost:3100/register")`, new tab and navigation | In-app browser | Real browser registration/profile verification | BLOCKED before navigation | Administrator policy check was unavailable and denied localhost; no browser claim or screenshot made | Environmental/browser policy |
| V-050 | `Get-CimInstance Win32_Process ...`; `Stop-Process -Id 43004,32708`; listener recheck | Repository root | Stop exact isolated API/UI child processes | PASS — 5302/3100 listeners closed; pre-existing Docker services untouched | Recursive cleanup of the verified temp runtime directory was rejected by execution policy | Environmental cleanup limitation |
| V-051 | SEC-004 focused/full backend/frontend tests and dual-provider migration scripts | Repository root | Canonical Microsoft identity regression and migration verification | PASS/PARTIAL — 34 focused, 507 backend, 152 frontend; SQLite upgrade/unique rehearsal and SQLite/MariaDB SQL pass | No real Microsoft token/account, MariaDB execution, browser or production inventory | Provider/environment limitation |
| V-052 | `dotnet test ... --filter "FullyQualifiedName~CvBuilderTests|...|FullyQualifiedName~ApplicationAssetsTests"` | Repository root | CORE-001 focused affected-service regression | PASS — 81/81 | Original audit runtime remains the pre-fix reproduction | N/A |
| V-053 | `dotnet test ... --filter "FullyQualifiedName~SqliteDateTimeOffsetCompatibilityTests"` | Repository root | Execute CORE-001 against real SQLite and generate MariaDB/Pomelo ordering/range SQL | PASS — 3/3; owner-scoped ordering, range, usage, workspace, artifact and isolation paths pass | MariaDB SQL generation only; no server connection | Provider limitation |
| V-054 | `dotnet test JobTrackerApi.Tests\JobTrackerApi.Tests.csproj --no-restore`; `git diff --check` | Repository root | CORE-001 full backend regression and patch hygiene | PASS — 509/509; diff check clean apart from line-ending notices | None | N/A |
| V-055 | Isolated `dotnet run --no-launch-profile ... --environment=Development -- --urls=http://127.0.0.1:5303`; synthetic registration/login and HTTP matrix | Repository root | Fresh default-SQLite startup and affected API/runtime isolation | PASS — empty variants/runs/history/usage 200, missing workspace 404, owner workspace 200, User B workspace 404/variants empty | Browser and MariaDB unavailable; no external calls or real data | Environmental/provider limitation |
| V-056 | Resolve listener with `Get-NetTCPConnection`; inspect exact process; `Stop-Process`; listener recheck | Repository root | Stop CORE-001 isolated API safely | PASS — exact `JobTrackerApi` PID 15400 stopped and port 5303 closed | Exact nested disposable data cleanup rejected by execution policy | Environmental cleanup limitation |
| V-057 | `dotnet test ... --filter "FullyQualifiedName~RouteUniquenessTests|...ApplicationIntelligenceTests|...InterviewPrepTests|...InterviewPrepPersistenceTests"` | Repository root | CORE-002 route uniqueness and focused behavior | PASS — 31/31 | None | N/A |
| V-058 | `npm test -- --runInBand src/application-route-contracts.test.ts src/application-intelligence.test.tsx src/interview-prep.test.tsx` | `job-tracker-ui` | Verify distinct frontend timeline/board/brief contracts | PASS — 21/21 | Static brief-route contract complements existing rendered board/timeline tests | N/A |
| V-059 | Full backend and frontend suites; frontend production build | Repository root / `job-tracker-ui` | CORE-002 regression | PASS — backend 511/511; frontend 45 suites/153 tests; build passes | Browser unavailable | Environmental browser limitation |
| V-060 | Isolated SQLite API on 5304; synthetic owner/User B/anonymous GET matrix for timeline, interview board and brief; exact listener shutdown | Repository root | Prove ambiguity removal and authorization at runtime | PASS — each owner 200, other user 404, anonymous 401; exact PID 23904 stopped and port closed | No browser, MariaDB or production smoke | Environmental/provider limitation |
| V-061 | `dotnet test ... --filter "FullyQualifiedName~AttachmentConsistencyTests|FullyQualifiedName~AttachmentFlagsRecomputeTests|FullyQualifiedName~AttachmentsControllerTests"` | Repository root | SEC-008 failure-boundary and storage-invariant regression | PASS — 20/20 | Symlink creation unavailable on this host | Environmental capability limitation |
| V-062 | `dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --no-restore`; `git diff --check` | Repository root | SEC-008 full backend regression and patch hygiene | PASS — 525/525; no whitespace errors | Repository line-ending notices only | N/A |
| V-063 | Isolated SQLite API on 5305; synthetic User A upload/list/download/rename/delete and User B direct-ID denial; exact listener shutdown | Repository root | SEC-008 runtime and tenant isolation | PASS — owner operations 200/204, User B 404, final owner list empty; exact PID 4592 stopped and port closed | Browser, MariaDB and production inventory unavailable | Environmental/provider limitation |
| V-064 | Disposable local symbolic-link capability probe using .NET filesystem APIs | System temporary directory | Determine whether child reparse escape can be executed safely | BLOCKED — host denied symbolic-link creation with `RuntimeException`; temporary directories removed | Refusal branch code-inspected; traversal/outside-root test passes | Environmental capability limitation |
| V-065 | `dotnet test ... --filter "FullyQualifiedName~BackgroundWorkerTenantTests|FullyQualifiedName~CurrentUserIdLiveEvaluationTests|FullyQualifiedName~RulesEngineTests"` | Repository root | BG-001 owner scope, switches and fake side-effect integration | PASS — 9/9 after final trust-boundary assertion | No real email/AI invoked | N/A |
| V-066 | `dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --no-restore` | Repository root | BG-001 full backend regression | PASS — 532/532 after final trust-boundary test | None | N/A |
| V-067 | `docker compose config --quiet`; `git diff --check` | Repository root | Default-off production configuration and patch hygiene | PASS — Compose valid; no whitespace errors | Unset optional/local environment warnings and line-ending notices only | N/A |
| V-068 | Isolated API on 5306 with disposable SQLite data and all four worker switches false; health/no-export check; exact PID shutdown | Repository root | BG-001 safe startup without worker side effects | PASS — health 200, no export directory, exact PID 44980 stopped, port closed | No browser, production canary, SMTP or AI provider | Environmental/provider limitation |
| V-069 | `dotnet test ... --filter "FullyQualifiedName~UserOperationStoreTests"`; full backend suite | Repository root | OPS-001A state, concurrency, owner and regression checks | PASS — focused 7/7; full 539/539 | No handler/UI yet | N/A |
| V-070 | `dotnet ef migrations has-pending-model-changes`; generated SQLite/MariaDB migration up/down scripts | Repository root | OPS-001A model/migration parity | PASS — snapshot current; both providers create/drop; MariaDB has bounded types/eight `datetime(6)` and no unbounded text | MariaDB generation only | Provider limitation |
| V-071 | Disposable existing SQLite `database update`, downgrade and re-upgrade | Repository root | OPS-001A upgrade/rollback rehearsal | PASS | Synthetic local database only | N/A |
| V-072 | Fresh isolated application startup on 5307; health; EF update no-op; exact process shutdown | Repository root | Reconciler/migration startup order with EF-only new table | PASS — health 200; database already current; exact PID 37276 stopped and port closed | No MariaDB/production runtime | Provider limitation |
| V-073 | `dotnet test JobTrackerApi.Tests\JobTrackerApi.Tests.csproj --no-restore --filter FullyQualifiedName~UserOperationStoreTests` | Repository root | OPS-001B terminal notification, owner-state and rollback checks | PASS — 9/9 | Real file-backed SQLite; no email/worker | N/A |
| V-074 | `dotnet ef migrations script 20260802224646_AddUserOperations 20260802225941_AddUserNotifications ...` and reverse for SQLite/MariaDB | Repository root | OPS-001B provider-safe up/down SQL | PASS after correction — bounded MariaDB/SQLite create/drop scripts retained | First MariaDB attempt used the wrong connection-string key and emitted SQLite SQL; invalid output was overwritten and not treated as evidence; MariaDB not executed | Verification setup corrected / provider limitation |
| V-075 | Disposable SQLite notification upgrade, downgrade and re-upgrade; `dotnet ef migrations has-pending-model-changes ... --no-build` | Repository root | OPS-001B safe additive migration and model parity | PASS — all transitions succeeded; no pending model changes | Synthetic copy of OPS-001A evidence database only | N/A |
| V-076 | `dotnet test JobTrackerApi.Tests\JobTrackerApi.Tests.csproj --no-restore`; `git diff --check` | Repository root | OPS-001B backend regression and patch hygiene | PASS — 541/541; no whitespace errors | Line-ending notices only | N/A |
| V-077 | Focused operation controller/store tests; full backend suite | Repository root | OPS-001C owner APIs, safe DTOs, mutations and regressions | PASS — 12/12 focused; 544/544 full | Direct controller tests use real SQLite | N/A |
| V-078 | Focused operations/shell Jest; full Jest; `npm run build` | `job-tracker-ui` | OPS-001C states, action lock, bell accessibility, regression and TypeScript build | PASS — 3/3 focused; 47/47 suites and 156/156 full; build pass | First full npm invocation used repository root and failed for missing root `package.json`; corrected working directory passed | Verification command corrected |
| V-079 | Isolated API on 5310; two disposable users; synthetic SQLite operation/notification rows; authenticated/anonymous direct HTTP matrix | Repository root | OPS-001C runtime authorization, CSRF and lifecycle | PASS — owner detail/cancel/read/dismiss/retry 200/204; four copied cross-owner paths 404; anonymous 401; listener stopped | Initial launch inherited local connection; exact synthetic users/sessions were removed with zero-count proof. Lowercase raw GUID seed was replaced before the passing matrix | Verification setup corrected |
| V-080 | Evidence tree/key inspection; exact generated Data Protection key deletion; listener and local synthetic-account count checks | Repository root | Prevent secret/test-data leakage and confirm cleanup | PASS — key absent; no 5308/5309/5310 listeners; local pre-existing DB has zero synthetic accounts | Disposable synthetic SQLite evidence/backups retained | N/A |
| V-081 | `rg`/bounded `Get-Content` inventory of `AccountPlans`, billing/auth DTOs, every `ISummarizerService` call, controller route, worker and frontend caller | Repository root | Trace POL-001 end to end before enforcement | PASS — all current model-call paths classified in `pol-001-free-pro-entitlements.md` | Usage accounting is complete only for AI Workspace; landing-page claims remain PRODUCT-001 | Application gap/dependency |
| V-082 | `dotnet build JobTrackerApi.sln --no-restore`; `npm run build` | Repository root | Initial POL-001 build attempt | FAIL — solution filename and npm working directory were wrong | Corrected immediately to the actual project/UI paths; no files or dependencies changed | Command/operator-related |
| V-083 | `dotnet build JobTrackerApi/JobTrackerApi.csproj --no-restore`; `npm run build` | Repository root / `job-tracker-ui` | Compile backend and production frontend after policy/UI changes | PASS — backend 0 warnings/errors; frontend TypeScript/static build passed | Frontend build repeated after final changes in V-086 | N/A |
| V-084 | `dotnet test ... --filter "...AccountPlansTests|...ProEntitlementAuthorizationTests|...BackgroundWorkerTenantTests|...ProfileCvControllerTests|...JobApplicationsEndpointBehaviorTests"` | Repository root | Free/Pro/Admin/downgrade, stable 403, worker recheck and core behavior | PASS — 74/74 final | Interim runs exposed a missing test `using`, absent role services and an outdated SQLite expectation; fixtures were corrected without weakening behavior | Test-fixture maintenance resolved |
| V-085 | `npm test -- --runInBand ai-workspace-panel.test.tsx ai-usage-card.test.tsx job-details-generated-drafts.test.tsx profile-page.test.tsx quick-capture.test.tsx` | `job-tracker-ui` | Locked state, no false generation, usage and unaffected job/CV flows | PASS — 5 suites, 22/22 tests | Component tests; not a browser claim | N/A |
| V-086 | Full backend `dotnet test`; full frontend `npm test -- --runInBand`; `npm run build`; `git diff --check` | Repository root / `job-tracker-ui` | POL-001 regression and patch hygiene | PASS — backend 568/568; frontend 47/47 suites, 157/157; build passed; no whitespace errors | First backend full run had one outdated direct-controller expectation; corrected to Pro because the test targets SQLite aggregation, then full rerun passed. Line-ending notices only | Test expectation resolved |
| V-087 | Bounded source/route/provider inventory plus `dotnet test ... --filter "FullyQualifiedName~AiEvaluationFixtureTests"` | Repository root | PROD-002 workload classification and synthetic fixture safety/coverage | PASS — 19 synthetic cases; 1/1 validator | First validator run showed the email regex retained sentence punctuation; regex boundary corrected and rerun passed | Test validator corrected |
| V-088 | Full backend `dotnet test`; full frontend `npm test -- --runInBand`; `npm run build` | Repository root / `job-tracker-ui` | PROD-002 wider regression after final entitlement contract and fixture | PASS — backend 569/569; frontend 47/47 suites, 157/157; build passed | No model/provider/internet/real data used | N/A |
| V-089 | Bounded `rg`/`Get-Content` of POL-002 source, account/settings/authorization/workers, named AI client, sidecar router, Compose and tests | Repository root | Revalidate privacy and provider execution paths | PASS — global `AI_PROVIDER` reached full `/cv/*` payloads without per-user consent; `/summarize` remained local | Background queued calls have no HTTP identity and therefore need later operation policy snapshots | Confirmed implementation gap |
| V-090 | `dotnet build JobTrackerApi.csproj --no-restore`; `dotnet ef migrations add AddAiPrivacyPreferences ... --no-build` | `JobTrackerApi` | Compile policy/API and create additive preference migration | PASS — build 0 warnings/errors; migration created | First migration attempt exposed a misplaced fluent `AddHttpMessageHandler`; corrected at the named client and rebuilt | Implementation error resolved |
| V-091 | Focused backend policy/entitlement/worker/CV tests; final `AiPrivacyPolicyTests|ProEntitlementAuthorizationTests` rerun | Repository root | Verify live opt-out, Pro/admin/user gates and backend permission header | PASS — 72/72 then final policy 28/28 | Interim test used a nonexistent framework overload and misplaced a `using`; test construction corrected without weakening policy | Test-code errors resolved |
| V-092 | `.\.venv\Scripts\python.exe -m pytest -q` | `tools/summarizer` | Verify sidecar requires administrator gate plus backend consent header and remains local otherwise | PASS — 18/18 | Five existing SWIG deprecation warnings | N/A |
| V-093 | Focused UI `npm test -- --runInBand --runTestsByPath ...`; rerun after fixture correction | `job-tracker-ui` | Verify server-backed privacy controls and default local-only disclosure | PASS — 3 suites, 8/8 final | First run failed because the expanded settings test lacked an `/ai/usage` fixture; fixture added, production code unchanged | Test-fixture error resolved |
| V-094 | `dotnet ef migrations has-pending-model-changes`; migration script; disposable clean `dotnet ef database update` | `JobTrackerApi` | Validate model/migration defaults and clean application path | PARTIAL — no pending model changes; new SQLite SQL correctly uses AI enabled `1` and external consent `0`; clean chain failed before the new migration | SQLite idempotent scripts are unsupported; historical `AddJobEntityAndProspectStages` expects a reconciler-added column (pre-existing EF-only blank-chain defect) | Existing application-related migration-chain limitation |
| V-095 | Full backend `dotnet test`; full frontend `npm test -- --runInBand`; `npm run build`; `docker compose config --quiet`; `git diff --check` | Repository root / `job-tracker-ui` | POL-002 regression, production build, deployment syntax and patch hygiene | PASS — backend 576/576; frontend 47 suites/158 tests; build/config/diff pass | Expected unset optional Compose variables and line-ending notices only. Temporary API launch command was rejected before execution by policy; no service started | Runtime/browser/production verification blocked |
| V-096 | Source re-read plus `dotnet test ... --filter "...AiOperationQueueTests|...UserOperationStoreTests|...OperationsControllerTests"` | Repository root | AI-001 admission, capacity, priority, claim, owner execution, policy recheck and existing state/API regression | PASS — 17/17 final | Initial 15/15 and 16/16 passes preceded priority and retry/downgrade additions | N/A |
| V-097 | Full `dotnet test`; `docker compose config --quiet`; `git diff --check` | Repository root | AI-001 full backend regression and deployment/patch syntax | PASS — backend 581/581; config/diff pass | Expected unset optional Compose variables and line-ending notices only; worker remains default-off with no real task handler | Browser/provider/production verification pending later feature packages |
| V-098 | Bounded `rg`/`Get-Content` of every `/summarize`, `/extract-text`, `/cv/*`, `ISummarizerService`, privacy-header, operation-worker, provider-config, Compose and test path | Repository root | Revalidate AI-002 route convergence and existing mitigations before design | PASS — deterministic and summarize/extract paths remain local; all generative CV paths converge in the sidecar; configured external provider was direct rather than fallback; actual provider/failure provenance was lost | Browser/provider behavior was not inferred from source; route matrix records code-inspected status | Confirmed implementation gap |
| V-099 | `dotnet test JobTrackerApi.Tests\JobTrackerApi.Tests.csproj --no-restore --filter "FullyQualifiedName~AiOperationQueueTests\|FullyQualifiedName~AiPrivacyPolicyTests\|FullyQualifiedName~SummarizerServiceTests\|FullyQualifiedName~AiWorkspaceTests"`; `python -m pytest -q` | Repository root / `tools/summarizer` | Verify local-first order, policy/task propagation, schema/circuit/cost/failure routing and actual provenance | PASS — backend 26/26; sidecar 22/22 | First sidecar run passed 15/18 and correctly failed three obsolete external-first expectations; tests were updated to the new approved policy, then extended. No network/provider call occurred | Expected test-contract transition resolved |
| V-100 | Full `dotnet test JobTrackerApi.Tests\JobTrackerApi.Tests.csproj --no-restore`; `python -m pytest -q`; synthetic-token `docker compose config --quiet`; `git diff --check` | Repository root / `tools/summarizer` | AI-002 wider regression, deployment syntax and patch hygiene | PASS — backend 588/588; sidecar 22/22; Compose/diff pass | Five existing SWIG deprecation warnings; Docker config-file access and unset optional-variable warnings; line-ending notices only. Worker/external gate remain off | Browser, MariaDB, selected-model, real-provider and production checks remain blocked |
## Secret-scan commands
The tracked-tree scan read only paths returned by `git ls-files`, skipped binary/large files, and applied high-confidence regular expressions for private-key headers, JWTs, common cloud tokens, and Stripe secrets. It emitted only secret type, path, and line number; never matched values. Result: one JWT-like token at `docs/_archive/artifacts/s06-acceptance/.dev-auth-token.txt:1`.
The JWT was decoded locally without printing claims or token text. It is an expired HS256 local-app token (expired 2026-03-27), has no current required session ID, and cannot pass current session validation.
The history scan used:
```powershell
$pattern='-----BEGIN (RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----|eyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}|(AKIA|ASIA)[A-Z0-9]{16}|AIza[0-9A-Za-z_-]{35}|gh[pousr]_[A-Za-z0-9]{30,}|(sk|rk)_(live|test)_[A-Za-z0-9]{16,}|whsec_[A-Za-z0-9]{16,}'
foreach($commit in (git rev-list --all)) { git grep -I -l -E -e $pattern $commit -- }
```
Output was reduced to filenames and commit counts. The token artifact appears under its current and former paths across history. A filename-only history check also found two historical ASP.NET Data Protection XML key files; no key material was printed. Current documentation states those production keys were rotated on 2026-08-02; that operational claim was not independently verified against production.
## Checks not available/configured
- No repository lint script or ESLint configuration is present.
- `gitleaks`, `trivy`, and `hadolint` are not installed; equivalent bounded checks were performed as described above, but no container CVE scan was available.
- Dependency audit results are advisory matches, not proof that every advisory is reachable or exploitable.
## Continued verification commands
| ID | Exact command | Directory | Purpose | Result | Relevant errors or warnings | Failure classification |
|---|---|---|---|---|---|---|
| V-104 | Bounded `rg`/`Get-Content` of `ProfileCvController` partials, `CvProcessingQueue`, extraction models/registration, Profile UI polling/tests and proxy timeout configuration | Repository root | Revalidate AI-004 upload/queue/restart/review path before design | PASS/PARTIAL — upload is synchronous through parser and multiple model-capable stages; reprocess/rebuild/improve persist runs and return 202, but an unbounded process channel supplies wakeups and no AI-001 operation/provenance/cancellation contract exists. Startup scans queued/running runs | No browser/private CV/parser payload/model/MariaDB/production execution; 504 origin not live-reproduced | Confirmed code-path gap plus environmental blockers |
| V-105 | `dotnet restore --packages C:\Users\Cesnimda\.nuget\packages --ignore-failed-sources`; `dotnet build --no-restore -p:UseAppHost=false` | `JobTrackerApi` | Recover the sandbox-rewritten assets file from the existing local package cache and compile AI-004 without downloading/upgrading dependencies | PASS — local-cache-only restore and build; 0 warnings/errors | Initial default restore failed because sandbox NuGet path was empty/network blocked; no dependency version or declaration changed | Environmental command path corrected |
| V-106 | `dotnet test --no-restore --filter "FullyQualifiedName~CvProcessingOperationTests|FullyQualifiedName~ProfileCvControllerTests|FullyQualifiedName~SqliteDateTimeOffsetCompatibilityTests|FullyQualifiedName~AiOperationQueueTests"`; `npm.cmd test -- --runInBand --forceExit src/profile-page.test.tsx`; `npm.cmd run build` | Backend tests / `job-tracker-ui` | Verify 202/dedup/owner/retry/provenance/review gate and durable Career Profile UI | PASS — backend 40/40; frontend 10/10; production build | Synthetic CV and fake provider only; Jest existing force-exit/open-handle notice | N/A |
| V-107 | Full `dotnet test --no-restore`; full `npm.cmd test -- --runInBand --forceExit`; `git diff --check`; implementation commit/push | Repository root / `job-tracker-ui` | AI-004 full regression, patch hygiene and remote checkpoint | PASS — backend 594/594; frontend 47/47 suites and 161/161 tests; no whitespace errors; `c3c5af8` pushed | Browser/private CV/parser isolation/MariaDB/model/restart/production checks not run; line-ending notices only | Environmental/dependency gates remain |
| V-101 | Bounded `rg`/`Get-Content` trace of Strategy button, Focus Plan tab/cache, controller/model calls, owner filters, proxy/queue/routing configuration and tests | Repository root | Revalidate AI-003 complete execution path before design | PASS — one UI action could start candidate fit plus four sequential synchronous focus-plan model calls; Pro and owner filters existed, durable state did not | Live timeout reproduction blocked; this is code-path evidence | Application-related |
| V-102 | `dotnet test ... --filter "...StrategySnapshotOperationTests|...AiWorkspaceNotePersistenceTests|...AiOperationQueueTests|...ProEntitlementAuthorizationTests"`; `npm.cmd test -- job-details-generated-drafts.test.tsx --runInBand --forceExit` | Repository root / `job-tracker-ui` | Focused 202/handler/cache/tenant/provider-shape and queued/cancel/fail/retry UI checks | PASS — backend 34/34; frontend 6/6 | Fake model only; Jest reports the existing force-exit/open-handle notice | N/A |
| V-103 | Full `dotnet test ... --no-restore`; full `npm.cmd test -- --runInBand --forceExit`; `npm.cmd run build`; `git diff --check` | Repository root / `job-tracker-ui` | AI-003 regression, TypeScript production build and patch hygiene | PASS — backend 592/592; frontend 47/47 suites, 160/160; build; no whitespace errors | Initial sandboxed build attempted blocked NuGet restore; previously approved build path restored from existing cache and passed. Line-ending notices only | Environmental command path corrected |
| V-108 | Bounded source trace of `LoginPage`, Google/Microsoft account cards, auth API/config, translations and login tests | Repository root | Revalidate UX-001 local/provider execution and identity boundaries | PASS — backend already accepts username or email; UI imposed email-only validation and separate provider tabs; provider exchange and account-link endpoints are distinct | No identity/config/schema behavior changed | N/A |
| V-109 | `npm.cmd test -- --runInBand --forceExit src/login-page.test.tsx`; full `npm.cmd test -- --runInBand --forceExit`; `npm.cmd run build`; `git diff --check` | `job-tracker-ui` / repository root | Verify unified form, invalid credentials, provider cancellation/return, full regression, TypeScript and patch hygiene | PASS — focused 13/13; full 47/47 suites and 166/166 tests; production build; no whitespace errors | Jest reports its existing force-exit/open-handle notice; provider tokens are synthetic mocks | N/A |
| V-110 | In-app browser at `http://localhost:3000/login`; dark-theme viewport/DOM checks and screenshots at 375×812, 768×900, 1440×1000 | Local frontend | Verify running local form, accessible names and responsive layout | PASS/PARTIAL — local form readable; viewport and document widths match with no overflow; evidence captured | API config service absent, so provider alternatives were mocked only; light/System and real-provider paths not run. Full-page screenshot mode produced an artifact and was discarded | Environmental/provider limitation |
| V-111 | Complete trace of `themePrefs`, auth user-key transitions, App provider/router lifecycle, Settings selector, Next layout/bootstrap and existing tests | Repository root | Reproduce UX-002 precedence and delayed switch path | PASS — login stored the resolved user key without a theme notification, so anonymous mode remained until refresh; provider key/router dependency remounted app state; no cross-tab listener or pre-paint bootstrap existed | Confirmed source execution path; no backend/identity behavior implicated | Application-related |
| V-112 | `npm.cmd test -- --runInBand --forceExit src/theme-state.test.tsx`; full `npm.cmd test -- --runInBand --forceExit`; `npm.cmd run build`; `git diff --check` | `job-tracker-ui` / repository root | Verify precedence, login/logout events, System behavior, pre-paint bootstrap, in-place provider state, regressions and TypeScript | PASS — focused 6/6; full 48/48 suites and 172/172 tests; production build and patch hygiene pass | Initial build found unsupported `noSsr` prop and was corrected; Jest retains existing force-exit/open-handle notice | Application issue corrected before commit |
| V-113 | In-app browser Settings: Light → Dashboard → refresh; Dark; System; second-tab Dark → Light sync; 375/768/1440 measurements/screenshots; console inspection | Local frontend | Verify actual theme transitions, persistence, cross-tab behavior and responsive access | PASS/PARTIAL — expected scheme at every transition, first tab updated without reload, no final console warnings/errors, no horizontal overflow after scrollable Settings tabs | Authenticated two-user, host OS preference flip and production not run; transient HMR messages occurred while editing and clean build passes | Environmental/deployment limitation |
| V-114 | Complete trace of import HTML cleanup/language/tagging, deterministic matcher, analysis endpoint/UI, match endpoint/UI, learning-item sync and storage/cache behavior | Repository root | Reproduce QA-001 low-information term path and version implications | PASS — visible terms come from English-only single-token ranking in `JobCvMatchService`; imported HTML is cleaned earlier but manual text may not be; result is on-demand and has no historical analysis cache; AI is not involved | Confirmed source execution path | Application-related |
| V-115 | `dotnet test ... --filter "...JobCvMatchServiceTests|...ApplicationIntelligenceTests|...JobApplicationsEndpointBehaviorTests|...ApplicationChecklist"`; `npm.cmd test ... match-score-panel.test.tsx application-intelligence.test.tsx`; final matcher/UI focused rerun | Repository root / `job-tracker-ui` | Verify seven required fixtures, affected endpoints/learning lifecycle and honest label | PASS — affected backend 54/54; affected UI 13/13; final matcher 15/15 and label 3/3 | Synthetic job/CV text only; no model/provider/browser | N/A |
| V-116 | Full `dotnet test ... --no-restore`; full `npm.cmd test -- --runInBand --forceExit`; `npm.cmd run build`; `git diff --check` | Repository root / `job-tracker-ui` | QA-001 full regression, TypeScript/build and patch hygiene | PASS — backend 601/601; frontend 48/48 suites and 172/172 tests; production build; no whitespace errors | Jest existing force-exit/open-handle notice; browser/production presentation not run | Environmental/deployment limitation |
| V-117 | Bounded `rg`/`Get-Content` of Career Workspace/Profile/Builder components, CV variant client, application CV assets, routes, requirements and tests | Repository root | Revalidate CAREER-001 state ownership, navigation, approval gate and existing job-specific CV boundary | PASS — profile component owns completeness/import state; variants carry optional job ownership; Apply/Discard is the only extraction merge path; old wrapper lacked resumable/recent/first-run hierarchy | No browser or production execution; behavior labels distinguish source inspection | Confirmed product hierarchy gap |
| V-118 | `npm.cmd test -- --runInBand src/career-workspace-page.test.tsx src/profile-page.test.tsx` | `job-tracker-ui` | Verify first/returning/incomplete/loading/processing/review/failure/recent-document states and unchanged approval gate | PASS — 2 suites, 16/16 tests | Initial assertions exposed intentional duplicate labels; duplicate page controls/completeness were removed and selectors corrected without weakening behavior | Implementation/test refinement resolved |
| V-119 | `npm.cmd test -- --runInBand`; `npm.cmd run build`; `git diff --check` | `job-tracker-ui` / repository root | CAREER-001 full regression, TypeScript/build and patch hygiene | PASS — 49/49 suites, 178/178 tests; optimized production build; no whitespace errors | Repository line-ending notices only; browser/production checks not run | Environmental/deployment limitation |
| V-120 | Bounded `rg`/`Get-Content` of CV Builder list/editor/client/tests, variant controller/service, application assets, architecture and Phase 8 requirements | Repository root | Revalidate CAREER-002 capabilities and identify confirmed gaps before editing | PASS — most requested section/edit/reorder/hide/preview/version/PDF behavior exists; silent debounce/failed-save navigation, blank-name feedback, custom-entry/delete confirmation and regression depth are evidenced gaps | Fresh FlowCV browser research unavailable after browser finalization; existing repository research is not relabeled as new evidence | Confirmed product/data-integrity gaps plus research limitation |
| V-121 | `npm.cmd test -- --runInBand src/cv-builder-deep-link.test.tsx src/cvBuilder.test.ts src/cv-builder-page.test.tsx` | `job-tracker-ui` | Verify name validation, latest-data retry, navigation warning and existing list/deep-link/helper behavior | PASS — 3 suites, 15/15 tests | Initial allowed-navigation assertion hit the test runtime's absent `Request`; the meaningful cancel/warning path remains covered without inventing a polyfill | Environmental test-runtime limitation |
| V-122 | `npm.cmd test -- --runInBand`; `npm.cmd run build`; `git diff --check` | `job-tracker-ui` / repository root | CAREER-002 save-integrity regression, TypeScript/build and patch hygiene | PASS — 49/49 suites, 181/181 tests; production build; no whitespace errors | Repository line-ending notices only; browser/production checks not run | Environmental/deployment limitation |
| V-123 | `npm.cmd test -- --runInBand src/cv-builder-deep-link.test.tsx`; full `npm.cmd test -- --runInBand`; `npm.cmd run build` | `job-tracker-ui` | Verify custom-section add/edit/reorder/hide/delete confirmation and persistence | PASS — focused 7/7; full 49/49 suites and 182/182 tests; production build | Synthetic variants only; browser not run | N/A |
| V-124 | `npm.cmd test -- --runInBand src/cv-builder-deep-link.test.tsx` | `job-tracker-ui` | Verify named expand/collapse/reorder/hide controls, persisted profile-entry overrides and preview failure/retry | PASS — editor 9/9 | Initial preview assertion read the iframe before the retry completed; changed to wait for observable async completion | Test timing corrected |
| V-125 | `npm.cmd test -- --runInBand`; `npm.cmd run build`; `git diff --check` | `job-tracker-ui` / repository root | Final CAREER-002 regression, TypeScript/build and patch hygiene | PASS — 49/49 suites, 184/184 tests; production build; no whitespace errors | Fresh FlowCV/browser/production verification not run; line-ending notices only | Environmental/deployment limitation |
| V-126 | Bounded `rg`/`Get-Content` of Phase 9 requirements, correspondence/Gmail routes/pages/shared job component, provider files/tests and architecture/audit reports | Repository root | Revalidate MAIL-001 duplicated navigation, domain ownership, provider and send boundaries | PASS/PARTIAL — inbox and Gmail review were separate routes; job workspace already reuses `Correspondence`; Gmail link/import is mature but provider-neutral hub state and explicit provider draft/send are not implemented | Source inspection only; no provider/account/email access | Confirmed product/domain gaps |
| V-127 | `npm.cmd test -- --runInBand --forceExit src/correspondence-inbox-page.test.tsx src/gmail-review-page.test.tsx` | `job-tracker-ui` | Verify canonical hub views, review reuse, decisions and legacy redirect | PASS — 2 suites, 5/5 tests | Non-force run retained an open handle; force-exit run completed in 50.051s | Existing test-runtime limitation |
| V-128 | `npm.cmd run build`; full `npm.cmd test -- --runInBand --forceExit`; `git diff --check` | `job-tracker-ui` / repository root | MAIL-001 route increment regression, TypeScript/build and patch hygiene | PASS — build; 49/49 suites and 186/186 tests; no whitespace errors | Full Jest took 228.709s and retained existing open-handle notice. One build process remained after compilation; exact task-owned PIDs were stopped and clean rerun passed | Environmental/tooling limitation |
| 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 |
| V-133 | Focused delivery/provider/controller tests; full backend; focused inbox Jest; frontend production build; `git diff --check` | Repository root / `job-tracker-ui` | Verify explicit consent scopes, capability reporting, Gmail/Graph payloads, IMAP read-only, rejected/reauth/uncertain classification and regressions | PASS — focused backend 18/18; full backend 613/613; inbox 5/5; production build and patch check pass | Ephemeral encrypted tokens, synthetic recipients/content and mocked HTTP only. No OAuth/provider/email call or real account. Browser/production not run | External provider/production limitation |
| V-134 | Focused `EmailSendControllerTests|EmailSendAttemptStoreTests|EmailControllerTests`; full backend; staged diff/secret-name/whitespace review | Repository root | Verify explicit confirmation, bounded input, owner isolation, canonical idempotency, rate-limited provider admission, correspondence/audit transaction and failed/uncertain behavior | PASS — focused 12/12; full backend 619/619; no whitespace errors or secret values. Provider called once across duplicate requests; cross-tenant/unconfirmed/malformed requests never reserve or deliver | SQLite and fake provider only. No real provider/email/network/browser/production execution. Crash-abandoned `sending` reconciliation remains | External provider/runtime limitation |
| V-135 | Focused correspondence-inbox Jest; full frontend Jest; `npm.cmd run build`; `git diff --check` | `job-tracker-ui` / repository root | Verify editable provider-bound reply, visible review fields, confirmation/cancel, one UUID, sent/uncertain duplicate safety, responsive TypeScript/build and regression hygiene | PASS — focused 7/7; full 49/49 suites and 190/190 tests; production build; no whitespace errors | JSDOM and mocked API/provider data only; no running browser/provider/email. Full Jest took 75.632s and retained the existing force-exit/open-handle notice | Browser/provider/production limitation |
| V-136 | Focused `EmailSendAttemptStoreTests|EmailSendControllerTests`; full backend; provider-dependency search; `git diff --check` | Repository root | Verify restart recovery, stale/fresh boundary, pending-failed versus sending-uncertain classification, two-owner notification isolation, idempotency and absence of provider retries | PASS — focused 10/10; full backend 620/620; repeated recovery 0/0; each owner sees one content-free notification; recovery code has no provider/SMTP dependency; no whitespace errors | Real SQLite and manual clock; no process kill, MariaDB, provider, email or production runtime. Five-minute scan performance is unmeasured on a large ledger | Runtime/performance limitation |
| V-137 | `npm.cmd ls react-router-dom react-router js-yaml nanoid --all --depth=4`; `npm.cmd audit`; six focused router suites; full `npm.cmd test -- --runInBand`; `npm.cmd run build`; staged diff review | `job-tracker-ui` / repository root | Resolve the frontend advisory gate without an unreviewed forced update and verify the React Router v7 compatibility path | PASS — audit reports 0 vulnerabilities; focused 6/6 suites and 24/24 tests; full 49/49 suites and 190/190 tests; production build/TypeScript/static generation pass; `b55a592` pushed | CI/live deployment has not yet consumed the pushed commit; no deployment or production access occurred | Deployment verification pending |
| V-138 | Focused `JobApplicationsFollowUpDraftTests|BackgroundWorkerTenantTests`; focused follow-up/trust-loop Jest; full backend/frontend; production build; `npm.cmd audit`; staged diff review | Repository root / `job-tracker-ui` | Verify legacy direct SMTP retirement while preserving draft generation, scheduled reminders and the provider-confirmed Job email boundary | PASS — focused backend 10/10 and UI 2/2; full backend 621/621 and frontend 49/49 suites, 190/190 tests; build and audit pass; legacy action returns 410 with no SMTP dependency; `8fe3903` pushed | JSDOM/fake services only; no provider/email/browser/production execution. Remote CI/live confirmation remains | External/deployment limitation |
| V-139 | Focused `BackupControllerTests|BackgroundWorkerTenantTests|EmailSendAttemptStoreTests`; full backend; staged diff/secret/content-field review | Repository root | Verify owner-readable content-free send-attempt exports and hard-job-delete cascade isolation | PASS — focused 16/16; full backend 622/622; encrypted and daily exports include one owner attempt without payload hash; real SQLite deletes only the target job's attempt; `aff34cc` pushed | Complete account deletion/files/backups/retention remain SEC-009; no production export or deletion occurred | Deliberately bounded lifecycle increment |
| V-140 | Running local API/frontend plus in-app browser at `/correspondence` and `/correspondence/review`; DOM/URL/layout/server-log inspection; screenshots | Local development environment | Verify authenticated empty Job email, disconnected capability states, view navigation and compatibility redirect in a real browser | PASS/PARTIAL — linked view and review view render; provider states are explicit; direct legacy route canonicalizes to `?view=review`; 1280×720 document width equals viewport; expected disconnected Gmail 409s are handled without 5xx; screenshots saved | Disposable local account/database only. No provider/send. Browser could not resize or dispatch native Tab traversal, so required widths/themes/keyboard and production remain blocked | Browser/tool/provider limitation |
| V-141 | Gitea commit status and public run 608/609 log/status inspection; focused `e2e/smoke.spec.ts` assertion review; `npm run test:e2e`; `git diff --check` | Repository root / `job-tracker-ui` | Verify the reported deployment audit remediation remotely and correct the next evidence-backed CI failure | PASS/PARTIAL — run 608 passed the audit then exposed stale Career Workspace copy; the behavior-based correction passes Playwright 4/4 locally and replacement run 609 passes the complete pull-request CI job in 4m20s | Merge-to-main live deploy remains pending; deploy was correctly skipped for the pull request and no production action occurred | Remote CI verified; live pending |
| V-142 | Provider-scope/contract inventory; focused correspondence context/inbox/job-detail Jest; full frontend Jest; production build; `git diff --check` | Repository root / `job-tracker-ui` | Verify the shared Application Workspace passes real job context without inventing unsupported provider actions | PASS — removed `null as any`; both application surfaces use one small context contract; focused 3/3 suites and 10/10 tests; full 50/50 suites and 192/192 tests; production build/TypeScript pass; `ff547df` committed | Gmail/Graph installed scopes do not include mutation and IMAP is read-only; no provider/network/browser/production action occurred | Provider mutation remains unsupported and honestly deferred |
| V-143 | Focused correspondence-inbox Jest; focused Gmail unlink API tests; full backend/frontend; production build; `git diff --check` | Repository root / `job-tracker-ui` | Verify canonical-hub Gmail unlink confirmation, provider-copy disclosure and cross-user isolation | PASS — hub 8/8; unlink API 2/2 including real-database User A/User B denial; backend 623/623; frontend 50/50 suites and 193/193 tests; build/TypeScript pass; `1dabbeb` committed | Mocked UI and local SQLite only; no provider message was deleted and no provider/network/production action occurred | Browser/provider/production verification remains |
| V-144 | Focused correspondence-inbox Jest; full frontend Jest; production build; `git diff --check` | `job-tracker-ui` / repository root | Verify disconnected/read-only/send-capable/provider-failure states remain honest without hiding saved correspondence | PASS — focused 9/9; full 50/50 suites and 194/194 tests; build/TypeScript pass; disconnected no longer claims read access; status failure leaves saved inbox visible; `f9e641c` committed | Mocked status responses only; no provider/network/browser/production action occurred | Provider mutation capabilities remain unsupported |
| V-145 | Email draft/storage inventory; focused `EmailSendControllerTests`; full backend; route authorization reflection; `git diff --check` | Repository root | Verify basic authenticated provider email remains Free while preserving send safety, and identify a privacy-safe durable-draft boundary | PASS/PARTIAL — local authentication is required with no Pro policy; focused 7/7 and backend 624/624; no existing email-draft entity safely owns recipient/subject/body/thread/provider/request state, so browser storage/job recruiter drafts were rejected as unsafe conflation | No provider/network/browser/production action; durable draft schema/API remains unimplemented | Free access verified; durable draft design pending |
| V-146 | `EmailDraftPersistenceTests`; full backend; backend build; `dotnet ef migrations has-pending-model-changes`; SQLite/MariaDB up/down script generation; disposable full-chain SQLite migration rehearsal; staged diff review | Repository root | Verify an inert owner-filtered email-draft persistence boundary, job lifecycle, additive dual-provider migration and rollback | PASS/PARTIAL — two-owner real-SQLite isolation/cascade passes; backend 625/625; build has 0 warnings/errors; model current; SQLite and MariaDB up/down SQL are bounded and reversible; `14b396a` pushed | Full-chain disposable SQLite apply is blocked before the new migration by pre-existing `AddJobEntityAndProspectStages` blank-chain drift (`LastReminderEmailSentAt` is referenced before creation); MariaDB SQL generated but not executed; no API/UI/provider/content logging added | Draft persistence verified; historical migration blocker remains JT-019 |
| V-147 | Focused `BackupControllerTests|BackgroundWorkerTenantTests.Daily_export_writes_one_isolated_atomic_file_per_owner`; full backend; staged diff review | Repository root | Verify readable private draft coverage through existing owner-isolated export boundaries | PASS — focused 4/4 and backend 625/625; encrypted on-demand export includes User A's complete draft and excludes User B; daily export writes exactly one matching draft per hashed owner file; `2fa4e38` pushed | Synthetic content and local stores only; daily exports inherit the existing plaintext-at-rest export-folder boundary; complete account deletion/backup retention remains SEC-009 | Export prerequisite verified; API/UI remains unexposed |
| V-148 | Focused `EmailDraftsControllerTests`; full backend; backend build; staged diff review | Repository root | Verify bounded authenticated draft CRUD, owner/job isolation and optimistic revision conflicts without provider side effects | PASS — focused 4/4; backend 629/629; build 0 warnings/errors; incomplete autosave, validation, unknown provider, foreign job/direct ID/update/delete denial, stale update/delete conflicts and owned delete pass on real SQLite; `a9bb22e` pushed | Synthetic content/local database only; no UI/browser/provider/send/production action | API boundary verified; UI recovery remains |
| V-149 | Focused draft API/export/persistence tests; full backend; EF model-current; SQLite/MariaDB up/down migration scripts; staged diff review | Repository root | Prevent refresh-restored drafts from receiving a new delivery identity | PASS — focused 9/9, backend 629/629 and model-current pass; creation assigns a canonical UUID, edits preserve it, exports include it, all-owner list remains tenant-filtered, and reversible provider SQL is generated; `80b5532` pushed | MariaDB SQL generated only; historical JT-019 still blocks full blank SQLite chain; no UI/provider/send/production action | UI safety prerequisite verified |
| V-150 | Focused correspondence-inbox Jest; full frontend Jest; production build; staged diff review | `job-tracker-ui` / repository root | Verify explicit reply-draft save, refresh-resume, server identity adoption, conflict handling and safe post-send cleanup | PASS — focused 11/11; frontend 50/50 suites and 196/196 tests; TypeScript/production build pass; save accepts incomplete reply, resume preserves private text, 409 keeps local edits visible, discard/delete and sent cleanup use revision | JSDOM/mocked API only; browser/provider/send/production not exercised; Jest retains existing force-exit notice | Reply recovery verified locally; new-message and durable failed-attempt rotation remain |
| V-151 | Focused `EmailDraftsControllerTests`; full backend; focused/full correspondence-inbox Jest; production build; staged diff review | Repository root / `job-tracker-ui` | Verify persisted delivery identity rotates only after the matching definitive failure | PASS — draft API 5/5; backend 630/630; inbox 12/12; frontend 50 suites/197 tests; build pass; no ledger row/refused, failed/rotated, stale/refused and foreign/not-found paths pass; `29de263` pushed | Synthetic SQLite and mocked UI only; two npm commands were initially run from repository root and failed environmentally before correct-directory reruns passed; no provider/send/production action | Durable failed-attempt rotation verified locally |
| V-152 | Focused/full correspondence-inbox Jest; production build; accessible-role inspection; staged diff review | `job-tracker-ui` / repository root | Verify new-message drafting uses an owned job and connected send-capable provider while reusing draft/send safety | PASS — inbox 13/13; frontend 50 suites/198 tests; build pass; owned paged jobs load, read-only provider is excluded, selectors have accessible names, empty job/re-consent guidance is visible, and saved new message uses null thread; `b735963` pushed | JSDOM/mocked APIs only; hub selector is bounded to 100 recent owned jobs; browser/provider/send/production not exercised | New-message repository flow verified locally |
| V-153 | Complete Phase 9 requirement reread; provider interface/scope/controller inventory; canonical hub and embedded correspondence action comparison | Repository root | Determine whether safe independent MAIL-001 implementation remains | PASS/PARTIAL — routing, suggestions/dismissal, link/relink/unlink, shared saved domain, provider-neutral reads/detail, reply/new-message drafts and explicit send are implemented; Gmail modify/Graph read-write and IMAP outgoing/category contracts are absent, so read/unread/pin/read-later/archive/spam/trash cannot be honestly enabled | Source inspection only; no provider/re-consent/browser/production action. Full SEC-009 deletion and real-provider gates remain | Repository scope implemented; external/authority verification blocked |
| V-154 | Phase 4 and discovery/import execution-path trace; `dotnet test ... --filter FullyQualifiedName~JobDiscoveryControllerTests --no-restore`; focused `job-discovery.test.tsx` and `quick-capture.test.tsx`; full backend/frontend; `npm run build`; `git diff --check` | Repository root / `job-tracker-ui` | Verify honest NAV provenance, explicit deadline/retrieval mapping and source preservation through reviewed import | PASS — focused backend 1/1; focused UI 2 suites and 4/4; backend 630/630; frontend 50 suites and 198/198; production build and diff check pass; `511a9f6` pushed | One npm command was initially run from repository root and failed environmentally before the correct-directory run passed. Synthetic fixtures/mocked API only; no NAV/browser/production request. Jest retains its existing force-exit/open-handle warning | Repository provenance increment verified; live/browser gates remain |
| V-155 | Focused `job-discovery.test.tsx`; full frontend Jest; `npm run build`; staged diff review | `job-tracker-ui` / repository root | Verify honest submitted-search, loading/error/retry/empty states, bounded sorting and missing-data disclosure | PASS — focused 4/4; frontend 50 suites and 201/201; production build/TypeScript and diff check pass; `3f74b23` pushed | JSDOM/mocked API only; no NAV/browser/production request. Jest retains its existing force-exit/open-handle warning | Repository UX increment verified; browser/live gates remain |
| V-156 | Focused discovery backend/UI; mocked Playwright JOBS journey; screenshot inspection; full backend/frontend/build; complete `npm run test:e2e`; staged diff review | Repository root / `job-tracker-ui` | Verify feed duplicate/withdrawal handling and discovery browser behavior across widths/themes/keyboard/long Norwegian content/reviewed import | PASS — focused backend 2/2 and UI 4/4; backend 631/631; frontend 201/201; build; Playwright 5/5 including 375/768/1440 with no overflow; dark banner contrast defect found visually, fixed and rerun; `82f4526` pushed | First two browser attempts exposed test-locator API mistakes and were corrected without weakening behavior. NAV/import responses were mocked; no external NAV/production request. Existing GSI repeated-initialize and Jest open-handle warnings remain | Synthetic/browser repository scope verified; live/production blocked |
| V-157 | Phase 10 source trace; failing computed-color browser reproduction; focused Kanban component tests; production build; mocked 1440/768/375 dark/light pointer/keyboard Playwright; screenshot inspection; full frontend and complete E2E; staged diff review | `job-tracker-ui` / repository root | Correct Kanban theme/state/accessibility/mobile behavior using shared tokens | PASS — pre-fix dark column was `rgb(245, 242, 250)`; after uses dark variable surface. Component 7/7, frontend 204/204, build and Playwright 6/6 pass; browser native hover/drag and keyboard drop each reach the mocked API; mobile owns horizontal board scroll; `fb6f17e`/`4e5ce0c` pushed | Iteration exposed CSS-variable `alpha()` incompatibility, test-theme fallback, stale locators and a one-pixel live region expressed as MUI width `1` (100%), all corrected. Mocked data/API only; GSI repeated-initialize and Jest open-handle warnings remain | Repository/browser scope verified; production/native-device gates remain |
| V-158 | Phase 11 requirement, route, `JobTable`, `JobDetailsDialog`, `ApplicationWorkspacePage`, workspace architecture and test inventory | Repository root | Reproduce JOBS-002 list-context, deep-link and presentation behavior before editing | PASS — filters/page were component-local; `?open=` was consumed and removed; row Open launched the legacy quick dialog; workspace navigation left `/jobs`, and workspace Back always returned to a fresh `/jobs`. The full-page workspace already composes the owned domain sections and remains the safe reuse boundary | Source execution-path inspection; no browser behavior relabelled as tested | Confirmed product/navigation gap |
| V-159 | Focused overlay Jest; full `npm test -- --runInBand --forceExit`; `npm run build`; `git diff --check` | `job-tracker-ui` / repository root | Verify first JOBS-002 route-backed embedded-workspace increment | PASS — focused 2/2, full frontend 51 suites and 206/206 tests, and optimized production build/TypeScript pass. Row Open creates `/jobs?workspace={id}`, direct URLs and section URLs render, close/Forward preserve history and in-memory search, the dialog has an accessible name/focus trap, mobile uses full screen, and the full-page route remains linked | JSDOM/mocked API only. Existing Jest force-exit notice remains. URL persistence of complete filter/page state, dirty-edit guards, table redesign and real browser/production checks remain | First cohesive increment verified |
| V-160 | Focused overlay/workflow Jest; direct URL query hydration; full `npm test -- --runInBand --forceExit`; production build; diff review | `job-tracker-ui` | Verify JOBS-002 URL-owned list state without breaking workspace routes or workflow links | PASS — focused 2 suites and 6/6, full frontend 51 suites and 207/207, and optimized production build/TypeScript pass. Search survives overlay Back/Forward; direct URLs hydrate status/company/location/follow-up/readiness/deleted/sort/direction/page into the API request; company loading no longer produces a MUI out-of-range state | Existing Jest force-exit notice remains; browser refresh/history still to be exercised in Playwright | Local increment verified |
| V-161 | `UsersControllerTests`; focused theme/confirm/admin-users Jest; production frontend build; native-confirm search; `git diff --check` | Repository root / `job-tracker-ui` | Verify canonical theme persistence, semantic Alert contrast ownership, app-owned destructive dialogs and final-admin safety | PASS — backend 4/4; theme/confirm 8/8; admin UI 3/3; production build/TypeScript pass; no remaining `window.confirm` in frontend. Self-demotion cancel/confirm, other-admin warning, preserved roles and final-admin disabled/API conflict paths are covered | JSDOM/local mocks only; authenticated real-browser refresh and production remain | Repository safety increment verified |
| V-162 | Focused workspace/table/workflow Jest; `ApplicationWorkspaceTests`; production frontend build; standalone TypeScript audit; route/native-popup search | Repository root / `job-tracker-ui` | Verify canonical dedicated job workspace, whole-row navigation, independent controls, list-state return, contextual section routes and richer owner-scoped details | PASS — frontend 8/8 and backend 9/9; optimized build passes; direct `/jobs/:id`, section route, return state, missing job and control isolation pass. Standalone TypeScript found only pre-existing test-prop/target errors, with no new application-source error | JSDOM/InMemory backend only; browser widths/themes/refresh and production remain. Legacy dialog source retained for rollback but is no longer reachable from the list | Repository increment verified |
| V-163 | Focused notification-popover/AppShell/Operations Jest; production frontend build; direct-navigation review | `job-tracker-ui` | Verify the header bell opens notification UI instead of routing to Reminders/Operations, while preserving global activity access | PASS — 3 suites and 6/6 tests; optimized TypeScript build passes. Popover fetch, count exposure, read, dismiss, notification-owned navigation and empty state are covered; Operations remains reachable through explicit “View all activity” | JSDOM/mocked API only; browser positioning/focus/theme and production remain | Repository increment verified |
| V-164 | Career/Profile focused Jest; CV extraction/diff backend tests; AI-sidecar pytest; production frontend build; ingestion execution-path review | Repository root / `job-tracker-ui` / `tools/summarizer` | Reproduce and fix career-field resets while assessing the proposed Ollama accuracy pipeline | PASS — Career 17/17 including active-poll preservation; backend 8/8; sidecar 22/22; build passes. Polling now fetches run status only. Existing pipeline is confirmed as local parser/OCR → Ollama-first normalize/classify → deterministic C# validation/diff/review | Synthetic/JSDOM/fake model only; no real private CV, live Ollama model comparison, provider or production call. Repository `.venv` lacked pytest; global Python passed | Repository correction verified; model benchmark remains external/runtime work |
| V-165 | CV renderer/resolver/template tests; Builder helper/editor/list Jest; optimized frontend build; real headless Chromium DOM/PDF probe; diff check | Repository root / `job-tracker-ui` | Verify professional multi-page CV rendering, physical preview metrics, custom-section ordering and stored-output safety under pathological content | PASS — backend 25/25; frontend 21/21; build passes. A 14-role/75-skill fixture with oversized name/email/URL produced zero horizontal offenders and a 9-page 173,196-byte PDF with extractable final-page text. Custom sections share persisted order; partial pages use ceiling count; stale preview/save/export races are gated | Synthetic data and local Chromium only; authenticated 375/768/1440 app journey, real private CV, production browser binary and DOCX remain unverified | Renderer/PDF repository scope verified; application-browser and production gates remain |
| V-166 | Focused/full backend and frontend tests; optimized frontend build/TypeScript; diff review | Repository root / `job-tracker-ui` | Verify an administrator can identify the deployed application version without exposing build metadata in the normal-user UI/API bootstrap | PASS — focused Auth/System 36/36 and AppShell 2/2; backend 640/640; frontend 53 suites/221 tests; production build passes. Configured version/commit reaches admin `/api/auth/me`, normal users receive no configured metadata, and the responsive header badge is absent unless the admin-owned prop is supplied | Local/JSDOM evidence only; remote CI and deployed version comparison remain. Jest retains the documented force-exit/open-handle notice | Priority repository increment verified; ship proof remains |
| V-167 | Failing Career round-trip reproduction; affected/full backend; focused Career/Profile Jest; persistence-consumer and diff review | Repository root / `job-tracker-ui` | Preserve every reviewed Career text value across save/get/version/projection/import use without weakening extraction cleanup or write bounds | PASS — pre-fix location became `Oslo, Norway and` and the test failed; post-fix affected backend 112/112, backend 642/642 and Career/Profile UI 17/17 pass. Website path/query, remote location, free-form date, custom language and incomplete WIP entry round-trip; oversized website is rejected explicitly | Local SQLite/JSDOM only; no real private CV/model/provider/production data. One initial Jest command used nonexistent paths and was corrected; the correct files passed | Reviewed/extracted normalization boundary verified locally |
| V-168 | Failing renderer contrast test; focused/full backend; CV Builder/public Jest; real Chromium computed-style/overflow probe; pathological A4 PDF export and text inspection | Repository root / `job-tracker-ui` | Make header/sidebar contact text readable for theme and custom palettes while keeping public renderer settings inert | PASS — renderer/settings 25/25, backend 644/644 and CV UI 22/22. Chromium computed white on Modern blue, black on `#f8fafc`, white on Technical sidebar, with zero element overflow. A 14-role/75-skill fixture produced a 17-page 259,447-byte A4 PDF with 1,685 final-page characters. CSS-like accent/font payloads normalize to null | Synthetic local data/browser only; authenticated application journey and production browser binary remain unverified. A direct PowerShell assembly probe failed to load dependencies before the compiled temporary test probe passed; temporary proof cleanup was blocked by execution policy | Renderer contrast/public-setting boundary verified locally |
| V-169 | Legacy-vs-dedicated workspace trace; failing package DTO/UI regressions; focused/full backend and frontend; optimized build; authenticated Playwright application journey; diff review | Repository root / `job-tracker-ui` | Close JOBS-002 application-package parity, marker encapsulation, dirty navigation, focus return, responsive/theme/history/error and tenant-safety gaps | PASS — focused backend 30/30, focused frontend 28/28 plus route/focus 6/6, backend 647/647, frontend 54 suites/227 tests, build and Playwright 7/7. Chromium covers keyboard row entry, Back/Forward, saved refresh, dirty-edit cancel, focus return, missing job and long data at 375/768/1440 in explicit light/dark with zero overflow. Cross-owner workspace read and draft write return not found | Synthetic local SQLite/account/browser only; no production/provider/private data. Two targeted browser iterations corrected locators, and a transient SQLite company-create 500 led to bounded idempotent setup retry; behavior assertions were not weakened. Existing GSI and Jest open-handle warnings remain | JOBS-002 repository/browser scope verified; production/native assistive-device gates remain |
| V-170 | Accessibility code audit; focused/full frontend; optimized build; full and targeted authenticated Playwright; computed-style contrast and nested-frame overflow probes | Repository root / `job-tracker-ui` | Close confirmed icon-name, keyboard CV-card, dark Alert contrast and fixed-width public-CV accessibility defects | PASS — static audit finds no `IconButton` without an explicit name; focused 4 suites/9 tests, full frontend 54 suites/228 tests, build, full Playwright 7/7 and final targeted 2/2. Chromium measures dark missing-job Alert contrast >= 4.5:1 and proves a 375px public CV retains a full A4 inner viewport with no inner or outer horizontal overflow | Local synthetic account/CV only; no native screen reader, operating-system high-contrast mode or production environment. Jest retains the known force-exit/open-handle warning; GSI repeats its existing initialization warning in development | Scoped cross-application accessibility repository/browser work verified; native AT and production remain |
| V-171 | Public/product claim inventory; plan/notice/usage focused Jest; current entitlement/billing-policy backend slice; full frontend; optimized build; full Playwright | Repository root / `job-tracker-ui` | Replace contradictory plan/commercial claims and prove respectful Free/Pro promotion without changing billing or enforcement | PASS — exactly Free/Pro comes from one catalogue; focused frontend 7 suites/30 tests, policy/billing backend 30/30, full frontend 57 suites/232 tests, build and Playwright 8/8. Chromium proves retired claims absent, explicit Light/Dark, 375/768/1440 no overflow and keyboard Free/Pro actions | Local synthetic account only; no Stripe checkout/webhook/portal, native AT or production. Commercial terms remain intentionally absent until configured Checkout; existing Jest/GSI warnings remain | PRODUCT-001 repository/browser scope verified; configured billing lifecycle and production remain |
| V-172 | Action-matrix reconciliation; full backend/frontend/sidecar/build/Compose/preflight gates; expanded authenticated and anonymous Playwright | Repository root / `job-tracker-ui` / `tools/summarizer` | Complete VER-001 local release regression without promoting mocked/provider/external checks | PASS — backend 647/647, frontend 57 suites/232 tests, sidecar 22/22, production build, Compose config, API-down/wrong-base/malformed-JSON preflight and Chromium 9/9. Browser covers admin deployment identity/normal-user absence, notifications, honest Free, jobs, Career/CV, Kanban, responsive themes and public PDF | No external provider, private data, native AT or production mutation. Optional Compose variables remain unset; existing Jest/GSI/SWIG warnings remain. Windows CRLF materialization was normalized for shell execution; indexed LF policy was already correct | VER-001 verified locally; remote CI/provider/native-AT/production cells remain |
| V-173 | Owner-path trace; focused CV/export/controller/background tests; full backend; build and diff hygiene | Repository root | Establish attributable generated-file ownership before SEC-009 export/deletion | PASS — CV PDFs use opaque owner/date/UUID storage while preserving download names; daily exports use opaque owner directories and atomic writes; legacy/new retention paths are covered. Focused 77/77 and backend 647/647 | No existing file moved or deleted. Legacy shared-date generated files are intentionally not guessed. No migration, production path or private data used | SEC-009 owner-scoped generated-output prerequisite verified locally |
| V-174 | Real-SQLite two-owner export fixture; manifest/checksum/file/redaction assertions; recent-session/rate-limit API tests; focused/full frontend and backend; optimized build; Chromium ZIP response | Repository root / `job-tracker-ui` | Deliver a complete user-readable export without exposing secrets or another tenant | PASS — focused backend/API 11/11, backend 650/650, frontend focused 4/4 and full 58 suites/234 tests, builds pass. Every manifest checksum/size matches; owned attachment/CV/avatar/generated/daily files are included; secret and other-owner sentinels are absent; Chromium receives HTTP 200 `application/zip` with `PK` signature | Synthetic data/files only; no production/private/provider access. Export reports backups/logs/external retention instead of claiming erasure. One initial InMemory-only test missed SQLite DateTimeOffset translation; the test moved to real SQLite and the query boundary was corrected | SEC-009 readable export verified locally; deletion/retention/restore remain |
| V-175 | Account-deletion threat-path review; real-SQLite lifecycle/controller tests; focused/full backend/frontend; optimized build; EF parity and MariaDB script generation; disposable Chromium startup/application suite | Repository root / `job-tracker-ui` | Deliver a production-inert, owner-isolated, retryable live-account deletion lifecycle without implying backup/provider erasure | PASS — focused backend 21/21, backend 657/657, frontend focused 8/8 and full 58 suites/237 tests, optimized build, no pending EF changes, bounded MariaDB script and Chromium 9/9. Tests prove disabled gate, exact/recent confirmation, immediate lockout, idempotence, owner-isolated row/file purge, quarantine failure safety, tombstone creation and restored-account replay; `842e793` pushed | Synthetic local rows/files only. No live deletion, provider revocation, sidecar restart, backup restore, production migration or retention decision occurred. Self/admin requests remain disabled by default. Full every-provider/disposable-production rehearsal remains external | SEC-009 repository scope implemented; production activation remains blocked |
| V-176 | Authorized sanitized read-only SSH inventory of OS/CPU/RAM/GPU/storage/Docker/Ollama/app health/networks/selected non-secret configuration and backup metadata/integrity | Production host / repository report | Replace stale guessed hardware/access assumptions and define evidence-based rollout stops without changing production | PASS/PARTIAL — confirmed Ubuntu 24.04.4, i5-8600 6C, 31 GiB RAM, GTX 1060 6GB, 1.4 TiB Docker-volume headroom, Ollama 0.31.1 with `qwen2.5:7b`, four healthy app containers and exact deployed version. Also confirmed all-interface 11434/3000 listeners, unlimited container resources, direct Gemini selection in the old sidecar, dirty deploy-script mode, and 21 gzip-valid database-only backups ending 2026-08-02 | No secret values, logs, prompts, private rows/content, provider call, inference, model pull, file read beyond metadata/integrity, service restart, backup creation, restore or mutation. Internet/NAT exposure, logical restore and complete file/key recovery remain unverified | PROD-001 inventory/report complete; safety acceptance blocked by measured network/backup/deployment gaps |
| V-177 | Python unit tests and plan-only execution against the checked-in synthetic fixture; script/content/SSRF/report review | Repository root | Prepare reproducible privacy-safe PROD-003 evaluation without authorizing a model or network call | PASS — harness tests 4/4; plan validates four Strategy cases across 4K/8K for eight future requests. Default performs no HTTP; exact model, `--execute` and explicit output are required; model pull/delete is absent; report excludes raw fixture/prompt/output content | No Ollama request, provider/internet access, model metadata query through the harness, candidate pull, inference or production change. Candidate metadata/licenses/results and model decision remain unmeasured | PROD-003 repository harness complete; execution remains blocked |
| V-178 | Benchmark harness safety tests, plan-only execution and CI workflow inspection | Repository root | Prevent an approved private Ollama origin from escaping through proxy settings or redirects and make the boundary a release gate | PASS — 5/5 standard-library tests; proxy discovery is disabled, redirects are refused, plan-only output remains eight future Strategy requests, and CI now runs the suite without dependencies or network execution | No network, Ollama, provider, package or production call occurred | Benchmark request boundary corrected and CI-enforced |
| V-179 | Account-deletion real-SQLite failure/retry tests; sidecar token/cache tests; full backend; Compose validation | Repository root / `tools/summarizer` | Remove the live sidecar-cache and shared tombstone-path gaps without enabling deletion | PASS — lifecycle 6/6, backend 658/658, sidecar 23/23 and Compose config pass. Sidecar failure withholds completion/tombstone until retry; maintenance purge is token-protected; tombstones map to a separate named volume; activation defaults false | Synthetic rows/cache only; no production volume, deletion, restart, provider revocation, backup restore or retention decision | SEC-009 repository cache/storage boundary complete; production activation remains blocked |
| V-180 | CV operation/store focused real-SQLite tests and full backend | Repository root | Keep dormant CV extraction history consistent with cancellation, deadline recovery and retry before worker claim | PASS — focused 17/17 and backend 660/660. Cancel sets the run terminal immediately, retry reopens it, deadline recovery fails it, and owner/task/subject predicates prevent unrelated updates | Synthetic rows only; no parser/model/MariaDB/production process interruption | AI-004 dormant-row consistency gap closed |
| V-181 | AI usage meter/operation/workspace/export/deletion real-SQLite tests; EF model check; SQLite/MariaDB scripts; disposable SQLite backfill and fresh application startup; full backend | Repository root | Make Workspace and durable Strategy/CV usage owner-safe, idempotent and independent of deletable private history | PASS — focused 28/28 and backend 663/663; no pending model changes; both providers generate bounded additive DDL; SQLite backfills the synthetic legacy row exactly once; fresh runtime applies through `20260815175236_AddCrossFeatureAiUsage` and serves `/health` | Synthetic local rows only; no provider/model call, MariaDB server, production migration or worker activation. CV retains a conservative reservation and older synchronous AI paths are not yet universal | Main durable usage boundary implemented; remaining synchronous producers stay tracked under POL-001 |
| V-182 | Real ASP.NET Identity data-protection token integration on SQLite; focused auth tests; full backend | Repository root | Close SEC-005B expiry/replay/custom-username proof without SMTP or production | PASS — valid confirmation succeeds once, replay and zero-lifetime expiry return the same generic failure, a real change-email token preserves a custom username and cannot replay; focused 39/39 and backend 666/666 | Synthetic addresses and ephemeral local data-protection keys only; no email, browser, MariaDB or production call | SEC-005B local token-state gap closed |