Skip to content

Audit Standard · AS-07 tới AS-10 ​

Một phần của Audit Standard. Chỉ báo AS-07 bảo mật và riêng tư, AS-08 tin cậy và vận hành, AS-09 trải nghiệm và design system, AS-10 AI governance và chi phí.

AS-07 — Bảo mật, Riêng tư & Tuân thủ ​

IDChỉ báoCách kiểm
AS-07.1Xác thực & phiên
AS-07.1.1🔴🚸 Mọi endpoint không public đều yêu cầu xác thựcgrep -c "requireSession" workers/api/src/modules đối chiếu tổng số route; mỗi route thiếu phải được liệt kê + xác nhận "public có chủ đích"
AS-07.1.2Token/session có hạn và có cơ chế thu hồiđọc resolveSession + rotated_token
AS-07.1.3audience / issuer của id_token được verify, không bỏ quađọc code xác thực OAuth
AS-07.1.4🚸 Khu vực nội bộ (admin, dolphin) có lớp bảo vệ hạ tầng (Cloudflare Access), không chỉ check ở appthử truy cập ẩn danh vào admin.nemo12.com/mentors.nemo12.com — kỳ vọng chặn ở Access trước khi tới app (đã xác nhận PASS theo đính chính Audit #001 §5 — giữ trong Pilot Gate để không âm thầm tắt lại)
AS-07.1.5Không có đường đăng nhập tắt / backdoor trên productiongrep -rn "bypass|skip.*auth|debug.*login" + rà middleware
AS-07.2Phân quyền backend
AS-07.2.1🔴🚸 Mọi truy cập learner data được authorize ở backend, không chỉ ẩn ở UIrà từng endpoint chạm bảng có learner_id; canAccessLearner() (hoặc tương đương) phải xuất hiện trong mọi module đó
AS-07.2.2🔴 RBAC dựa trên role/id, không so sánh emailgrep -rn "role.*===.*email|\.email ===" workers/api/src trong logic authz phải rỗng
AS-07.2.3🔴🚸 Parent chỉ truy cập learner trong family của mình — có test chứng minhfind workers/api/src -iname "*authz*test*" -o -iname "*parent*family*test*" phải tồn tại và pass
AS-07.2.4Mentor truy cập rộng hơn nhưng bắt buộc ghi audit logđọc code mentor routes + SELECT COUNT(*) FROM audit_log WHERE actor_role='mentor' > 0
AS-07.2.5Ma trận quyền reference/permissions.md khớp kiểm tra thật trong codeđối chiếu
AS-07.3Dữ liệu trẻ em & đồng thuận
AS-07.3.1Mỗi trường dữ liệu trẻ em có mục đích ghi rõ (thu thập tối thiểu)data-dictionary.md
AS-07.3.2🚸 Ghi dấu vết đồng thuận (KHÔNG chặn) — chủ dự án 2026-08-15 quyết bỏ cổng chặn, xem SRC-137đọc luồng onboarding — có bảng consents ghi ai bật/tắt cái gì, lúc nào
AS-07.3.3Nội dung do trẻ viết (portrait learner sections) chỉ role learner được ghiđọc code + portraits/*.test.ts
AS-07.3.4Không chia sẻ dữ liệu trẻ em sang bên thứ ba ngoài nhà cung cấp hạ tầng đã khairà lời gọi ra ngoài — grep -rn "fetch(\"https://" workers/api/src đối chiếu domain đã khai
AS-07.3.5Parent xem được dữ liệu nào đang dùng để ra quyết định về con mìnhUI marlins
AS-07.4Audit log
AS-07.4.1Mọi truy cập learner data bởi role không phải chủ sở hữu được ghi logđọc code — điểm ghi audit_log ở mọi route mentor/staff chạm learner data
AS-07.4.2Log ghi đủ: ai, cái gì, khi nào, từ đâuschema audit_log — có actor_id, target_id, created_at, ip/tương đương
AS-07.4.3Log không chứa nội dung nhạy cảm nguyên văn (chỉ tham chiếu)đọc mẫu log — chỉ target_type+target_id, không có nội dung
AS-07.4.4Log không thể bị ứng dụng sửa/xóarà endpoint/quyền — không route nào UPDATE/DELETE audit_log
AS-07.4.5Có đường truy vấn log phục vụ điều tra sự cốUI admin/query endpoint
AS-07.5Bề mặt tấn công
AS-07.5.1🔴 Không secret trong git historygit log -p --all | grep -E "(api[_-]?key|secret|token)\s*[:=]"
AS-07.5.2🔴 Không endpoint debug/seed mở trên productiongrep -rn "debug|/seed" workers/api/src/index.ts đối chiếu route thật
AS-07.5.3Input người dùng validate bằng schema trước khi chạm DBrà router — mọi route có .input()/zod schema
AS-07.5.4Nội dung người dùng nhập được escape khi render (chống XSS)grep -rn "dangerouslySetInnerHTML" apps/*/src — mỗi hit xác nhận nguồn không phải input người dùng trực tiếp
AS-07.5.5🚸 Rate limit / chống lạm dụng cho endpoint tốn kém (AI, crawl, đăng nhập)đọc code — middleware rate-limit trên route AI/login

AS-08 — Tin cậy & Vận hành ​

IDChỉ báoCách kiểm
AS-08.1Production-ready
AS-08.1.1Mỗi worker khai availability tierdocs/config
AS-08.1.2Trả lời được bằng văn bản 5 câu hỏi production-ready SDD-006 §16đọc
AS-08.1.3Mỗi tính năng mới định nghĩa "hỏng thì người dùng thấy gì"đọc SDD
AS-08.1.4🚸 Health endpoint phản ánh phụ thuộc thật, không trả 200 cứngđọc code index.ts + curl — health chạy SELECT 1 trên D1 thật
AS-08.1.5Không TODO/FIXME chặn đường còn sót trong mã đang chạy productiongrep -rn "TODO|FIXME" workers/api/src apps/*/src
AS-08.2Idempotency & DLQ
AS-08.2.1Mọi queue consumer idempotent theo message idđọc code consumer
AS-08.2.2🔴🚸 Mọi queue có DLQ cấu hìnhgrep "dead_letter_queue" workers/api/wrangler.jsonc
AS-08.2.3Có đường xử lý/replay message trong DLQquy trình + code
AS-08.2.4Retry có giới hạn và backoff, không vòng lặp vô hạnđọc max_retries trong wrangler config
AS-08.2.5Cron job an toàn khi chạy chồng (overlap), hoặc có khóađọc code cron handler
AS-08.3Observability
AS-08.3.1Observability bật trên mọi workergrep -c "observability" workers/*/wrangler.jsonc khớp số worker
AS-08.3.2Log có level và request id xuyên suốt một requestđọc code middleware log
AS-08.3.3Lỗi 5xx ghi kèm ngữ cảnh đủ để tái hiệnđọc code error handler
AS-08.3.4Có chỉ số theo dõi engine/queue (số run, số lỗi)dashboard/query
AS-08.3.5Biết được một workflow đã chạy hay chưa mà không cần đọc log thôSELECT COUNT(*) FROM workflow_runs > 0
AS-08.4CI/CD & rollback
AS-08.4.1🚸 CI chạy typecheck + lint + test trước khi deployci.yml bước 1-3 — đã enforce trên mọi push; deploy-app.yml đọc lại kết quả ci qua wait-for-ci.sh
AS-08.4.2Deploy chỉ chạy cho app có thay đổi (path filter đúng)đọc workflow paths:
AS-08.4.3🔴🚸 Migration được áp trước code trong pipeline APIđọc ci.yml và deploy-app.yml — dòng apply trước dòng wrangler deploy ở cả hai
AS-08.4.4Có cách rollback nhanh về version trước cho từng workerrollback.yml + quy trình ghi lại
AS-08.4.5Không bước deploy thủ công bắt buộc nằm trong đường chínhđọc workflow — mọi bước trong on: push tự động, không chờ tay trừ migration-apply (đã ghi rõ lý do ở AS-03.5.4)
AS-08.5Suy giảm duyên dáng & phụ thuộc ngoài
AS-08.5.1Mỗi phụ thuộc ngoài (AI, OAuth, crawl target) có hành vi fallback khi lỗiđọc code
AS-08.5.2Lỗi phụ thuộc ngoài không làm sập trang chínhthử ngắt — mock lỗi AI, xem UI
AS-08.5.3Timeout đặt tường minh cho mọi lời gọi ra ngoàigrep -rn "AbortSignal.timeout|signal:" workers/api/src
AS-08.5.4Có cache / kết quả gần nhất cho dữ liệu đọc nhiềuđọc code — KV cache hoặc tương đương
AS-08.5.5Sự cố hiển thị thông điệp người dùng hiểu được, không phải stack tracethử lỗi — đọc response errorResponse

AS-09 — Trải nghiệm & Design System ​

IDChỉ báoCách kiểm
AS-09.1Luật tối giản (SRC-048) — từ v0.2: đòi artifact cụ thể, xem §1.10
AS-09.1.1Mỗi màn hình có đúng một hành động chính rõ ràngđọc docs/reference/ui-minimalism-audit.md cột "hành động chính"; artifact chưa tồn tại = KHÔNG PASS (mã CX)
AS-09.1.2Bố cục full-width, không cột phụ thừacột "bố cục" trong cùng artifact
AS-09.1.3Số element ở mức tối thiểu cần thiết — không badge/nhãn/đếm thừacột "số element" trong cùng artifact
AS-09.1.4Hình ảnh/biểu tượng ưu tiên hơn chữ giải thích dàicột "hình/chữ" trong cùng artifact
AS-09.1.5Trang chủ mỗi cổng đóng vai trò hub, không phải trang nội dung dàicột "là hub?" trong cùng artifact, riêng cho route / mỗi app
AS-09.2Token & component
AS-09.2.1Chỉ dùng token màu/khoảng cách của DS; không hardcode hex trong app — xem thêm AS-03.1.4 (góc khác: không định nghĩa lại token, đây là không hardcode khi dùng)grep -rEc "#[0-9a-f]{6}" apps/*/src loại trừ file SVG/art
AS-09.2.2Không fork component: mỗi component dùng chung có đúng một định nghĩagrep -rn "function <TênComponent>" packages apps phải chỉ 1 định nghĩa
AS-09.2.3Không CSS riêng theo trang ngoài phạm vi cho phéprà file .css theo route
AS-09.2.4Portal theme chỉ đổi lớp accent, không đổi cấu trúc tokenđọc packages/design-system/tokens/base.css
AS-09.2.5Font size sàn 14px, không có chữ nhỏ hơngrep -rn "text-xs|font-size:\s*1[0-3]px" apps/*/src
AS-09.3Accessibility
AS-09.3.1🔴🚸 Tương phản màu đạt WCAG AA cho cả text thường và text lớnnpm run contrast --workspace @nemo12/design-system, chạy trong CI từ SRC-593. Trước đó chỉ tiêu này có script nhưng script không được nối vào CI, nên một cặp trượt ngưỡng nằm trên main mà không gì báo — chỉ tiêu đỏ mà không có cổng chạy thì chỉ là một lời hứa. Từ SRC-827 cổng chấm mỗi cặp trong đúng ngữ cảnh nó chạy (:root, .n12-v1, .n12-v1 .n12-deep, .theme-marlins.od-root, .n12-band-dark, .n12-nav-deep) thay vì chỉ ở gốc, hoà màu mờ lên --card trước khi đo, và soi gương các remap utility của từng vùng; nợ cũ (nếu có) phải ghi TÊN trong contrast-baseline.json, nợ mới là đỏ. Ca mẫu: bg-accent-ink text-white được chấm 17:1 ở gốc nhưng là 1,11:1 trong .n12-deep (b09b40ea). Từ SRC-842 cổng chấm thêm ở ĐỈNH của mặt gradient (od-root/marlins/deep) với lớp kính đặt lên đó — đỉnh suy từ token thật, không phải stop tuyến tính — đọc .od-dim/.od-card từ chính CSS và từ chối chạy nếu .od-root rời --surface-deep. Giới hạn đã biết: mực badge của marlins trong od-root (.n12-badge-solid/-review, hover:bg-card) là gương viết tay trong PAIRS — xoá rule ở index.css thì cổng vẫn xanh; kiểm bằng đo pixel trên build (DS-001 §2·1·26).
AS-09.3.2Mọi phần tử tương tác có focus state nhìn thấy đượcthử tab qua bàn phím trên ≥3 màn hình chính
AS-09.3.3Touch target ≥ 44px trên mobileđo trên DevTools mobile emulation
AS-09.3.4Mọi ảnh có alt, hoặc được đánh dấu là trang trígrep -rn "<img" apps/*/src | grep -v "alt="
AS-09.3.5Điều hướng bàn phím đi hết được luồng chínhthử tay — Tab qua luồng "trả lời câu hỏi" đầu-cuối
AS-09.4Ngôn ngữ & nội dung UI
AS-09.4.1Cổng learner/marlins dùng tiếng Việt; khu admin dùng tiếng Anh toàn bộ (SRC-098)rà UI string trong apps/admin/src, apps/learn/src
AS-09.4.2Không lẫn hai ngôn ngữ trong cùng màn hình (trừ thuật ngữ giữ nguyên có chủ đích)rà UI
AS-09.4.3Thuật ngữ dùng thống nhất theo reference/glossary.mdđối chiếu
AS-09.4.4Thông điệp lỗi viết cho người dùng, không phơi mã kỹ thuật trầnrà UI — errorResponse
AS-09.4.5Chữ trên UI không lặp lại nội dung đã hiển thị bằng hình/nhãn khácrà UI
AS-09.5Hiệu năng cảm nhận
AS-09.5.1Trang chính hiện nội dung chính dưới ngưỡng đã khai báođo — Lighthouse LCP đối chiếu ngưỡng khai trong SDD
AS-09.5.2Không có layout shift lớn sau khi tải xongLighthouse CLS
AS-09.5.3Trạng thái loading / empty / error đều có thiết kế, không để trắngrà từng màn — spot-check ≥5 màn
AS-09.5.4Ảnh/mascot phục vụ đúng kích thước, không tải ảnh quá khổnetwork panel — so kích thước file với kích thước hiển thị
AS-09.5.5Thao tác chính (trả lời câu hỏi) phản hồi ngay, không chờ round-trip mới đổi UIthử tay — chấm client-side trước, evidence gửi async

AS-10 — AI Governance & Chi phí ​

IDChỉ báoCách kiểm
AS-10.1Đường AI duy nhất
AS-10.1.1🔴 100% lời gọi AI đi qua AI Gateway nemo12grep -rn "env.AI.run(" workers/api/src mọi hit có gateway: { id:
AS-10.1.2🔴 Không có probe-fallback tự dò modelđọc code — không vòng lặp thử nhiều model id
AS-10.1.3Model id khai tường minh, không dùng alias mơ hồgrep -rn "@cf/" workers/api/src
AS-10.1.4Không có lời gọi AI trực tiếp từ frontendgrep -rn "env.AI|ai.run" apps/*/src phải rỗng
AS-10.1.5Mọi điểm gọi AI có mặt trong reference/ai-registry.mdđối chiếu
AS-10.2Prompt registry
AS-10.2.1Mọi prompt production nằm trong registry, không viết inline rải rácgrep -rn "const.*[Pp]rompt.*=.*\" workers/api/src/modules` đối chiếu registry
AS-10.2.2Mỗi prompt có versionđọc registry — trường PROMPT_VERSION
AS-10.2.3Đổi prompt = tạo version mới, không sửa tại chỗgit log -p spot-check
AS-10.2.4Mỗi prompt ghi mục đích, đầu vào kỳ vọng, ràng buộc đầu rađọc registry
AS-10.2.5Output AI có schema và được validate trước khi dùngđọc code — không z.object({ data: z.any() })
AS-10.3Context Builder & ranh giới dữ liệu
AS-10.3.1🔴🚸 Context Builder là đường duy nhất AI chạm learner datarà code — mọi route gọi AI đi qua một hàm builder chung
AS-10.3.2Context gửi đi được tối thiểu hóa — chỉ trường cần cho tác vụđọc builder
AS-10.3.3Không gửi định danh trực tiếp của trẻ (tên thật, email) vào prompt khi không cầnđọc builder
AS-10.3.4Mỗi output AI lưu input_ref để truy ngượcschema
AS-10.3.5🔴🚸 Có kiểm chứng dữ liệu learner A không lọt vào context của learner Bfind . -iname "*context*leak*test*" -o -iname "*context*isolation*test*" phải tồn tại và pass
AS-10.4Đánh giá & chống ảo giác
AS-10.4.1🔴🚸 Nội dung AI sinh ra không publish thẳng; phải qua ngưỡng đánh giáđọc pipeline — route sinh nội dung AI không INSERT thẳng vào bảng published
AS-10.4.2Có multi-evaluator cho nội dung quan trọng (đề, lời giải)đọc pipeline
AS-10.4.3Có tỷ lệ spot-check bởi người, được ghi lại thành sốlog/ghi chú
AS-10.4.4Mọi khẳng định kiến thức do AI sinh có nguồn, hoặc được đánh dấu là sinh tự độngrà nội dung
AS-10.4.5Learner báo sai → có đường quay lại chỉnh nội dung, không rơi vào hư vôđọc pipeline — content_reports nối vào hàng đợi thật
AS-10.5Chi phí & hạn mức
AS-10.5.1Mỗi loại lời gọi AI có ước tính chi phí ghi lạiai-registry.md
AS-10.5.2Có cách xem chi phí theo thời gian (dashboard/gateway)dashboard Cloudflare AI Gateway — cần scope token đọc gateway
AS-10.5.3Có hạn mức hoặc cảnh báo khi vượt ngưỡngconfig gateway
AS-10.5.4Tác vụ nền tốn kém có lịch chạy và giới hạn số lượng mỗi lầncron config
AS-10.5.5Không có vòng lặp gọi AI không giới hạn kích hoạt được bởi hành vi người dùngđọc code — route AI chỉ ở staff/admin hoặc có rate limit