T0-E1 Result — Security Boundary and Runtime Enforcement Closure¶
| Metadata | Value |
|---|---|
| Mode | Server development /home/scola/odoo |
| Docs read | audit/T0-final-*.md, T0-E1-preflight, development-guide, workspace-governance, architecture-api, DEC-002, DEC-014 |
| Authority | Independent audit VERDICT C — T0 NOT CLOSED; this tranche does not close T0 |
| Implementation label | T0-E1 IMPLEMENTATION COMPLETE — PENDING INDEPENDENT AUDIT |
| FE branch / HEAD | develop / faefe33cc44bb45f32dabeea5831b6c6b5cd7583 |
| BE branch / HEAD | main / 039e95b587cb40ca7db12fdfeb2320deeff2c8cc |
| BE last application commit | 508400c7effa272f49e3c111b4a2f6f6360b5cd1 (ICP upsert); tip adds Golden harness only |
| Golden DB | scola_golden @ :8090 upgraded + restarted with SCOLA_BACKEND_GIT_COMMIT_SHA |
| Evidence dir | docs/release-readiness/execution/T0-E1-evidence/ |
Runtime matrix snapshot¶
| Matrix | Run ID | Result |
|---|---|---|
| Conflict-role (T0F-001) | T0-E1-20260809T065956Z |
10/10 PASS |
| Entitlement OFF mixed-install (T0F-004) | T0-E1-20260809T070149Z |
8/8 PASS |
| Credential expanded (T0F-014) | T0-E1-20260809T070201Z |
19/19 PASS |
| Tenant / mail / attach / DIR (T0F-002/015) | T0-E1-20260809T070458Z |
27/27 PASS (focused subset; MAN-01 not claimed) |
| Route denominator CI | local api_route_surface_coverage_check.py |
PASSED (0 unregistered protected) |
| E1 evidence validator mutations | test_e1_evidence_validator_mutations |
PASS (adversarial cases fail as required) |
Finding closure table¶
| Finding | Before | Fix | Static proof | Runtime proof | Immutable evidence | Status |
|---|---|---|---|---|---|---|
| T0F-001 | Controllers authorized via scola_role / group union |
Canonical authority_context + session active role across Core/portal/leadership/attendance; preferred field display-only |
authority_context.py, portal/leadership controllers, unit tests |
Conflict matrix 10/10 (gt.multi.teacher_admin teacher vs school_admin dual session) |
T0-E1-*-conflict-role.json |
FIXED_AWAITING_INDEPENDENT_AUDIT |
| T0F-002 | B2-DIR-01 false-green on [742] create id |
detect_direct_path_bypass; /web/dataset mutation gate for non-system Scola actors; harness requires side-effect denial |
test_direct_path_bypass_unit.py, ir_http.py |
B2-DIR-01 PASS on Golden |
T0-E1-*-tenant-dir.json |
FIXED_AWAITING_INDEPENDENT_AUDIT |
| T0F-003 | Ancestor/docs tip green; narrow tree hash | New e1_evidence_identity_validator.py exact FE/BE app tree + commit equality; --allow-docs-tip only when app tree unchanged |
Mutation suite PASS | N/A (validator) | scripts under scripts/golden/e1_* |
FIXED_AWAITING_INDEPENDENT_AUDIT |
| T0F-004 | Optional data while flags false; leadership soft | Route flags for HR/finance optional surfaces; soft→hard deny in ir_http |
api_route_access.py unit |
Entitlement OFF 8/8; HR open only when scola_hr forced enabled |
T0-E1-*-entitlement-off.json |
FIXED_AWAITING_INDEPENDENT_AUDIT |
| T0F-005 | Bulk parent reset SUPERUSER browse + password return | Endpoint 410 Gone; FE bulk button removed | account_generation_api.py, ParentList.vue |
T0D-BULK-01 PASS |
credential results json | FIXED_AWAITING_INDEPENDENT_AUDIT |
| T0F-006 | Caller-chosen password on /api/v1/users |
Server-generated secret + must_change; historical migrations no-op |
user_detail_api.py, lifecycle unit |
Covered by create policy unit + matrix policy cases | credential unit + matrix | FIXED_AWAITING_INDEPENDENT_AUDIT |
| T0F-007 | Must-change FE-only | Server gate allowlist auth/recovery only | test_ir_http_must_change_unit.py |
T0D-MUSTCHANGE-01 PASS |
credential results | FIXED_AWAITING_INDEPENDENT_AUDIT |
| T0F-008 | Native /web/reset_password active |
ICP auth_signup.reset_password=False via set_param; native_reset_block 404 |
XML + controller | T0D-NATIVE-01 PASS |
credential results | FIXED_AWAITING_INDEPENDENT_AUDIT |
| T0F-009 | Token race; revoke/audit swallow | FOR UPDATE consume; revoke fail-closed |
credential lifecycle unit 11/11 | T0D-CONFIRM-04/05 concurrent/replay |
credential results | FIXED_AWAITING_INDEPENDENT_AUDIT |
| T0F-013 | Public prefix classifies children public; CI unwired | Exact public allowlist; CI runs coverage checker | route unit + workflow YAML | registers public, registers/list not; coverage 0 blockers |
CI config + local PASS | FIXED_AWAITING_INDEPENDENT_AUDIT |
| T0F-014 | 11/11 incomplete denominator | Expanded matrix (xtenant, must-change, native, bulk, deact, concurrent) | t0d_credential_matrix.py |
19/19 PASS | T0-E1-20260809T070201Z-results.* |
FIXED_AWAITING_INDEPENDENT_AUDIT |
| T0F-015 | Disallowed-model / fabricated hashes | Allowlisted op.session attach + admin count; mail/search/detail FK probes; before==after |
core_reference_api company scope on attach |
A005/S005/ATT/DIR focused 27/27 PASS | T0-E1-*-tenant-dir.json |
FIXED_AWAITING_INDEPENDENT_AUDIT |
Explicit non-claims¶
- Not
T0 CLOSED. - Not T1 start.
- Optional REPORT/LEARN/ASSESS/ATTEND+/FOUND/DAP/BOS business certification not claimed.
- Leadership remains not reclassified as Core; unresolved surfaces stay fail-closed / entitlement-gated.
- Full B2.1 MAN-01 identity equality against the superseded B2.1 manifest is not re-claimed in this tranche (E1 uses new validator + E1 evidence).
Adversarial self-review (implementation)¶
| Question | Answer after E1 |
|---|---|
| Inactive assigned roles widen authority? | No — conflict matrix proves teacher session cannot use school_admin surface |
/web/RPC bypass Scola predicate? |
Dataset mutations denied for school actors; DIR-01 PASS |
| T1 mutate T2 Core object? | Attach/mail/search denied; side-effect counts unchanged |
| Installed optional modules return data while entitlement false? | HR/finance/leadership optional probes denied when forced disabled |
| GT-T1 admin reset GT-T2 credential? | T0D-XTENANT-01 PASS |
| User-create arbitrary reusable password? | Ignored; server secret + must-change |
| Must-change call normal APIs? | Denied (T0D-MUSTCHANGE-01) |
/web/reset_password second lifecycle? |
Disabled/blocked (T0D-NATIVE-01) |
| Token succeed twice concurrently? | Covered (T0D-CONFIRM-05) |
| Public prefix makes child public? | Exact match only |
| One app file keeps validator green? | Mutation tests require FAIL |
| Denied mutation changes DB? | Harness requires before_count == after_count |
Next step¶
Independent Codex audit of this tranche. Composer must not mark independent findings permanently closed.