Lewati ke isi

T6A W03 Product Decision Gate

Historical T6A-B record (do not rewrite)

Issued: 2026-08-16
Status at issue: FAIL — ENTRY BLOCKED
Engineering label at issue: T6A ENTRY BLOCKED — NAMED PRODUCT DECISIONS REQUIRED

That label was correct when issued. No signed immutable W03 contract existed; implementing inferred code would have invented lifecycle, approval, privacy, recovery, or enrollment semantics. Phases 3–10 were correctly not entered. The tables below are the original T6A-B evidence and must remain as chronology.

Descendant approval (2026-08-16, later the same day)

Field Value
Approver Requesting user via current conversation
Date 2026-08-16
Scope SC-ADM / W03 only
Status APPROVED_BY_REQUESTING_USER_CONVERSATION
Immutable contract T6A-W03-approved-product-contract.md
RC1 impact None
Production authority None

The 15 properties are now approved by that descendant record. Engineering may implement only that contract. Current code remains non-authoritative until replaced.

Current gate (after approval): PASS for product-decision entry. Implementation, tests, and runtime evidence are tracked in later T6A artefacts — not in this historical T6A-B section.


Proceed to Phase 3 only when every material item below is explicit, signed, immutable, and traceable. Current code behavior is not an approved lifecycle.

Gate result

# Property Signed immutable approval? Current evidence Recommended decision (not implemented)
1 Canonical applicant/application identity and duplicate key NO scola.spmb.applicant email unique constraint is commented out (spmb_applicant.py _sql_constraints). Duplicate check is search-then-create. op.admission identity uses NISN/NIK fields without a signed duplicate key. Owner must name the duplicate key (email, NIK, NISN, KK, or composite + company) and uniqueness scope.
2 Approved lifecycle and exact state-transition table NO Applicant states draft/verified/active/completed/archived/blocked plus lifecycle_stage. Application (op.admission) uses OpenEduCat states (draft/submit/confirm/admission/reject/pending/done/cancel) plus announcement guard. Catalog says ordering is Inferred from code. RT-W03-STA-01 BLOCKED. Signed table: actor × from-state × to-state × side effects. Do not freeze the inferred table.
3 Actors allowed to verify, reject, approve, reopen, withdraw, enroll NO Staff APIs use model write / dashboard view capabilities. Portal applicant uses admissions.portal.view for almost all self actions. DEC-004 unsigned for Admissions. Named actor/action matrix per transition.
4 Final admission approver and maker-checker/self-approval NO DEC-004 open. /api/SPMB/admissions/<id>/transition accepts state/action with op.admission write. No SoD. Named final approver; self-approval allowed or denied.
5 Quota enforcement point and concurrent last-seat NO enroll_student takes pg_advisory_lock, counts state=done, then unlocks before student create (admission.py ~1008–1032). Public /api/SPMB/public/quota-monitor is public. Exact enforce point (decision vs enroll); last-seat fail-closed; public capacity disclosure yes/no.
6 Exact transition at which a Core student/onboarding record is created NO enroll_student creates op.student when student_id empty, then state=done, then applicant action_complete_lifecycle. Product contract: “moment of student creation require decision.” Name the exact from→to transition and the Core/W02 record created.
7 Student creation automatic vs explicitly invoked NO Code creates student inside enroll_student. Whether UI “Daftar Ulang” / staff transition / cron may invoke it is unsigned. Automatic on approved state or explicit enroll action only.
8 Idempotency key for application, decision, and W02 handoff NO No durable idempotency key on application/decision/handoff. Retry/concurrency unproven. RT-W03-IDM-01 BLOCKED. Keys and uniqueness constraints, not controller search-then-create.
9 Correction, reversal, withdrawal, failed-enrollment recovery NO Reject/cancel exist as OpenEduCat states. Recovery via archive cron / per-record ir.cron.sudo().create. No signed compensating W02 path. RT-W03-REC-01 BLOCKED. Who may reopen/withdraw; failed-handoff queue; never delete audit history.
10 Config ownership, effective dates, referenced-record deletion NO DEC-008 unsigned. Config CRUD uses view capabilities for save/delete (admission_config_api.py VIEW_CAPABILITIES). STAB-013 / BLK-A13 open. Owner, effective-date rule, referenced-delete fail-closed.
11 Applicant document type/size/signature/download/retention/deletion NO Upload/delete APIs exist (spmb_document_api.py, native /my/admission/<id>/upload). No signed DPO policy. Type/size/signature/scan, download actors, retention, deletion.
12 Public abuse/rate-limit and anti-enumeration NO Public allowlist includes register/status/pathways/quota. Status lookup by application number. Comment in registry: “Abuse/rate controls remain controller-owned.” No signed rate/enum policy. Rate limit; identical shapes for missing/disabled/duplicate identities.
13 Notification recipients and whether failure blocks the authoritative transaction NO OTP email failure is logged and registration still succeeds (spmb_api.py register). Enrollment sends notification then completes lifecycle. Recipients; block vs continue on notify failure.
14 Fees, CBT, Foundation as separately entitled bridges partial catalog, not certified Catalog and manifests treat them as overlays. Fees bridge auto_install=True. Assessment hard-depends scola_cbt. Foundation depends analytics. Base still ships payment/formulir/complaint/test leftover surfaces. Confirm bridges separately entitled; base SC-ADM must run without them; auto_install policy.
15 Applicant credential lifecycle under DEC-014 DEC-014 signed; Admissions mapping NOT signed DEC-014 frozen 2026-08-10: server-generated temp or recovery token; no shared/default; no native Odoo customer lifecycle; SPMB OTP must stay separate from password-reset. Current code: dual /api/SPMB/account/register; caller-supplied password; email-link to existing parent skips verification (spmb_lifecycle_api.py). Apply DEC-014 with no Admissions exception. Name one canonical applicant credential path. Do not keep email-link-by-email.

Signed decisions that do exist (do not invent around them)

Decision Status Implication for T6A
DEC-001 bounded Core Approved / RC1-A certified SC-ADM is optional, not Core. Core smoke must not own W03 business tests.
DEC-003 atomic capabilities Approved as Core control Admissions must not collapse view/configure/decide/enroll. STAB-013 still open.
DEC-014 credential lifecycle Frozen V1 Admissions may not weaken it. Current public register contradicts it. Containment of the bypass is not a substitute for a signed applicant mapping (which of OTP / temp password / token is canonical).
DEC-004 maker-checker Unsigned for Admissions Blocks item 4.
DEC-008 master data / effective dates Unsigned for Admissions Blocks item 10.

Questions requiring owner approval

Copy-ready for Product / Admissions SME / Security / DPO:

  1. What is the canonical applicant identity and duplicate key, including company scope?
  2. What is the exact state-transition table (applicant and application), including illegal transitions?
  3. Which acting roles may verify, reject, approve, reopen, withdraw, and enroll?
  4. Who is the final admission approver, and is self-approval denied?
  5. At which transition is quota enforced, and what happens on concurrent last seat? Is public quota visible?
  6. At which exact transition is a Core student / W02 onboarding record created?
  7. Is that creation automatic or an explicit enroll invocation?
  8. What are the idempotency keys for application, decision, and W02 handoff?
  9. What is the correction / reversal / withdrawal / failed-handoff recovery contract?
  10. Who owns config records, how do effective dates work, and how is referenced-record deletion rejected?
  11. What is the document type/size/signature/download/retention/deletion policy?
  12. What is the public abuse, rate-limit, and anti-enumeration contract?
  13. Who is notified, and does notification failure block the authoritative write?
  14. Confirm Fees / CBT / Foundation are separately entitled bridges, not base SC-ADM, including auto_install of the fees bridge.
  15. Confirm the single applicant credential lifecycle under DEC-014 (no caller-chosen initial password, no email-link hijack, no second register controller, no native /web signup).

Until those answers are signed and immutable, engineering must not implement “the current code path” as the approved W03 lifecycle.

Containment note

Phase 2 permits containing an unsafe surface only when that containment follows an existing security/package contract.

DEC-014 already forbids email-link-by-email and caller-chosen initial passwords. Choosing which of the two /api/SPMB/account/register controllers remains would itself invent the canonical applicant credential path (item 15). Therefore this tranche did not change application code. The dual register and parent-email link are recorded as S1 findings, not silently “fixed” into a new lifecycle.