Skip to content

Service Agent Wave Board ​

Status: orchestrator-owned dispatch board for service owner agents.

Use this board with docs/agents/service-agent-manifest.json, docs/agents/service-agent-proof-ledger.json, docs/agents/service-agent-closeout-ledger.json, docs/architecture/service-responsibility-matrix.md, docs/agents/service-agent-dispatch-roster.md, and the per-service packs in docs/agents/service-tasks/. Each worker owns one canonical service row for a small vertical slice. The worker must read its task pack first, audit legacy evidence, then code/test/fix only inside the assigned writable scope.

Dispatch Rules ​

  • One service owner per implementation directory at a time.
  • Alias services must use the current implementation directory listed here; do not create duplicate directories for canonical names.
  • Shared files such as root Make targets, Compose, Helm, K8s, gateway route tables, generated OpenAPI indexes, and docs navigation stay orchestrator-owned unless explicitly delegated.
  • Public route cutovers are separate tasks. A service foundation or route rehearsal does not imply default gateway promotion.
  • Persisted sourceService ids in search/sync/event projections use the current implementation id unless a versioned migration says otherwise. Current examples: question-bank-service, course-service, exam-service, document-service, docx-import-service, and ai-classifier-service.
  • Every worker closeout must list docs read, legacy files read, files changed, tests run, rollback notes, and next task.
  • The service-agent closeout ledger is the machine-readable acceptance gate for that handoff evidence; update it only after the handoff exists and passes make test-service-agent-closeout-ledger.
  • spawn-ready in the proof ledger is a dispatch state only. It is not a service completion claim.

Current Waves ​

WaveServicesPurposeParallelism
0OrchestratorKeep matrix, task packs, deploy/env coverage, and shared route examples coherent.Single owner.
1api-gateway, iam-service, profile-service, organization-service, classroom-service, bff-serviceEntry, identity, profile, tenant/class foundations.Parallel by service; IAM/organization membership changes need explicit contract handoff.
2question-service, exam-service, attempt-service, course-service, file-service, import-service, formula-docx-service, search-serviceLearning, import, exam runtime, and rebuildable discovery.Parallel by service; import approval/exam/question/search contracts must be versioned before shared edits.
3ai-service, billing-service, wallet-service, usage-service, payment-serviceAI workload and monetization foundations.Parallel by service; usage/wallet/billing/payment event contracts stay orchestrator-owned until stabilized.
4notification-service, audit-service, analytics-service, admin-serviceOperational read models, governance, admin workflows.Parallel by service; admin must not absorb audit/payment/wallet/IAM source-of-truth logic.
Ruser-serviceRetirement only. No new product work.One compatibility owner when parity evidence is ready.

Service Rows ​

Dispatch IDCanonical serviceCurrent implementationTask packCurrent agent missionRequired verification
SVC-001api-gatewayservices/api-gatewaydocs/agents/service-tasks/api-gateway.mdKeep frontend entrypoint single, JWT/JWKS verification compatible with IAM, and route rehearsals rollback-safe.GOTOOLCHAIN=go1.25.11 go test ./services/api-gateway/... plus named route targets for touched surfaces such as make test-auth-routes test-auth-routes-live test-auth-routes-browser test-auth-routes-session-browser test-profile-routes test-organization-routes test-attempt-routes test-bff-routes; exam_start_adapter slices also require make test-attempt-live and make test-attempt-browser before public promotion.
SVC-002bff-serviceservices/bff-servicedocs/agents/service-tasks/bff-service.mdBuild frontend-specific aggregation without a primary business DB and without hiding domain logic.GOTOOLCHAIN=go1.25.11 go test ./services/bff-service/... and make test-bff-routes when gateway routes change.
SVC-003iam-serviceservices/iam-servicedocs/agents/service-tasks/iam-service.mdOwn identity, credentials, sessions, JWT/JWKS, roles, permissions, invites, and permission-bearing org membership.GOTOOLCHAIN=go1.25.11 go test ./services/iam-service/..., make test-auth-routes, AUTH_ROUTE_LIVE_SELF_TEST=1 make test-auth-routes-live, AUTH_ROUTE_BROWSER_SELF_TEST=1 make test-auth-routes-browser, AUTH_SESSION_BROWSER_SELF_TEST=1 make test-auth-routes-session-browser, make test-organization-routes, and ORGANIZATION_MEMBERSHIP_WRITE_SELF_TEST=1 make test-organization-membership-write-live when membership routes change.
SVC-004profile-serviceservices/profile-servicedocs/agents/service-tasks/profile-service.mdOwn education profile/display data and keep password/JWT/role/payment state out.GOTOOLCHAIN=go1.25.11 go test ./services/profile-service/... plus make test-profile-routes test-profile-kyc-routes test-profile-admin-kyc-routes, PROFILE_ROUTE_LIVE_SELF_TEST=1 make test-profile-routes-live, and PROFILE_ROUTE_BROWSER_SELF_TEST=1 make test-profile-routes-browser when profile gateway routes change; default promotion remains orchestrator-owned.
SVC-005organization-serviceservices/school-service aliasdocs/agents/service-tasks/organization-service.mdOwn schools/centers/campuses/org metadata; coordinate IAM-owned membership policy.GOTOOLCHAIN=go1.25.11 go test ./services/school-service/... and make test-organization-routes when gateway routes change.
SVC-006classroom-serviceservices/classroom-servicedocs/agents/service-tasks/classroom-service.mdOwn classes, members, teacher assignments, and class progress read models.GOTOOLCHAIN=go1.25.11 go test ./services/classroom-service/... plus make test-classroom-route-guard when classroom public routes change.
SVC-007course-serviceservices/course-servicedocs/agents/service-tasks/course-service.mdOwn courses/modules/lessons/material metadata/enrollments/progress, not question/exam attempts.GOTOOLCHAIN=go1.25.11 go test ./services/course-service/... plus make test-student-course-routes test-student-course-progress-routes and STUDENT_COURSE_BROWSER_SELF_TEST=1 make test-student-course-browser; docs/qa/student-course-route-rehearsals.md keeps live/browser proof required before course gateway promotion.
SVC-008question-serviceservices/question-bank-service aliasdocs/agents/service-tasks/question-service.mdOwn canonical questions, answers, solutions, types, tags, taxonomy refs, editor write save/reload parity, and question search projections.GOTOOLCHAIN=go1.25.11 go test ./services/question-bank-service/... plus make test-question-read-routes test-question-types-routes test-question-classification-apply-routes, make test-question-write-routes, QUESTION_WRITE_SELF_TEST=1 make test-question-write-live, QUESTION_WRITE_BROWSER_SELF_TEST=1 make test-question-write-browser, make test-question-types-live test-question-types-browser, and make test-question-read-browser test-question-read-browser-admin for route slices.
SVC-009exam-serviceservices/exam-servicedocs/agents/service-tasks/exam-service.mdOwn exam authoring, snapshots, publish/access workflow, assignments, and exam search projections.GOTOOLCHAIN=go1.25.11 go test ./services/exam-service/... plus make test-exam-authoring-routes; docs/qa/exam-authoring-route-rehearsals.md keeps live/browser proof required before exam authoring promotion; runtime-access/start-adapter slices also require make test-attempt-routes, make test-attempt-live, and make test-attempt-browser.
SVC-010attempt-serviceservices/attempt-servicedocs/agents/service-tasks/attempt-service.mdOwn attempt sessions, attempt-owned snapshots, answers, grading, events, results, and copied result-release propagation.GOTOOLCHAIN=go1.25.11 go test ./services/attempt-service/...; public attempt/start slices also require make test-attempt-routes, make test-attempt-live, and make test-attempt-browser.
SVC-011file-serviceservices/document-service aliasdocs/agents/service-tasks/file-service.mdOwn files/media/object metadata/signed reads and keep parsing/credit charging out.GOTOOLCHAIN=go1.25.11 go test ./services/document-service/... plus make test-storage-media-parity; docs/qa/storage-media-parity-smoke.md keeps browser proof required before public storage promotion.
SVC-012import-serviceservices/docx-import-service aliasdocs/agents/service-tasks/import-service.mdOwn import jobs, parse orchestration, preview/review, approval handoffs, and next PDF/OCR/MathType status/download slices.GOTOOLCHAIN=go1.25.11 go test ./services/docx-import-service/... plus make test-import-create-routes test-import-status-routes test-import-approval-routes test-import-review-roundtrip-routes and the matching live/browser smoke target for changed workflows.
SVC-013formula-docx-servicesource-controlled runtimes/go-formula-docx runtime behind import adaptersdocs/agents/service-tasks/formula-docx-service.mdMaintain parser runtime integration and adapter evidence; do not create services/formula-docx-service without a later ADR.sh scripts/test/go-formula-runtime-coverage.sh, make test-docx-corpus, and GOTOOLCHAIN=go1.25.11 go test ./services/docx-import-service/internal/parser/docx -count=1 when parser behavior changes.
SVC-014search-serviceservices/search-servicedocs/agents/service-tasks/search-service.mdOwn rebuildable copied indexes and sync checkpoints; never owner business data or course-service-owned /api/public/catalog* compatibility.GOTOOLCHAIN=go1.25.11 go test ./services/search-service/... -count=1, make test-search-rebuild, and make test-search-routes; any route rehearsal must cite the exact legacy route/controller mapping first.
SVC-015ai-serviceservices/ai-classifier-service aliasdocs/agents/service-tasks/ai-service.mdOwn AI provider adapters/jobs/prompts/results plus generate/explain/grade contracts; call usage/wallet through explicit APIs only and never own quota checks or credit movement.GOTOOLCHAIN=go1.25.11 go test ./services/ai-classifier-service/..., make test-ai-classification-job-route-guard, AI_CLASSIFICATION_JOB_SELF_TEST=1 make test-ai-classification-job-live, and make test-question-classification-apply-routes; run make test-monetization-event-chain when touching usage/wallet handoff contracts, and use make test-question-classification-apply-live only for explicit live write smoke.
SVC-016billing-serviceservices/billing-servicedocs/agents/service-tasks/billing-service.mdOwn plans, subscriptions, invoices, and commercial entitlements.GOTOOLCHAIN=go1.25.11 go test ./services/billing-service/... plus make test-monetization-event-chain and make test-monetization-broker-transport.
SVC-017wallet-serviceservices/wallet-servicedocs/agents/service-tasks/wallet-service.mdOwn AZ Credits, balances, immutable ledger, grants/debits/refunds.GOTOOLCHAIN=go1.25.11 go test ./services/wallet-service/... plus make test-monetization-event-chain test-monetization-routes and make test-monetization-broker-transport.
SVC-018usage-serviceservices/usage-servicedocs/agents/service-tasks/usage-service.mdOwn feature gates, quota periods, usage counters, check/consume/reset APIs.GOTOOLCHAIN=go1.25.11 go test ./services/usage-service/... plus make test-monetization-event-chain and make test-monetization-broker-transport.
SVC-019payment-serviceservices/payment-servicedocs/agents/service-tasks/payment-service.mdOwn payment orders, provider transactions, webhooks, reconcile/idempotency.GOTOOLCHAIN=go1.25.11 go test ./services/payment-service/... plus make test-monetization-event-chain test-monetization-routes and make test-monetization-broker-transport.
SVC-020notification-serviceservices/notification-servicedocs/agents/service-tasks/notification-service.mdOwn notifications, preferences, read/delete state, event fanout, and delivery metadata for already-resolved recipients; attempt-service is a bounded grade-release producer dependency, not an SVC-020 implementation owner.GOTOOLCHAIN=go1.25.11 go test ./services/notification-service/... plus GOTOOLCHAIN=go1.25.11 go test ./services/attempt-service/... and make test-notification-routes test-parent-alert-routes test-attempt-routes for producer/route cutovers.
SVC-021audit-serviceservices/audit-servicedocs/agents/service-tasks/audit-service.mdOwn append-only compliance/security event history, producer replay, retention metadata, and future audit compatibility storage.GOTOOLCHAIN=go1.25.11 go test ./services/audit-service/... and make test-audit-admin-compat-routes when admin audit compatibility routing changes.
SVC-022analytics-serviceservices/analytics-servicedocs/agents/service-tasks/analytics-service.mdOwn dashboard/result/progress/mastery projections, weak-topic rollups, and rebuildable analytics events.GOTOOLCHAIN=go1.25.11 go test ./services/analytics-service/... plus make test-analytics-routes and event projection fixtures for changed producers.
SVC-023admin-serviceservices/admin-servicedocs/agents/service-tasks/admin-service.mdOwn admin read models, feature maintenance, moderation, support/admin workflows, and ops controls without absorbing source services or synthesizing source-service totals.GOTOOLCHAIN=go1.25.11 go test ./services/admin-service/... plus owner-source/source-snapshot tests, make test-feature-maintenance-routes test-admin-audit-routes, and route/browser proof before admin default promotions.

Alias And Retirement Rows ​

RowDispatch ruleVerification
auth-serviceNot a service row. Route auth/login/session/access work to iam-service; do not create an auth-service task pack, API doc, OpenAPI contract, deployment, or runtime directory.Use iam-service verification.
entitlement-serviceAlias concept only. Route implementation work to usage-service unless an ADR renames the canonical service.Use usage-service verification.
RET-USER user-serviceDeprecated compatibility scaffold. Route product work to iam-service or profile-service; use docs/agents/service-tasks/user-service-retirement.md only for retirement/quarantine after parity evidence.GOTOOLCHAIN=go1.25.11 go test ./services/user-service/... plus IAM/Profile parity tests before removal.

Agent Prompt Template ​

txt
You own <canonical-service> for one vertical slice.

Read first:
- docs/architecture/service-responsibility-matrix.md
- docs/agents/service-agent-dispatch-roster.md
- docs/agents/service-agent-wave-board.md
- docs/agents/service-workflow-test-matrix.md
- <task-pack>
- legacy evidence cited by the task pack

Rules:
- Work only in <writable-scope>.
- Do not edit orchestrator-owned shared files unless explicitly delegated.
- Do not revert unrelated worktree changes.
- Keep default gateway routes legacy unless the task is specifically a route
  rehearsal/cutover with rollback evidence.

Deliver:
- Audit notes with exact legacy/current source references.
- One small code or docs slice that moves the service toward its mission.
- Focused tests plus the service verification command.
- Closeout with changed files, tests, rollback notes, and next task.

Prioritized Cross-Service Backlog ​

These are orchestrator-owned contract slices that should be completed before spawning service workers that depend on them.

PrioritySliceOwnerAgent handoff
P0IAM canonical organization membership guardrailsOrchestrator with iam-service and organization-service ownersIAM membership -> refresh -> org_ids/role/permission/security-event coverage exists, school-service member writes now require explicit IAM read-model sync, IAM emits add/remove membership events, IAM persists an iam_membership_outbox, and the school-service read model records IAM event ordering/tombstones so stale upserts do not recreate newer deletes. IAM-sync deletes can remove the last local OWNER because IAM is canonical. Non-default gateway membership-write rehearsal now routes add/remove through organization_membership_adapter, translating legacy userId to IAM accountId; default writes and PATCH member updates stay legacy. Added opt-in make test-organization-membership-write-live for add/remove route smoke; next run it against a live gateway with an IAM admin bearer token and keep default routes legacy until rollback proof exists.
P0IAM/Profile UUID, backfill, and default cutover hardeningOrchestrator with iam-service, profile-service, gateway, and migration ownersNative IAM/Profile foundations exist, but public routes remain conservative and text ids remain for string-id API compatibility. IAM/Profile legacy backfill now has a read-only report scaffold and guard target, and make test-iam-profile-runtime-proof covers static/render migration-before-runtime wiring for Compose, offline K8s, and Helm. IAM_PROFILE_CLEAN_COMPOSE_CONFIRM=clean-runtime make test-iam-profile-clean-compose is the opt-in live clean Compose proof for IAM/Profile migration records, Postgres health, readiness, and JWKS; it preflights default ports 5433, 8081, and 8082, supports host-port overrides, and can use IAM_PROFILE_CLEAN_COMPOSE_USE_LOCAL_IMAGES=1 with Docker Compose --no-build when local service images are already present. Clean Compose live proof was refreshed on 2026-07-08 after the new IAM 13-file/Profile 10-file readiness/FK/PK-promotion migrations with rebuilt IAM/Profile/migrator images, Compose project hoctapaz-iam-profile-smoke, host ports 55433, 58081, and 58082, migration container completion, per-file schema_migrations, Postgres health, service health/readiness, and IAM JWKS. IAM_PROFILE_K8S_LIVE_CONFIRM=local-k8s make test-iam-profile-local-k8s was refreshed on 2026-07-08 against kind-hoctapaz-go after loading rebuilt IAM/Profile/migrator :local images, namespace hoctapaz-iam-profile-uuidpk2-20260708, host ports 58191 and 58192, migration Jobs, per-file schema_migrations for the current IAM 13/Profile 10 migration sets, service health/readiness, JWKS, port-forward, and namespace cleanup. Additive UUID shadow columns, dual-write triggers, read-only UUID primary-key readiness views, owner-local UUID FK constraints, and UUID primary-key promotion now have guard coverage; public text ids remain unique for API/upsert compatibility. Staff per-account permission source mapping is explicit zero-source legacy reconciliation, IAM_PROFILE_BACKFILL_POPULATED_CONFIRM=populated-fixture make test-iam-profile-backfill-populated is the opt-in fixture proof for loader/migration/UUID-shadow/UUID-PK compatibility, and IAM_PROFILE_LIVE_VALIDATION_CONFIRM=live-populated IAM_PROFILE_LIVE_VALIDATION_RUN_REPORT=/path/to/migrator-run.json IAM_PROFILE_LIVE_VALIDATION_REQUIRE_RUN_REPORT=1 make test-iam-profile-live-populated-validation is the cutover-grade read-only validation path for already-populated target DBs; the attached run report must include matched postload-reconciliation items with zero issues and zero rejected rows. The fixture path passed with completed migration_runs and hash evidence; production-like populated target DSN validation, live UUID readiness/FK/promotion output, final text-id cleanup, and default route/browser promotion evidence remain blockers. Use docs/agents/service-tasks/iam-profile-cutover-hardening.md before claiming UUID/backfill/default route cutover completion.
P0OpenAPI mirror drift guardOrchestratorKeep every services/*/api/openapi.yaml byte-identical with contracts/openapi/services/*.yaml; make test-service-task-packs enforces this.
P1Payment-to-billing/wallet event replay pathPayment, billing, wallet workersDurable payment event outbox dispatch is in place over the current internal HTTP sink: payment records payment.order.paid.v1, persists pending/delivered/retry/dead state, dispatches due paid events to billing/wallet /v1/events/payment-order-paid, billing activates subscriptions idempotently by source payment event id, and wallet writes one top-up ledger entry by source payment event id. Next: replace the HTTP sink with shared broker transport when selected and keep public routes legacy until runtime parity evidence exists.
P1Billing-to-usage entitlement syncBilling and usage workersDurable billing event outbox dispatch is in place: billing records billing.entitlements.updated.v1, persists pending/delivered/retry/dead state, dispatches due entitlement events to usage /v1/events/billing-entitlements-updated, and usage consumes them with processed-event replay plus stale snapshot guards without cross-DB reads. Next: replace the HTTP sink with shared broker transport when selected, then keep quota callers legacy until service-route parity exists.
P1Billing-to-wallet subscription creditsBilling and wallet workersDurable billing event outbox dispatch now also records billing.subscription.activated.v1, routes it to wallet /v1/events/billing-subscription-activated, and wallet grants one replay-safe SUBSCRIPTION_CREDIT ledger entry from monthlyCredits. Next: define renewal/proration/backfill policy before promoting subscription public routes.
P1Exam runtime/access decision APIExam and attempt workers after contract acceptanceLocal exam-service resolver is in place at POST /v1/exams/{id}/runtime-access with data.startInput, link/password/window/snapshot checks, exam_assignments, verifier hooks, and IAM/classroom verifier clients behind IAM_SERVICE_URL/CLASSROOM_SERVICE_URL. Attempt-service start now requires the trusted exam-service decision marker plus idempotency/correlation context, persists replay keys, and has submitted-retake count coverage. Non-default gateway attempt route tables now use the exam_start_adapter state so /api/exams/:id/start calls exam-service first and only forwards data.startInput to attempt-service when allowed. Static, live, and browser proof hooks are named as make test-attempt-routes, make test-attempt-live, and make test-attempt-browser. Next: run live/browser smoke with real disposable fixtures and keep default routes legacy until rollback evidence exists.
P1Document search projectionDocument and search workersLocal owner projection and rebuild route are in place: document-service exposes GET /v1/documents/search-projections, search-service pulls it through POST /v1/rebuild/document-service/documents, fixture coverage exists, and deploy env includes DOCUMENT_SERVICE_BASE_URL. Search-service now has an opt-in SEARCH_REBUILD_WORKER_ENABLED=1 projection freshness worker that cycles question-bank/course/exam/document sources, resumes sync-state cursors, caps pages per tick, and records owner-source failures as sync-state ERROR without taking the service down. make test-search-routes keeps public search routing blocked until a real legacy route/controller mapping selects search-service; /api/public/catalog* remains course-service-owned. Next: event/subscriber freshness or runtime worker proof against disposable owner-service fixtures plus a gateway/public route rehearsal only after that mapping exists.
P2BFF admin overview route rehearsalBFF and gateway workersNon-default route rehearsal is in place for GET /api/admin/overview -> bff-service /v1/bff/admin/overview, with make test-bff-routes static and gateway behavior coverage. BFF admin overview and operations summary can call admin-service /v1/admin/operations/source-map and /v1/admin/operations/source-snapshots, returning optional ownerSources and ownerSourceSnapshots trace metadata while degrading only the affected metadata on upstream failure. Document-service now provides owner document review counts at /v1/admin/documents/review-summary, school-service now provides owner organization roster counts at /v1/admin/organizations/roster-summary while IAM keeps permission-bearing membership authority, IAM provides access-control counts at /v1/admin/identity/summary, profile-service provides display/read-model counts at /v1/admin/profiles/summary, classroom-service provides classroom count summaries at /v1/admin/classrooms/summary, exam-service provides exam counts at /v1/admin/exams/summary, attempt-service provides local attempt metrics at /v1/admin/attempts/summary while analytics-service keeps derived rollups, docx-import-service provides import queue/failure summaries at /v1/admin/import/docx/queue-summary for queue.failures and the DOCX side of queue.depths, ai-classifier-service provides provider readiness at /v1/ai/providers/status for ai.providers plus queue/failure summaries at /v1/admin/ai-classifier/queue-summary for the AI side of queue.depths, and notification-service provides support notification queue/event/delivery summaries at /v1/admin/support/notification-summary for support.queues. Next: more owner-service metric adapters, browser proof, and rollback rehearsal before default route promotion.
P2AI question-context clientAI and question workersLocal client is in place: ai-classifier consumes question-bank POST /v1/questions/ai-classify/context when QUESTION_BANK_SERVICE_BASE_URL or QUESTION_BANK_SERVICE_URL is configured, persists scope.questionContext, and includes it in provider prompts. Next: BullMQ/job worker parity, gateway RBAC/maintenance checks, and browser proof before public route promotion.
P2Operational producer event contractsNotification, analytics, audit, admin, gateway workersUse docs/agents/service-tasks/operational-producer-events.md for each producer/consumer handoff. Attempt submitted/graded, course enrollment/progress/material/video, exam publish/assignment/result-release, exam assignment notification, classroom student/parent notification through profile resolver, explicit-recipient admin broadcast notification, explicit-recipient support ticket notification, classroom membership snapshot analytics, and gateway route-operation audit producers are now covered as best-effort event handoffs. Next slices need recipient discovery/resolver handoff for support and admin inbox, richer audit/security retry and runtime proof for IAM/payment/billing/wallet/admin/gateway, organization-membership audit semantics, and admin dashboard reads from owner APIs. Keep broad admin/notification/analytics routes legacy until route guards, browser/runtime proof, and rollback evidence exist.
P2IAM security-event projection contractIAM and audit workersIAM keeps credential/session/security decisions local, while audit-service owns compliance-grade security history. The current optional AUDIT_SERVICE_URL/AUDIT_SERVICE_BASE_URL sink posts IAM security_events to audit-service with sourceService=iam-service, stable sourceEventId, metadataSchemaVersion=1, retentionPolicy=security, and redacted metadata; local IAM logs stay authoritative and sink failures are non-blocking. Next slices are outbox-backed retry/replay, legacy security-event backfill reports, runtime smoke, and rollback evidence, with no raw passwords, reset tokens, Google tokens, refresh tokens, or provider secrets crossing the boundary.

Orchestrator Checkpoint ​

Run these after integrating any service-agent wave:

bash
make test-service-readiness
make test-runtime-foundation
pnpm docs:build
git diff --check

Go-platform documentation is generated from repository Markdown.