Appearance
Handoff: SVC-010-attempt-public-idempotency-proof
Scope
- Dispatch ID:
SVC-010 - Service:
attempt-service - Task pack:
docs/agents/service-tasks/attempt-service.md - Next task:
SVC-010-attempt-public-idempotency-proof - Goal: prove the native attempt workflow and idempotency/result policy before public route promotion.
- Status: accepted bounded contract slice, not service completion.
Docs Read
docs/agents/service-tasks/attempt-service.mddocs/agents/handoffs/SVC-010-timeout-retake-result-visibility.mddocs/agents/service-agent-next-slice-queue.jsondocs/agents/service-agent-next-slice-closeout-ledger.jsondocs/qa/attempt-live-smoke.mddocs/qa/attempt-browser-smoke.mddocs/api/attempt-service.md
Legacy Evidence Read
/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/attempts/attempts.controller.ts/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/app-data/app-data.exams-attempts.ts/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/app-data/app-data.exam-runtime-core.ts/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/prisma/schema.prisma
Legacy source was read-only evidence. No file under /Users/velikho/Desktop/WORKING/HOCTAPAZ/ was changed.
Behavior Implemented
TestStartAttemptHTTPproves the HTTP workflow from trusted runtime start through copied snapshots, answer save, event write, submit/grading, and result read with answer-key redaction.TestStartAttemptHTTPReplaysIdempotencyKeyAfterSubmitproves exact replay returns the original graded attempt withcreated=false.- Usecase tests prove open-attempt reuse, submitted-attempt retake counting, durable idempotency, timeout submission, and
IMMEDIATE,AFTER_CLOSE, andMANUALresult visibility. - Direct public-compatible start bodies remain rejected unless the gateway or BFF supplies the exam-service decision marker and idempotency context.
- On 2026-07-13, a disposable local proof ran a trusted runtime-access fixture on
127.0.0.1:8090, in-memoryattempt-serviceon127.0.0.1:8091, and Gateway with the non-default attempt table on127.0.0.1:18085. A separately signed student JWT passed list -> start -> detail -> answer save -> event -> submit -> result through the Gateway. The submitted attempt wasGRADEDand itsIMMEDIATEresult was visible without answer-key leakage. - Replaying the exact
X-Correlation-Idafter grading returned the same attempt withcreated=falseandGRADEDstatus. Chromium then read the list/detail/events/result routes through the same native Gateway table. - Gateway rollback was rehearsed by restarting it with
deploy/gateway/routes.jsonandLEGACY_API_BASE_URL=http://127.0.0.1:59999: native candidates returned502throughexams/legacy_proxyandattempts/legacy_proxy. Default routes were not changed. - Required evidence: attempt route proof, idempotency proof, and live/browser rollback proof are recorded by the bounded local artifacts below. They do not remove the real
exam-serviceor student UI parity gates.
Files Changed
docs/qa/attempt-public-idempotency-proof.mddocs/agents/handoffs/SVC-010-attempt-public-idempotency-proof.mddocs/agents/service-tasks/attempt-service.mddocs/qa/attempt-live-smoke.mddocs/qa/attempt-browser-smoke.mdscripts/test/attempt-live-smoke.shscripts/test/attempt-browser-smoke.mjsdocs/agents/service-agent-next-slice-closeout-ledger.jsondocs/agents/service-agent-next-slice-closeout-ledger.mddocs/agents/service-agent-accepted-handoffs.mddocs/agents/service-tasks/attempt-service.mddocs/api/attempt-service.mddocs/index.mddocs/.vitepress/config.tsdocs/qa/service-agent-goal-completion-audit.mddocs/qa/service-agent-readiness-smoke.md
Tests And Verification
GOTOOLCHAIN=go1.25.11 go test ./services/attempt-service/... -count=1make test-attempt-routesATTEMPT_LIVE_SELF_TEST=1 bash scripts/test/attempt-live-smoke.shATTEMPT_BROWSER_SELF_TEST=1 bash scripts/test/attempt-browser-smoke.sh- Non-default runtime artifacts:
output/qa/attempt-public-idempotency-proof-20260713/final-live/andoutput/playwright/attempt-public-idempotency-proof-20260713/. - Default rollback artifact:
output/qa/attempt-public-idempotency-proof-20260713/rollback-default/.
The focused tests, route guards, self-tests, local Gateway workflow, browser read smoke, exact replay assertion, and default rollback assertion passed.
Route State
- Default
/api/exams/*/start,/api/student/attempts, and/api/attempts*remain legacy-proxied. - Native attempt routes remain non-default rehearsals.
- Route state: public attempt route promotion requires route, live, browser, idempotency, and rollback proof; it remains an explicit review decision and the default table still routes attempt surfaces to legacy.
- Rollback uses
GATEWAY_ROUTE_TABLE=deploy/gateway/routes.json; rerunmake test-attempt-routesand the relevant smoke checks.
Risks / Blockers
- The runtime-access response came from a disposable fixture, not a seeded running
exam-serviceinstance. - Browser evidence uses the Gateway health page as a same-origin shell and verifies fetches/headers; it is not a student exam-room UI parity test.
- Attempt-service is not complete migration proof; legacy parity and default route promotion remain open.
- Future adapters must preserve exam-service ownership of access decisions and never hydrate attempts from current question-service rows.
Next Step
Seed a published exam through a running exam-service and exercise the actual student exam-room frontend before proposing any default route promotion.