Appearance
Handoff: SVC-009-exam-attempt-public-proof
Scope
- Dispatch ID:
SVC-009 - Service:
exam-service - Task pack:
docs/agents/service-tasks/exam-service.md - Next task:
SVC-009-exam-attempt-public-proof - Goal: prove exam authoring/start contracts with attempt-service plus live/browser evidence before public route promotion.
- Status: accepted bounded contract slice, not service completion.
Docs Read
docs/agents/service-agent-next-slice-queue.jsondocs/agents/service-agent-next-slice-closeout-ledger.jsondocs/agents/service-tasks/exam-service.mddocs/agents/handoff-phase-7-exam-snapshots.mddocs/qa/exam-authoring-route-rehearsals.mddocs/qa/exam-attempt-public-proof.mddocs/api/exam-service.md
Legacy Evidence Read
/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/exams/exam-core.service.ts/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/exams/exams.controller.ts/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/exams/exams.controller.spec.ts/Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/exams/exam-core.service.spec.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.
Files Changed
services/attempt-service/internal/usecase/attempt.goservices/attempt-service/internal/usecase/event_result.goservices/attempt-service/internal/http/server_test.godocs/qa/exam-attempt-public-proof.mddocs/agents/handoffs/SVC-009-exam-attempt-public-proof.mddocs/agents/service-tasks/exam-service.md
Behavior Implemented
- Verified a real in-memory
exam-servicepublished snapshot throughruntime-access, then through Gatewayexam_start_adapterinto a real in-memoryattempt-service. - The temporary IAM/classroom verifier fixture required the real
X-Internal-Service,X-Internal-Token, actor, role, and organization headers before returning an active organization-membership decision. - Fixed a public response leak found during the proof:
Startand idempotent start replay now return the same student projection as attempt reads. It removes optionisCorrect, non-empty answer keys, scoring rules, source snapshots, and explanations until a result is visible. - Attempt creation, answers, grading, and results remain attempt-service owned; the default Gateway table remains unchanged.
Required Evidence
- exam-attempt contract proof: a direct
runtime-accesscall on the seeded published snapshot returned an allowedexam-servicedecision with verified password, one question, and no access-link code or password hash inoutput/qa/exam-attempt-public-proof-20260713/authoring/. - authorization regression proof: focused runtime-access tests still cover the fail-closed verifier behavior; the local fixture proves the configured verifier contract only, not a deployed IAM/classroom stack.
- live/browser proof: Gateway list/start/detail/save/event/submit/result and post-grade idempotency replay passed against real local services. Chromium read smoke passed from a same-origin
/healthzshell, not from the student UI. - rollback notes: the unchanged default
deploy/gateway/routes.jsonreturned502withexams/legacy_proxyandattempts/legacy_proxyagainst a deliberately unavailable legacy target.
Tests And Verification
GOTOOLCHAIN=go1.25.11 go test ./services/exam-service/... -count=1GOTOOLCHAIN=go1.25.11 go test ./services/exam-service/internal/usecase ./services/exam-service/internal/http -run 'TestExamRuntimeAccess|TestRuntimeAccessRouteReturnsAttemptStartInput' -count=1 -vGOTOOLCHAIN=go1.25.11 go test ./services/attempt-service/internal/http -run TestStartAttemptHTTP -count=1 -vGOTOOLCHAIN=go1.25.11 go test ./services/attempt-service/internal/usecase -count=1make test-exam-authoring-routesmake test-attempt-routes
All commands passed. The local browser smoke proves authenticated browser fetch and route headers, but not the student-facing application workflow.
Route State
- Route/default state: exam authoring/start promotion requires exam-attempt contract proof plus live/browser and rollback proof.
- Default exam, attempt, and fallback routes remain legacy-proxied.
- The candidate table was only
deploy/gateway/routes.attempt-native-localhost-example.jsonat127.0.0.1:18085; it was stopped after proof.
Data Notes
- Exam-service owns exam snapshots, access-link policy, assignments, and access decisions.
- Attempt-service owns attempts, answers, grading, and results.
- Question snapshots are copied by value; no cross-service question DB reads.
Risks / Blockers
- The proof uses memory stores and a local IAM/classroom verifier fixture, not persistence or deployed downstream services.
- The Chromium run executes same-origin API fetches from
/healthz; real student UI navigation, rendering, and authenticated session behavior remain open. - Full legacy share-link CRUD and guest-registration parity remain future work.
Rollback Notes
These are the rollback notes for the accepted bounded slice and were exercised:
- Set
GATEWAY_ROUTE_TABLE=deploy/gateway/routes.json. - Disable any non-default exam/attempt rehearsal caller.
- Rerun
make test-exam-authoring-routesandmake test-attempt-routes.
Next Step
Before any default-route promotion, run a deployed IAM/classroom-backed proof and an actual student application browser workflow; retain the legacy route table until both are captured.