Appearance
Exam Blueprint Generation Runtime Proof
Scope
This proof covers the bounded native workflow:
- Seed published canonical questions in
question-bank-servicefor one teacher and organization. - Create a matrix in
exam-servicethroughbff-service. - Generate both
ONLINEandOFFLINEdrafts through the BFF adapter. - Verify that
exam-servicehas immutable snapshots while Question Bank remains the source, then remove all temporary rows.
Boundaries
question-bank-serviceselects tenant/actor-scopedPUBLISHEDquestions.exam-serviceowns drafts and snapshot rows; it does not read Question Bank storage directly.bff-serviceforwards actor scope only and owns no primary database.- The default Gateway route table remains legacy. This proof uses direct owner routes or the documented non-default BFF/Gateway rehearsal configuration.
Runtime Gate
Rebuild the three services from the same worktree, then capture request IDs, generated IDs, deliveryMode, snapshot answer content, cross-owner rejection, and final cleanup query. Do not claim default-route or browser promotion from this proof alone.
bash
docker compose -f deploy/docker-compose.yml build question-bank-service exam-service bff-service
docker compose -f deploy/docker-compose.yml up -d --no-deps question-bank-service exam-service bff-service
curl -fsS http://127.0.0.1:8089/readyz
curl -fsS http://127.0.0.1:8090/readyz
curl -fsS http://127.0.0.1:8102/readyzAccepted Local Evidence (2026-07-12)
All three rebuilt local services returned ready on ports 8089, 8090, and 8102.
- Seeded two
PUBLISHEDQuestion Bank questions fororg_exam_blueprint_generation_live_20260712: one grouped question and one ungrouped question, both filtered by the samechapterIdandtopicId. - Created matrix
ebp_1aa3dc9a00c36be1611135c8cb162e9dthrough BFF with the first rule requiring a group and the second rule receiving the remaining question through source-side duplicate exclusion. POST /v1/bff/teacher/exam-blueprints/{id}/generategenerated online draftexam_babd3a708f98192423e43a1baa16289c(workflow=exam,deliveryMode=ONLINE) and offline draftexam_0a5a59a85d72fb113f3cdc95255f0cdd(workflow=tron-de,deliveryMode=OFFLINE). Each returnedquestionCount=2, total score3, and aRANDOM_PER_EXAMsaved shuffle flag.- Snapshot read for the online draft preserved the source question versions, rich content text, correct option IDs, answer keys, explanations, score, order, source service, matrix ID, and rule ID. Logs show Question Bank internal selection
200, Exam generation201, and BFF generation201for both requests. - A different teacher in the same organization received
404 BFF_NOT_FOUNDwhen attempting matrix generation. - Cleanup removed both drafts through Exam API, the matrix through BFF, both canonical questions through Question Bank API, and the now-empty temporary group. PostgreSQL verification returned:
text
exams=0
snapshots=0
blueprints=0
rules=0
questions=0
groups=0Offline DOCX Evidence (2026-07-12)
The native offline export path was also exercised without allowing the matrix screen to fabricate a file result:
- Created BFF matrix
ebp_3aeccb61be8b44e9eeeec192b8e8d583with a grouped and an ungrouped published Question Bank question, then generated offline draftexam_79612d7a5ed16a1c789b84da69fe244busingworkflow=tron-de,deliveryMode=OFFLINE, andRANDOM_PER_ATTEMPT. - Created owner-scoped print template
ept_3475469a0cbe34da110734c3c141e9a2, then exportedepe_392fc434b4742c00fd854c433ce48d8cthrough BFF. The export completed with a Document Service media asset and a 3,212-byte DOCX payload. - Download through the BFF content route returned HTTP
200, the DOCX media type, a validPKZIP signature, and passedunzip -t. Its Word XML contained both question bodies, correct answers, and explanations from the immutable Exam snapshots. - A second teacher in the same organization received
404 BFF_NOT_FOUNDfor the exported content. This confirms that theexamIdhandoff remains owner-scoped at the BFF boundary. - Cleanup deleted the object through Document Service, the exact media/export rows, template and exam through Exam Service, blueprint through BFF, and canonical questions through Question Bank. Final PostgreSQL checks returned:
text
exams=0
snapshots=0
blueprints=0
rules=0
print_exports=0
print_templates=0
media_assets=0
questions=0
question_groups=0Physics DOCX Matrix Evidence (2026-07-13)
The bounded workflow was re-run against the real MẪU 2 - MÔN LÝ - HOCTAPAZ.docx corpus fixture, rather than Question Bank seed data. An isolated Compose project rebuilt Import, Go Formula, Document, Question Bank, Exam, and IAM. A separately started BFF instance was restricted to the exam-service upstream and listened only on a temporary host port.
The resulting artifact is output/qa/docx-physics-exam-blueprint-runtime-20260713122942851/summary.json. It proves the following source-owned handoff:
- Import parsed and approved all 28 Physics rows to
PUBLISHEDQuestion Bank records for one isolated organization: 18SINGLE_CHOICE, 6SHORT_NUMERIC_ANSWER, and 4TRUE_FALSE_GROUP. - Read-back from Question Bank found 28 canonical answer keys, 7 media references, and 84 formula references. Those values were not reconstructed by Exam Service.
POST /v1/bff/teacher/exam-blueprintsstored three exact matrix rows for the same 18/6/4 type distribution. The BFF then generated both anONLINEexamworkflow and anOFFLINEtron-deworkflow.- Each draft returned
questionCount=28. Direct Exam owner reads found 28 immutable snapshots with the same type distribution, 28 answer keys, 7 media references, 84 formula references, and the exact originating blueprint id in everysourceSnapshotJson. - An owner print template rendered the offline draft to a 10,254-byte DOCX. It passed
unzip -t;word/document.xmlcontainedPHIẾU TRẢ LỜIandĐÁP ÁN VÀ LỜI GIẢI. - A matrix requiring one unavailable
ESSAYquestion failed through BFF with HTTP400before any draft could be created. This prevents a partial matrix from silently creating an incomplete exam.
The repeatable opt-in smoke starts a fresh Compose project itself, exposes only the owner/BFF endpoints on loopback, then removes its containers, network, and volumes. It does not use the developer's parser or the default Gateway route table:
bash
DOCX_PHYSICS_EXAM_BLUEPRINT_ISOLATED_CONFIRM=docx-physics-exam-blueprint-isolated \
HOCTAPAZ_DOCX_CORPUS_DIR=/Users/velikho/Desktop/test-hoctapaz \
make test-docx-physics-exam-blueprint-isolatedThe overlay deploy/docker-compose.docx-physics-exam-blueprint-proof.yml maps only Import, Question Bank, Exam, BFF, and AI to five temporary free 127.0.0.1 ports selected by the runner; no developer port is reused or stopped. The harness writes a new local artifact under output/qa/docx-physics-exam-blueprint-runtime-* before cleanup. This is local isolated proof. It does not alter deploy/gateway/routes.json, promote any default public route, assert browser parity, or make a production claim.
Fresh Compose Revalidation (2026-07-14)
The latest disposable run wrote output/qa/docx-physics-exam-blueprint-runtime-20260714074442729/ and passed the complete Physics fixture workflow. The verifier observed 28 approved questions with the expected 18 single-choice, 6 short-numeric, and 4 true/false-group distribution; all 28 answer keys, seven media assets, 84 formula references, 16 true/false statements, and five source solutions were retained in Question Bank.
The BFF created matching online and offline snapshots with the same copied media/formula/answer evidence. The owner Word template contained seven embedded media parts, 62 OMML formulas, 22 explicit formula-review fallbacks, and the 16 true/false statements. The same run verified preview-only AI similar-question and solution generation, followed by the reviewed Question Bank writes, and rejected an insufficient ESSAY matrix through BFF before a partial draft was created. Compose cleanup removed the isolated project, containers, network, and volumes after the artifact was written.
DOCX_PHYSICS_EXAM_BLUEPRINT_ISOLATED_SELF_TEST=1 make test-docx-physics-exam-blueprint-isolated validates that topology before a runtime is created. It requires the five selected public ports, the Import, Exam, BFF, and AI dependency closures, and no host ports for shared storage, database, parser, attempt, usage, wallet, or identity services.
Local Postgres Recheck (2026-07-14)
When Docker is unavailable, the same owner/BFF workflow can run against a new native PostgreSQL cluster without reusing any developer service or database:
bash
DOCX_PHYSICS_EXAM_BLUEPRINT_LOCAL_POSTGRES_CONFIRM=local-postgres \
HOCTAPAZ_DOCX_CORPUS_DIR=/Users/velikho/Desktop/test-hoctapaz \
make test-docx-physics-exam-blueprint-local-postgresThe runner creates five service-owned databases (document, docx_import, question_bank, exam, and ai_classifier) beneath one temporary PostgreSQL cluster. It starts Document, Import, Question Bank, Exam, BFF, and AI Classifier on fresh loopback ports. Import materializes the source media in Document through the temporary internal token; Exam resolves those same owned assets while rendering the Word template. Document metadata is PostgreSQL, but the object bytes deliberately use the disposable in-memory store, so neither is evidence for persistent object storage.
The latest 2026-07-15 artifact is output/qa/docx-physics-exam-blueprint-local-postgres-20260715114605/summary.json. It imported and approved all 28 Physics questions, retained the 18/6/4 type split, 28 answer keys, seven media refs, 84 formula refs, 16 true/false statements, and five source solutions. It generated both online and offline 28-question snapshots, rendered a 933,276-byte DOCX with seven embedded media parts, 62 OMML formulas, 22 visible formula fallbacks, and five solutions. Mock AI preview did not write a question; the explicit teacher review created one draft, and the reviewed solution updated only the existing question version.
The same harness then created a second Physics job and exercised the direct EXAM_DRAFT approval state machine, not the BFF blueprint route. Replaying the identical approval returned the same 28 Question Bank IDs and Exam ID with reused=true. Direct owner reads confirmed one Exam, 28 scoped Question Bank rows, and 28 snapshots with the canonical 18/4/6 type distribution, 16 true/false statements, seven media refs, 84 formula refs, and five source solutions. The fresh stores therefore finished with 14 media assets, two import jobs, 57 Question Bank rows (including the reviewed AI draft), and three Exams.
This is completed-operation replay evidence. The Import unit regression also injects one checkpoint-save failure after each of the Question Bank and Exam owner responses, and verifies stable owner keys on retry. It has not fault-injected an actual process stop or PostgreSQL outage between an owner write and the following Import checkpoint save.
Cross-fixture Review-safe Recheck (2026-07-15)
The same temporary native owner/BFF topology now covers the reviewed Math, English, and DGNL corpus subsets with DOCX_CORPUS_EXAM_BLUEPRINT_LOCAL_POSTGRES_CONFIRM=local-postgres make test-docx-corpus-exam-blueprint-local-postgres. Artifact: output/qa/docx-corpus-exam-blueprint-local-postgres-20260715113710/summary.json.
The runner holds the full parser and review-subset baselines at Math 22 -> 13 (12 single choice, 1 short numeric, two media, 28 formula refs), English 40 -> 34 (28 single choice, 6 passage), and DGNL 102 -> 37 single choice. Each untouched EXAM_DRAFT approval failed with no canonical write; the saved review then passed direct replay, a BFF ONLINE/OFFLINE matrix, and a document-service Word export with metadata and checksum verification. This is still direct local owner/BFF evidence, not default Gateway, browser, visual-rendering, public-provider, or production proof.
Latest Refresh (2026-07-15)
output/qa/docx-corpus-exam-blueprint-local-postgres-20260715122636/summary.json repeated the review-safe corpus workflow over fresh Document, Import, Question Bank, Exam, and BFF stores. It created three checksum-verified Word exports and preserved every selected source ID, answer key, type, media and formula reference in direct, online, and offline snapshots: Math 13, English 34, and DGNL 37. Before cleanup, the disposable databases contained 84 canonical questions, nine exams, 252 snapshots, three import approvals, three print exports, and ten media assets. The runner removed every temporary listener and PostgreSQL byte. The excluded Math, English, and DGNL rows remain teacher-review-required; this does not establish default Gateway, browser, or production behavior.
This remains isolated owner/BFF evidence: no Gateway, browser, OCR provider, attempt session, default route, shared runtime, or production claim is covered.
Current Isolated Recheck (2026-07-14)
output/qa/docx-physics-exam-blueprint-runtime-20260714002758359/summary.json was produced by the reusable isolated target. Its loopback ports were selected at runtime (57633 through 57637), avoiding the occupied developer port that previously prevented the stack from starting. The fresh project parsed and approved the 28-question Physics DOCX fixture, then verified the canonical Question Bank 18/6/4 type split, 28 answer keys, 7 media refs, 84 formula refs, 16 ordered true/false statements, and 5 source-keyed solutions.
Both generated Exam snapshots retained those totals. The offline Word artifact was 933,278 bytes, passed its OpenXML checks, embedded all seven media parts, contained 62 OMML formulas plus 22 visible review fallbacks, and retained all five solutions. Mock AI similar/explanation previews left the canonical count at 28 until the explicit teacher-reviewed Question Bank write created one draft; the reviewed explanation advanced only the referenced question version. An unavailable blueprint rule returned 400 before creating a partial exam. The runner removed its Compose project and volumes after the artifact was written; no dynamic ports or containers remained.