Điều 41 — Luật Vận hành Mã VPS v0.5.1 DRAFT
ĐIỀU 41 — LUẬT VẬN HÀNH MÃ VPS v0.5.1 DRAFT
Trạng thái: DRAFT hoàn thiện sau phản biện vòng 3
Ngày: 2026-04-14
Soạn thảo: Incomex Hội đồng AI / GPT
Phạm vi: Quy định cách sửa mã trực tiếp trên VPS khi VPS đang là SSOT vận hành và hiện chỉ có một VPS dùng chung code + production data
§0. Bối cảnh và mục tiêu
CI/CD qua GitHub hiện mất khoảng 10 phút mỗi vòng. Trong giai đoạn hệ thống đang sửa nhanh và dày, nhu cầu sửa mã trực tiếp trên VPS là có thật để tiết kiệm chu kỳ chờ. Đồng thời, hiện chỉ có một VPS duy nhất, nên chưa thể tách riêng dev VPS và production VPS.
Vì vậy, hệ thống tạm chấp nhận mô hình một VPS dùng chung cho cả code và production data. Agent cần có quyền thao tác đủ mạnh để sửa và deploy nhanh trên VPS này. Điều 41 không cấm điều đó; Điều 41 ép nó vào một hành lang có kiểm soát: tách vùng, lock, verify, rollback, audit trail, guard chống drift, và phân loại rõ mức độ đụng data/schema thật.
Giả định vận hành hiện tại
- Chỉ có một DB production thật.
- Hiện không có cách bảo vệ data tốt hơn backup.
- Backup hiện đang chạy tự động về Google Drive; khi data quan trọng hơn có thể tăng lên 5–6 lần/ngày.
- Chúng ta chấp nhận rủi ro rằng nếu VPS bị hack thì secret/env có thể bị lộ; đây là rủi ro phải chấp nhận trong mô hình hiện tại.
- Vì vậy, luật này không được giả định có sandbox data riêng hay DR nhiều lớp; nó phải dùng được trong bối cảnh thật hiện nay.
Định hướng tương lai
Khi bắt đầu có khách hàng thật hoặc volume data đủ lớn, mô hình mục tiêu sẽ là:
- VPS-A: dev/build/repair
- VPS-B: production runtime
Điều 41 v0.5.1 là luật cho giai đoạn chuyển tiếp một VPS.
§1. Nguyên tắc nền
| # | Nguyên tắc | Nội dung chốt |
|---|---|---|
| NT-VPS-1 | Một VPS nhưng vẫn phải tách vùng | Dù chỉ có một VPS, vẫn phải tách vùng sửa mã (app-dev) và vùng chạy thật (app-production/current). |
| NT-VPS-2 | Agent được quyền sửa trên VPS nhưng không được sửa bừa | Quyền đủ mạnh là cần thiết, nhưng mọi thay đổi phải đi qua quy trình có lock, audit, verify và rollback. |
| NT-VPS-3 | Atomic deploy | Production chỉ nhận mã qua release mới + symlink swap hoặc cơ chế apply có rollback tương đương. |
| NT-VPS-4 | Verify trước khi sống | Build pass, smoke/verify pass rồi mới được coi là thành công. |
| NT-VPS-5 | Mọi thay đổi phải có dấu vết | Mission, agent, file đổi, release path, trạng thái, bằng chứng smoke phải ghi vào sổ tay PG. |
| NT-VPS-6 | Một deploy một thời điểm | Phải có lock; concurrent deploy không được chạy song song. |
| NT-VPS-7 | Data production là thật, schema production là vùng nhạy cảm | Trong giai đoạn một VPS, app-dev có thể phải đọc/ghi data thật; nhưng destructive change và schema change không được trộn tự phát vào app deploy thường ngày. |
| NT-VPS-8 | Rollback nhanh là bắt buộc | Mọi quy trình hợp lệ phải rollback được trong vài giây đến vài phút. |
| NT-VPS-9 | Backup là tuyến bảo vệ dữ liệu thực tế hiện nay | Luật không giả định có DR cao cấp; vì vậy mọi thao tác chạm data/schema phải phân loại rõ để backup/restore còn khả thi khi cần. |
| NT-VPS-10 | Config production là tài sản nhạy cảm | .env.production và các config runtime sống phải có quản lý riêng, chống drift và có audit. |
| NT-VPS-11 | Mỗi loại ENV chỉ có một SSOT duy nhất trên VPS | Không được tạo nhiều bản ENV theo từng chương trình/nhiệm vụ. Mỗi loại ENV chỉ có một file SSOT duy nhất; các release/script chỉ được đọc/copy từ SSOT đó. |
| NT-VPS-12 | ENV không được lọt vào log, repo, GitHub | Secret/ENV không được echo ra log, không commit vào repo, không đẩy lên GitHub, không chép vào backup code công khai. |
§2. Mô hình thư mục chuẩn
/opt/incomex/
├── app-dev/
├── app-production/
│ ├── releases/
│ └── current -> releases/<timestamp>
├── infra/
├── deploy/
└── secrets/
└── .env.production
Quy định bắt buộc
app-production/currentlà vùng chạy thật, cấm sửa tay.app-dev/là vùng agent được sửa.infra/là vùng hạ tầng, đi theo quy trình riêng.secrets/là vùng chứa ENV/config SSOT của production.- Release production phải là thư mục bất biến sau khi build xong; không patch nóng vào release đã sống.
§3. Phạm vi cho phép và phạm vi cấm
3.1. Được phép
- Sửa mã ứng dụng trong
app-dev/ - Test cục bộ trên port dev/phụ hoặc mode verify nhanh tùy smoke profile
- Build release mới
- Atomic swap sang production
- Rollback theo script chuẩn
- Sửa hạ tầng qua quy trình
infra-deploy.sh - Trong giai đoạn hiện tại, app-dev được phép chạm production data nếu nhiệm vụ đòi hỏi và không có môi trường tách riêng
3.2. Cấm tuyệt đối
- SSH vào sửa trực tiếp trong
app-production/current/ - Bypass
app-deploy.shhoặcinfra-deploy.sh - Hotfix trong container đang chạy mà không backfill vào vùng dev/release
- Agent desktop sửa file code thực thi trực tiếp trên VPS
- Tự ý trộn destructive migration/schema patch vào app deploy loop mà không khai báo rõ
- Tạo thêm ENV mới chỉ để phục vụ từng chương trình, từng agent, từng nhu cầu riêng khi đã có ENV cùng loại làm SSOT
- In secret/ENV ra log, chat transcript kỹ thuật, Git diff, GitHub commit hoặc artifact công khai
3.3. Phân loại thao tác trong giai đoạn một VPS
Loại A — App code change thông thường
- sửa mã,
- build,
- deploy,
- verify.
Được phép theo quy trình §5.
Loại B — Data patch nghiệp vụ nhỏ, có chủ đích
Ví dụ:
- update hẹp có điều kiện rõ,
- backfill nhỏ,
- fix dữ liệu phục vụ chạy hệ thống.
Được phép có điều kiện, và phải có đủ 4 thứ:
DATA-TOUCHED=truetrong sổ tay PG- script hoặc câu lệnh truy được
- DRY-RUN/evidence trước khi chạy thật: tối thiểu
SELECT count(*)+ 5 dòng mẫu bị tác động - mô tả rõ phạm vi tác động trong
notes
Ngưỡng cứng để được coi là Loại B — phải thỏa cả 3:
SELECT count(*)dự kiến tác động ≤ 100 rows với cùng WHERE clause như câu lệnh cập nhật thật- chỉ
UPDATE/INSERT, không DELETE - chỉ đụng 1 bảng duy nhất
Vượt bất kỳ điều nào ở trên, hoặc mơ hồ về phân loại, mặc định nâng lên Loại C.
Khuyến nghị thực thi: Loại B nên chạy trong transaction wrapper BEGIN; ... COMMIT; khi kỹ thuật cho phép để giảm rủi ro thao tác tay.
Loại C — Schema change / destructive data change
Ví dụ:
- ALTER TABLE,
- DROP/DELETE diện rộng,
- đổi constraint,
- rename,
- backfill lớn có rủi ro,
- migration có thể làm app hoặc data không tương thích.
Không được coi là app deploy thường ngày. Phải đi bằng nhiệm vụ riêng và tối thiểu phải có đủ 5 điều kiện:
SCHEMA-TOUCHED=truetrong sổ tay PG- mô tả rõ UP change và rollback story
- backup point hoặc export phù hợp với phạm vi bảng/schema bị tác động
- evidence thử trước trên phạm vi hẹp hoặc transaction dry-run khi khả thi
- Owner approval explicit trong chat/task trước khi apply
3.4. Safe schema exception trong app deploy loop
Một số thay đổi schema nhỏ có thể đi cùng app deploy nếu đồng thời thỏa cả 4 điều kiện:
- additive-only, ví dụ
ADD COLUMN NULLABLE - không DROP/RENAME/ALTER destructive
SCHEMA-TOUCHED=true- có script kèm rollback story rõ ràng
Nếu không thỏa 4 điều kiện này, nó quay về Loại C đầy đủ.
§4. Vai trò và quyền hạn
| Vai trò | Quyền |
|---|---|
| Claude Code CLI / Codex / Gemini CLI | Sửa app-dev/, chạy deploy script, tạo release, rollback theo luật; có thể chạm production data trong phạm vi nhiệm vụ hợp lệ |
| Claude Desktop | Điều phối, đọc luật, soạn prompt, rà soát sổ tay; không sửa file code thực thi |
| Claude Desktop qua Agent Data | Được phép sửa tài liệu .md trong knowledge/laws nếu đi qua công cụ tài liệu có audit trail |
| Cron jobs | Backup, guard, audit, cleanup; không tự sửa code |
| Owner | Có toàn quyền, nhưng được khuyến nghị đi qua quy trình để giữ audit trail |
§5. Quy trình deploy app code
Bước 1 — Pre-check
- Lấy lock bằng
flocktrên file lock chuẩn trong/opt/incomex/deploy/ - Xác nhận không có deploy khác đang chạy
- Xác nhận baseline production đang healthy
- Ghi dòng
runningvàovps_deploy_log
Bước 2 — Sửa mã trong app-dev
- Agent chỉ sửa trong
app-dev/ - Chạy test cục bộ ở port dev khi phù hợp
- Commit hoặc ít nhất snapshot diff theo mission code
Bước 3 — Build release mới
- Tạo release timestamped trong
app-production/releases/ - Copy mã từ
app-devsang release mới - Inject ENV/config từ SSOT duy nhất trong
/opt/incomex/secrets/ - Build theo một trong hai cách:
build_method='vps_native'build_method='artifact_upload'
- Với app web nặng như Nuxt, khuyến nghị ưu tiên
artifact_uploadnếu build native gây áp lực rõ lên CPU/RAM/IO của VPS - Build fail => dừng, ghi
build_failed
Bước 4 — FAST mode / FULL mode
FULL mode
- Chạy instance tạm từ release mới ở port phụ nếu khả thi
- Verify theo smoke profile
- Smoke fail => dừng, ghi
smoke_failed
FAST mode
- Chỉ được phép nếu thỏa cả 5 điều kiện:
- diff chạm ≤ 5 files
- không đụng route/API/auth
- không đụng schema/migration
- không đụng
.envhay config service - không đụng dependency (
package.json, lock file)
- Vượt 1 điều kiện => tự động FULL mode
- Script phải kiểm dựa trên diff/path; agent không tự khai báo bằng miệng
- FAST mode bỏ qua port phụ chỉ khi smoke profile cho phép
FAST path-pattern cứng
Các path/pattern sau nếu bị chạm thì script phải tự động coi là FULL mode:
- route/API:
server/api/**,server/routes/**,pages/**,app/pages/** - auth:
server/middleware/auth*,server/utils/auth*,plugins/auth*,**/auth/** - schema/migration:
**/migrations/**,sql/**,dot/schemas/** - config:
.env*,nuxt.config.*,docker-compose*.yml,**/config/** - dependency:
package.json,package-lock.json,pnpm-lock.yaml,yarn.lock
Bước 5 — Atomic swap
ln -sfnrelease mới sangcurrent- restart/reload service cần thiết
Bước 6 — Verify production thật
- Gọi endpoint trên domain public hoặc đường nội bộ production thật
- Kiểm tra theo smoke profile: status, max size, max latency
- Nếu swap + restart quá 60 giây mà chưa healthy => rollback
Bước 6.5 — Post-deploy watch
- Theo dõi 5 phút sau deploy
- Nếu fail lặp lại vượt ngưỡng định nghĩa trong smoke profile/watch profile => auto rollback + alert
- Pass watch => đánh dấu
is_known_good=true
Bước 7 — Rollback
- Chỉ rollback về release gần nhất có
is_known_good=true - restart/reload lại service
- Ghi
rolled_back
Bước 8 — Đóng mission
- Ghi
successhoặc trạng thái cuối vào PG - Giữ retention theo §10
- Release lock
§6. Quy trình hạ tầng và quản lý config
6.0. Hạ tầng
Hạ tầng đi theo quy trình:
- lock,
- backup file gốc,
- sửa,
- test syntax/config,
- apply,
- smoke test,
- fail thì restore backup + reload lại,
- pass thì ghi sổ tay.
6.1. Quản lý .env.production
.env.production là tài sản nhạy cảm vì chứa secret + config runtime production.
Quy định:
- SSOT duy nhất của config production là
/opt/incomex/secrets/.env.production. - Không cho phép tồn tại một bản ENV khác được xem là “chuẩn” ngoài SSOT này. Release/script chỉ được copy từ SSOT để chạy.
- File này phải được bảo vệ quyền truy cập hẹp và không để lộ ra log, Git, GitHub, artifact công khai.
- Mỗi lần deploy phải ghi
env_hashvào sổ tay PG;env_hashđược tính từ SSOT duy nhất. - Guard drift config phải so hash ENV đang live trong release với hash của SSOT; lệch = alert.
- Backup
.env.productionphải đi tuyến riêng, không lẫn vào backup code công khai. - Mọi update file này phải có audit trail, không sửa lén rồi im lặng.
6.2. Nguyên tắc một ENV cho mỗi loại script/runtime
Trên VPS, mỗi loại script/runtime chỉ dùng một ENV duy nhất.
Nghĩa là:
- không tạo
.envriêng cho từng công cụ, từng agent, từng script nhỏ nếu chúng cùng một scope runtime, - không tạo thêm ENV chỉ để “phục vụ nhu cầu tạm thời”,
- khi SSOT thay đổi, mọi nơi đọc ENV phải cập nhật từ cùng một nguồn duy nhất.
Mục tiêu là tránh tình trạng:
- một chương trình dùng ENV A,
- chương trình khác dùng ENV B,
- về sau SSOT đổi nhưng chỉ một nửa hệ cập nhật.
§7. Smoke profile bắt buộc
Không hardcode cứng 3 endpoint giống nhau cho mọi app. Mỗi app phải có smoke profile riêng, có thể ở dạng YAML/JSON, tối thiểu quy định:
- endpoints
- expected_status
- max_size_bytes
- max_latency_ms
- watch rule sau deploy
- cho phép hay không cho
FAST mode - có thể hay không thể test bằng port phụ
§8. Sổ tay PG bắt buộc
CREATE TABLE vps_deploy_log (
id SERIAL PRIMARY KEY,
mission_code TEXT NOT NULL,
agent TEXT NOT NULL,
files_changed TEXT[],
release_path TEXT,
started_at TIMESTAMPTZ NOT NULL,
finished_at TIMESTAMPTZ,
status TEXT NOT NULL,
smoke_evidence JSONB,
rollback_from TEXT,
notes TEXT,
data_touched BOOLEAN NOT NULL DEFAULT false,
schema_touched BOOLEAN NOT NULL DEFAULT false,
is_known_good BOOLEAN NOT NULL DEFAULT false,
build_method TEXT,
backup_point TEXT,
env_hash TEXT
);
Bắt buộc có
- mission code,
- agent,
- thời gian bắt đầu/kết thúc,
- trạng thái,
- bằng chứng smoke,
- release path,
data_touched,schema_touched,is_known_good,build_method,env_hash.
backup_point là bắt buộc cho Loại C, và là tùy chọn có khuyến nghị cho Loại B khi phạm vi patch không còn thật sự nhỏ.
§9. DOT guard bắt buộc
| DOT | Mục tiêu |
|---|---|
dot-vps-deploy-guard |
phát hiện sửa tay trong production/current |
dot-vps-deploy-audit |
đối chiếu file thay đổi với vps_deploy_log |
dot-infra-config-guard |
phát hiện drift ở infra/ |
dot-vps-release-cleanup |
dọn release cũ theo retention policy |
dot-vps-deploy-watch |
theo dõi 5 phút sau deploy để xác nhận known-good |
dot-env-drift-check |
phát hiện drift của .env.production qua hash |
Metrics tối thiểu cần theo dõi trong giai đoạn provisional 2 tuần
- Số deploy FAST vs FULL
- Số rollback + lý do gốc
- Số nhiệm vụ bị nâng từ Loại B lên Loại C
- Số drift
.envbị phát hiện - Peak CPU/RAM/build-time khi build native
- Số bypass/warning từ
dot-vps-deploy-audit
§10. Chuyển đổi từ trạng thái hiện tại và retention
- Tạo cấu trúc
app-dev/,app-production/,infra/,deploy/,secrets/ - Snapshot mã hiện tại trên VPS thành release legacy đầu tiên
- Trỏ
currentsang release legacy đó - Khởi tạo
vps_deploy_log - Tăng tần suất backup code/data lên mức phù hợp khi cần, có thể 5–6 lần/ngày nếu dữ liệu bắt đầu đáng kể hơn
- Chạy audit backfill cho các thay đổi gần đây chưa có sổ tay
- Sau đó mọi thay đổi mới phải đi qua Điều 41
Retention policy
- Giữ tối thiểu 5 release gần nhất
- và giữ mọi release trong 24 giờ gần nhất
- không bao giờ xóa release đang được
currenttrỏ tới
§11. Các chỉnh lý chính sau phản biện vòng 3
Đã tiếp thu
- thêm path-pattern cứng cho FAST/FULL mode
- chốt SSOT duy nhất của
.env.production - thêm nguyên tắc một ENV duy nhất cho mỗi loại runtime/script
- siết không cho ENV lọt vào log / Git / GitHub
- thêm metrics giai đoạn provisional 2 tuần
- làm rõ
SELECT count(*)của Loại B phải dùng cùng WHERE clause
Chưa tiếp thu toàn phần
- Không đưa known-good 3 tầng thành bắt buộc: quá phức tạp cho giai đoạn một VPS;
is_known_goodmột tầng đủ cho provisional. - Không bắt buộc đồng bộ secret/ENV vào GitHub hoặc repo: điều này đi ngược nguyên tắc không để ENV lọt repo. SSOT của ENV nằm trên VPS trong
secrets/; backup/DR của ENV phải đi tuyến riêng. - Không ép line-count làm tiêu chí FAST mode: risk area/path vẫn là tiêu chí chính xác hơn.
§12. Kết luận ngắn
Điều 41 v0.5.1 chấp nhận thực tế hiện nay: một VPS duy nhất, một DB thật duy nhất, agent cần quyền đủ mạnh để sửa nhanh trên VPS. Nhưng quyền đó không phải quyền sửa bừa. Luật buộc mọi thao tác phải đi trên một đường ray có tách vùng, có lock, có smoke profile, có FAST/FULL mode, có rollback về known-good, có audit trail, có guard chống drift, có quản lý config production theo SSOT duy nhất, và có nguyên tắc một ENV duy nhất cho mỗi loại runtime/script trên VPS.