Đặc tả API và ngữ cảnh — T09 ngoại tuyến

Hợp đồng: 0.1.0-offline · Ngày: 26/09/2026 · Trạng thái: bản mô phỏng ban đầu.

1. Ranh giới

T09 chỉ có phần khung kỹ thuật, chưa hoàn thành toàn bộ.
T01/T02/T04/T07 chưa giải quyết đầy đủ các phê duyệt y khoa và pháp lý.
T10/T11 chỉ có kiểm tra kỹ thuật tổng hợp tách biệt; chưa triển khai luồng thật.
T12 có giao diện mô phỏng riêng, chưa nối hoặc tư vấn.
Đây không phải , công cụ hoặc hệ thống tư vấn.
Không nhận dữ liệu bệnh nhân trong vận hành thử.
Không gọi mô hình, Internet, cơ sở dữ liệu hoặc nạp kho tri thức.
Không có lịch sử hội thoại, phiên người dùng, đọc khóa hoặc lưu tệp.
Ứng dụng không đọc biến môi trường và không có nhánh cho phép bật dịch vụ thật.
Kết nối thật đòi hỏi triển khai mới cùng lần xem xét riêng; phê duyệt không được suy ra từ kiểm thử.

2. Hợp đồng công khai

Phương thức và đường dẫn HTTP Nội dung JSON
GET /api/health 200 status: "ok", contract_version: "0.1.0-offline"
GET /api/readiness 503 status: "not_ready", code: "OFFLINE_NOT_READY", contract_version: "0.1.0-offline", approvals
POST /api/chat, yêu cầu hợp lệ 503 code: "OFFLINE_SERVICE_UNAVAILABLE", message cố định
POST /api/chat, yêu cầu không hợp lệ 422 code: "INVALID_REQUEST", message cố định, errors đã loại dữ liệu đầu vào
/api/chat, thân yêu cầu vượt 16 KiB 413 code: "REQUEST_BODY_TOO_LARGE", message cố định

approvals chứa clinical, provider, schema; mọi giá trị luôn là "unknown".
Đây là trạng thái chưa xác minh, không phải kết quả kiểm tra dịch vụ bên ngoài.
Biến môi trường không thay đổi trạng thái hoặc câu trả về.

Thông báo 503: Dịch vụ chưa sẵn sàng. Bản kiểm thử ngoại tuyến không xử lý yêu cầu tư vấn.

Thông báo 422: Yêu cầu không đúng cấu trúc kiểm thử.

Thông báo 413: Yêu cầu vượt giới hạn dung lượng kiểm thử.

Yêu cầu JSON là đối tượng chỉ có trường bắt buộc text.
text phải là chuỗi thật, dài từ 1 đến 2.000 ký tự Python, tính cả khoảng trắng.
Chuỗi chỉ chứa khoảng trắng bị từ chối; chuỗi hợp lệ không bị cắt hoặc chuẩn hóa.
Số, boolean, null, danh sách, đối tượng và trường dư đều bị từ chối.
Ví dụ tổng hợp hợp lệ: {"text":"SYNTHETIC_ALPHA"}.

errors là danh sách đối tượng gồm field và code: "INVALID_FIELD".
field chỉ là text hoặc body; lỗi trường dư và JSON hỏng được gộp vào body.
Danh sách loại trùng và sắp xếp theo tên trường.
Không trả tên trường lạ, giá trị đầu vào, vị trí JSON, thông báo gốc hoặc ngữ cảnh lỗi Pydantic.
Lỗi độ sâu hoặc mã hóa khi đọc JSON cũng trả 422 cố định, kể cả khi thư viện bọc thành HTTP 400.
Phản hồi không có trường câu trả lời, phân loại mức độ hoặc trích dẫn.
Không nhận diện ; mọi văn bản hợp lệ nhận cùng thông báo 503.

3. Giới hạn vận hành

Chỉ kiểm thử ngoại tuyến trong tiến trình hoặc trên 127.0.0.1, với nhật ký truy cập bị tắt.
Không có CORS cho phép nguồn khác; không có trang tài liệu hoặc đường dẫn OpenAPI công khai.
Không ghi nội dung yêu cầu; không trả giá trị môi trường.
Giới hạn 2.000 ký tự không phải giới hạn kích thước toàn bộ yêu cầu HTTP.
Lớp ASGI đếm byte thực nhận cho toàn thân yêu cầu tại /api/chat và /api/chat/, trước khi phân tích JSON.
Giới hạn mặc định là 16.384 byte, gồm cả khoảng trắng và trường dư; đúng giới hạn vẫn được phân tích.
MAX_CHAT_BODY_BYTES là hằng số mã; tham số max_body_bytes cho phép cấu hình lớp trong mã, không đọc môi trường.
Không tin Content-Length; vượt giới hạn trả 413 cố định và không đọc tiếp hoặc chuyển yêu cầu vào .
Ngắt kết nối trước khi nhận đủ thân yêu cầu không tạo phản hồi hoặc chuyển vào ứng dụng.
Bộ nhớ đệm giữ tối đa giới hạn byte; một đoạn quá lớn đã do máy chủ ASGI cấp phát vẫn nằm ngoài kiểm soát này.
Chưa giới hạn header, thời gian nhận, số đoạn rỗng hoặc số kết nối đồng thời.
Chưa có xác thực, giới hạn tần suất hoặc bảo vệ đầy đủ trước từ chối dịch vụ.
Không đưa phần khung lên Internet hoặc dùng cho nghiên cứu có người tham gia.

4. Bằng chứng và bước còn thiếu

Kiểm thử dùng FastAPI TestClient, không mở máy chủ và không cần mạng.
Kiểm thử chặn kết nối socket thông thường, tra cứu DNS và gửi UDP qua sendto.
Kiểm thử cài bộ chặn trước khi nạp ứng dụng và khởi động.
Windows tạm mở riêng connect khi thư viện chuẩn tạo socketpair nội bộ, rồi khôi phục chặn ngay.
Đây không phải môi trường cách ly hoàn chỉnh hoặc chứng nhận không thể truy cập mạng.
Kiểm thử xác nhận hợp đồng, từ chối cố định, lỗi đã loại dữ liệu và trạng thái không đổi qua biến môi trường.
Không chứng minh độ chính xác y khoa hoặc tính đầy đủ của cơ chế bảo vệ dữ liệu.
Cần giải quyết phê duyệt, cấu trúc dữ liệu và thiết kế bảo vệ dữ liệu trước triển khai có kết nối.
Không tự chuyển trạng thái thành APPROVED hoặc đánh dấu T09 hoàn thành.
Tham chiếu: README backend, mục đích sử dụng, thuật ngữ.

5. Bản kê thử nghiệm tổng hợp — chuẩn bị T10/T11

app/services/release_preflight.py chỉ nhận đối tượng Python trong bộ nhớ và thời điểm now có múi giờ.
Hàm validate_synthetic_manifest không đọc tệp, không gọi mạng, không sửa đầu vào và không xuất qua HTTP.
synthetic-preflight-0.1 là thử nghiệm riêng, không thay schema chuẩn hoặc quyết định T04.

Trường Quy tắc kỹ thuật
schema_version, kind Chính xác synthetic-preflight-0.1 và SYNTHETIC
records Danh sách 1–100 bản ghi; ID duy nhất
id, kind ID theo ^SYNTHETIC_[A-Z0-9_]+$; loại SYNTHETIC
content Chuỗi 1–16.384 ký tự, bắt đầu SYNTHETIC_; chỉ dùng văn bản giả
sha256 64 ký tự hex thường; khớp byte UTF-8 chính xác của content, không chuẩn hóa
status Chuỗi giả APPROVED; giá trị khác bị loại
citation_ids 1–100 ID, không trùng, mọi ID phải thuộc bản kê; tự tham chiếu được phép trong mô phỏng
rights Đúng hai quyền: synthetic_context và synthetic_citation, mỗi thao tác một mục
Mỗi quyền Có operation, evidence_id dạng ID tổng hợp, valid_from, expires_at, revoked

Ngày giờ phải là đối tượng datetime có múi giờ, không nhận chuỗi ngày giờ hoặc ép kiểu.
Mỗi quyền phải thỏa valid_from <= now < expires_at và revoked: false.
Phép so sánh chuyển thời điểm sang UTC để không chấp nhận quyền hết hạn trong giờ địa phương lặp lại.
Thiếu bằng chứng, hết hạn, bị thu hồi, trường dư hoặc sai cấu trúc đều khiến kiểm tra thất bại.
Mã lỗi cố định; không trả ID, nội dung hoặc thông báo lỗi Pydantic gốc.
structural_eligible: true chỉ xác nhận các điều kiện cấu trúc trong bảng.
clinical_authority_verified và release_authorized luôn là false, kể cả khi cấu trúc đạt.

Nhãn SYNTHETIC không chứng minh dữ liệu thực sự giả; người gọi phải chỉ cung cấp dữ liệu tổng hợp.
ID bằng chứng không được tra cứu hoặc xác thực. Trích dẫn chỉ kiểm liên kết, không kiểm sự hỗ trợ của nội dung.
Không có chữ ký, duyệt gắn phiên bản, kiểm quyền thật, nạp tri thức hoặc quy tắc y khoa.
Q01–Q08 và phê duyệt y khoa vẫn chưa giải quyết; không dùng kết quả này đóng T10/T11 hoặc mở dịch vụ.