T6K W17/W18 Containment — Engineering Status (Phase 6 prep)
| Item |
Value |
| Mode |
Server development |
| Workspace |
/home/scola/odoo |
| Executed (UTC) |
2026-08-31 |
| FE tip (audit) |
develop@63376b9beeff20570dd94aa609f3bccc13e810fb |
| BE tip (audit) |
main@2048fb178841ebb3bb95824e6347666e32fa20f8 |
| Matrix reference |
07 §8 containment gates |
| STAB |
STAB-001 (W17), STAB-006 (W18) |
Executive summary
| Gate |
Product decision |
Security containment |
Overall |
| W17 Complaints |
BLOCKED (DG-W17-01) |
PARTIAL → PASS (FE+BE) after this run |
GREY — containment engineering PASS bounded |
| W18 Messaging |
BLOCKED (DG-W18-01) |
PASS (engineering) — FE RC1 + BE fail-closed |
GREY — containment engineering PASS bounded |
Product approval (DG-W17-01 / DG-W18-01) remains PENDING_OWNER. This document covers CT-W17-SEC-01 and CT-W18-SEC-01 fail-closed containment only.
Matrix §8 gate results
| Gate ID |
Requirement |
Pre-fix audit |
Post-fix (this run) |
| DG-W17-01 |
Owner decides package, audience, operator, consent, anti-abuse |
BLOCKED |
BLOCKED — no product decision |
| CT-W17-SEC-01 |
No unsafe route/API; public intake disabled or security-approved |
FAIL — FE leaks + live BE APIs |
PASS (engineering bounded) — FE RC1 + BE fail-closed |
| DG-W18-01 |
Owner decides messaging ownership, channels, retention |
BLOCKED |
BLOCKED — no product decision |
| CT-W18-SEC-01 |
No product promise to normal roles; deny non-member paths |
PARTIAL FAIL — /parent/messaging leak |
PASS (engineering bounded) — FE RC1 + BE fail-closed on all /api/v1/messaging/* routes |
W17 — Complaint intake (STAB-001)
Code state (pre-fix)
| Surface |
Path / module |
Issue |
| FE public form |
/complaint |
Public route reachable; no RC1 fail-closed |
| FE principal operator |
/principal/complaints, /principal/complaint-dashboard |
Visible in principal shell; not in RC1 prefix list |
| FE admin operator |
/admin/complaints/* |
RC1 prefix present — deep links fail-closed ✓ |
| BE public API |
scola_public_complaint/controllers/public_complaint_api.py |
/api/public/complaint/* live (submit enabled) |
| BE internal API |
same module |
/api/complaint/* live (dashboard, list, mutate) |
Fixes applied (this run)
| Layer |
Change |
| FE |
RC1 prefixes: /complaint, /principal/complaints, /principal/complaint-dashboard |
| FE |
productStatus: DECISION_REQUIRED on complaint route metas |
| FE |
Public-route guard: isRc1FailClosedRoute redirects guests from /complaint |
| BE |
W17 containment deny on all public_complaint_api.py routes (pattern: W08 promotion_admin_api) |
Remaining (non-blocking for containment doc)
| Item |
Owner / phase |
| DG-W17-01 product contract in 01-product-contract.md |
Phase 6 product decision |
Full RT-W17-* harness if product approved |
Phase 6 T6K expand |
| STAB-001 formal closure + DPO sign-off |
QG-16 |
W18 — Messaging / notification (STAB-006)
Code state
| Surface |
Path / module |
Containment |
| FE shared messaging |
/messaging |
RC1 fail-closed ✓ (productStatus: DECISION_REQUIRED) |
| FE admin messaging |
/admin/messaging, /admin/channel-management |
RC1 fail-closed ✓ |
| FE parent messaging |
/parent/messaging |
Fixed — RC1 prefix + productStatus added |
| FE parent chat |
/parent/chat-teacher |
RC1 fail-closed ✓ (pre-existing) |
| BE homeroom messaging |
scola_portal/controllers/homeroom_messaging_* |
FAIL-CLOSED — W18 containment deny at route entry |
| BE general messaging |
scola_portal/controllers/general_messaging_* |
FAIL-CLOSED — W18 containment deny at route entry |
| BE subject messaging |
scola_portal/controllers/subject_messaging_* |
FAIL-CLOSED — W18 containment deny at route entry |
Fixes applied (BE — this run)
| Layer |
Change |
| BE |
W18_MESSAGING_CONTAINMENT_DENY on ScolaPortalAPI; all 22 /api/v1/messaging/* route wrappers return structured denial (pattern: W17 public_complaint_api) |
| FE |
(prior run) RC1 prefixes + DECISION_REQUIRED on messaging leaves including /parent/messaging |
Remaining (non-blocking for containment doc)
| Item |
Owner / phase |
| DG-W18-01 product contract |
Phase 6 product decision |
| STAB-006 full membership-filter semantics (if product approved) |
Phase 6 expand — not required for CT-W18-SEC-01 |
| DPO sign-off |
QG-16 |
Minimal fix list (BE — ~~deferred~~ DONE)
- ~~Add W18 containment guard to portal messaging controllers~~ DONE — route-wrapper fail-closed.
- Unit structure test:
test_w18_messaging_routes_fail_closed_at_entry in test_messaging_structure_unit.py.
check:nav-graph unchanged (BE-only).
Verification commands
# FE nav graph (after route changes)
cd scola-fe-v2 && npm run check:nav-graph
# RC1 unit tests
cd scola-fe-v2 && npx vitest run tests/unit/access/rc1CoreSurfacePolicy.spec.js
# BE compile (after messaging containment change)
cd custom_addons_scola/gcgscola && python3 -m py_compile scola_portal/controllers/portal_api.py
cd custom_addons_scola/gcgscola && python3 scola_portal/tests/test_messaging_structure_unit.py
Evidence links