hs:test
Runs tests for what just changed, then reports honestly. A failing test is information, not an enemy — never deleted, skipped, or weakened to fake green. The final verdict and a checks[] array land in verification.json, the exact evidence the hard gate reads.Chạy test cho phạm vi vừa đổi, rồi báo cáo thật. Test fail là thông tin, không phải kẻ thù — không bao giờ xóa/skip/weaken để xanh giả. Verdict cuối + mảng checks[] vào verification.json, đúng bằng chứng hard gate đọc.
When to useKhi nào dùng
✓ Reach for it when✓ Dùng khi
- a phase just changed code and needs a verdictmột phase vừa đổi code và cần verdict
- before a hard stage — run the integration profiletrước stage cứng — chạy profile integration
- you need a tight, honest QA reportbạn cần một QA report gọn, thật
✗ Won't do✗ Sẽ không làm
- delete / skip / weaken a test for fake greenxóa / skip / weaken test để xanh giả
- write PASS while the suite is failingghi PASS khi suite đang fail
- run blind — preflight stops on missing depschạy mò — preflight dừng khi thiếu dep
How to run itCách chạy
Invoke /hs:test after a phase changes code. The standard command is python3 -m pytest harness/tests/ -q (target repos run their own suite per standards).Gọi /hs:test sau khi một phase đổi code. Lệnh chuẩn là python3 -m pytest harness/tests/ -q (repo đích chạy suite riêng theo standards).
Pre-flightPre-flight
preflight_deps.py checks pytest/PyYAML/defusedxml — missing → stop with the install command. Then a quick import-check of the changed module.preflight_deps.py kiểm pytest/PyYAML/defusedxml — thiếu → dừng với lệnh cài. Rồi import-check nhanh module vừa đổi.
Pick a profileChọn profile
unit (changed module → full unit suite) for every TDD cycle; integration (adds the e2e vertical slice) before a hard stage.unit (module vừa đổi → toàn suite unit) cho mỗi vòng TDD; integration (thêm e2e vertical slice) trước stage cứng.
Run, then read honestlyChạy, rồi đọc thật
100% pass is the gate. Fix the code, or fix a genuinely-wrong test with a stated reason — never delete, skip, or weaken a test to fake green.100% pass là gate. Sửa code, hoặc sửa một test SAI thật kèm lý do — không bao giờ xóa, skip hay weaken test để xanh giả.
QA reportQA report
Under 200 lines: every failing test by name + a one-line reason, coverage judged only against a floor the repo declares, named with where it was read (codemap.yaml coverage.floors, coverage-floors.yaml, fail_under, coverageThreshold) — with none declared the number is reported, not judged; a test that failed and then passed on a rerun stays listed as flaky; and one final verdict.Dưới 200 dòng: mọi test fail kèm tên + một dòng lý do, coverage chỉ được chấm theo ngưỡng mà repo tự khai, kèm nơi đọc ra (codemap.yaml coverage.floors, coverage-floors.yaml, fail_under, coverageThreshold) — không khai ngưỡng nào thì con số chỉ được reported, không chấm; test đỏ rồi xanh khi chạy lại vẫn bị ghi là flaky; và một verdict cuối.
Write the verdictGhi verdict
The verdict + checks[] array go into verification.json (schema artifact-verification.json) — the exact evidence the hard gate reads.verdict + mảng checks[] vào verification.json (schema artifact-verification.json) — đúng bằng chứng hard gate đọc.
hs-code test run runs the vitest or jest a repo declares in codemap.yaml (on an hs-rops lane with --rops), reads the verdict from the tool's own result file, never its exit code, and says how many tests ran, failed and were skipped. A test file the runner could not load is a FAIL naming it. test prove, test mutation and test isolation-bisect run the same tests in a copy of the tree.Test của repo TypeScript do chính harness chạy. hs-code test run chạy vitest hoặc jest mà repo khai trong codemap.yaml (trên lane hs-rops với --rops), đọc verdict từ tệp kết quả của chính công cụ, không bao giờ từ exit code, và nói bao nhiêu test đã chạy, đỏ và bị bỏ qua. Tệp test runner không nạp được là FAIL nêu tên tệp. test prove, test mutation và test isolation-bisect chạy cùng các test đó trong một bản sao của cây.A real run, and the verdictLần chạy thật, và verdict
The whole suite, greenCả suite, xanh
The real run over harness/tests/ — unit tests plus bug-class invariants, all passing. 100% pass is the gate; anything less raises a local advisory (exit 0) that never blocks you — fix it before you ship. real output
Lần chạy thật trên harness/tests/ — test unit cộng invariant bug-class, tất cả pass. 100% pass là gate; thiếu một cái sẽ phát advisory tại máy (exit 0) không bao giờ chặn bạn — sửa trước khi ship. đầu ra thật
........................................................................ [ 98%] ........................................................................ [ 98%] ........................................................................ [ 98%] ........................................................................ [ 99%] ........................................................................ [ 99%] ........................................................................ [ 99%] ........................................................................ [100%] 22405 passed, 418 skipped, 1 xfailed, 21 warnings in 276.29s (0:04:36)
The verdict the gate readsVerdict mà gate đọc
The QA result is serialized as verification.json — stage, actor, a checks[] array, and one final verdict. The gate reads exactly this off disk. captured artifact
Kết quả QA serialize thành verification.json — stage, actor, mảng checks[], và một verdict cuối. Gate đọc đúng cái này từ đĩa. artifact đã ghi
{
"stage": "push",
"plan": "260818-0400-rate-limit-middleware",
"phase": "p1",
"actor": "user:dev@team.example",
"ts": "2026-08-18T04:12:41.118203+00:00",
"checks": [
{
"name": "preflight_deps",
"status": "PASS",
"detail": "22 declared deps resolved"
},
{
"name": "pytest harness/tests",
"status": "PASS",
"detail": "22405 passed, 418 skipped"
},
{
"name": "schema load yaml+json",
"status": "PASS",
"detail": "yaml ok, schemas ok"
},
{
"name": "verify_install --strict",
"status": "PASS",
"detail": "manifest 3490 files"
},
{
"name": "e2e vertical slice",
"status": "PASS",
"detail": "advisory-then-pass, transport=simulated-stdin"
}
],
"verdict": "PASS"
}
A captured snapshot (actor scrubbed, counts from when it was written). Any check with status FAIL raises a local advisory (exit 0) — it never blocks; fix the failing check before you ship. Schema: harness/schemas/artifact-verification.json.Một bản chụp đã ghi (actor đã làm sạch, số liệu từ lúc nó được ghi). Bất kỳ check nào status FAIL sẽ phát advisory tại máy (exit 0) — không bao giờ chặn; sửa check fail trước khi ship. Schema: harness/schemas/artifact-verification.json.
Two profilesHai profile
| ProfileProfile | ScopePhạm vi | WhenKhi nào |
|---|---|---|
| unit (default) | changed module → whole unit suitemodule vừa đổi → toàn suite unit | every TDD loopmỗi vòng TDD |
| integration | adds the e2e vertical slicethêm e2e vertical slice | before a hard stagetrước stage cứng |
coverage-grid artifact tells test which axis combinations and risk classes deserve a case — a thin or [JUSTIFIED-THIN] cell is a hint about where edge cases hide. It's consumed advisory: absent → silent, never a block. For structured edge-case discovery beyond the grid, hs:scenario now decomposes a feature through an ISO 25010 coverage matrix plus stakeholder & lifecycle dimensions. See Methodology.Đọc coverage grid, advisory. Khi một plan chạy ở grid mode, artifact coverage-grid của nó cho test biết tổ hợp trục và lớp rủi ro nào đáng có một case — một ô mỏng hay [JUSTIFIED-THIN] là gợi ý nơi edge case ẩn. Nó được tiêu thụ advisory: vắng → im, không chặn. Để khám phá edge case có cấu trúc ngoài grid, hs:scenario giờ phân rã tính năng qua ma trận coverage ISO 25010 cộng chiều stakeholder & lifecycle. Xem Phương pháp.Three verdicts, no fourth way outBa verdict, không có lối thứ tư
The QA report (<200 lines) lists every failing test by name with a one-line reason, any meaningful coverage change, and ends with one verdict:QA report (<200 dòng) liệt kê mọi test fail kèm tên + một dòng lý do, mọi thay đổi coverage đáng kể, và kết bằng một verdict:
PASS ships. PASS_WITH_RISK ships but names the risk out loud. BLOCKED doesn't ship — fix the code, or fix a genuinely-wrong test with a stated reason. Removing a test to go green is never an option.PASS thì ship. PASS_WITH_RISK ship nhưng nêu rõ risk. BLOCKED không ship — sửa code, hoặc sửa một test SAI thật sự kèm lý do. Xóa test để xanh không bao giờ là lựa chọn.
gate_stage.py reads verification.json: any check at FAIL raises a local advisory (exit 0) naming the gap — it never blocks you locally. What hard-blocks with no CI required: the path-keyed write floors and the artifact-forgery check. A dishonest PASS still carries an attribution trail — the trace records who wrote it either way.
gate_stage.py đọc verification.json: bất kỳ check nào FAIL sẽ phát advisory tại máy (exit 0) nêu chỗ thiếu — không bao giờ chặn bạn tại máy. Cái chặn cứng mà không cần CI: các sàn ghi theo đường-dẫn và check chống-giả-mạo artifact. Một PASS gian dối vẫn mang theo dấu vết attribution — trace ghi ai đã viết dù thế nào.
FAQHỏi đáp
Can I skip a flaky test to go green?Skip test hay nhiễu để xanh được không?
Unit or integration profile?Profile unit hay integration?
unit (default) runs the changed module plus the full unit suite on every TDD cycle. integration adds the e2e vertical slice — run it before a hard stage (push/pr/ship).unit (mặc định) chạy module vừa đổi cộng toàn suite unit mỗi vòng TDD. integration thêm e2e vertical slice — chạy trước stage cứng (push/pr/ship).What do the three verdicts mean?Ba verdict nghĩa là gì?
PASS ships. PASS_WITH_RISK ships but names the risk out loud. BLOCKED does not ship until the code (or a genuinely-wrong test) is fixed.PASS thì ship. PASS_WITH_RISK ship nhưng nêu rõ risk. BLOCKED không ship đến khi sửa code (hoặc một test SAI thật).Does hs:test fix the failing code?hs:test có sửa code fail không?
hs:cook / hs:fix; post-test review is hs:code-review; deep root-cause tracing is hs:debug.Không — nó chỉ chạy và báo cáo. Sửa là hs:cook / hs:fix; review sau test là hs:code-review; truy nguyên nhân gốc là hs:debug.What if someone writes PASS while the suite is failing?Nếu ai đó ghi PASS khi suite đang fail?
actor is attribution, not proof of identity. Wire the optional receipts-gate CI workflow into your own repo if you want a re-run to catch it too.Tại máy, không gì chặn lần ghi đó — gate chỉ advisory. Cái còn lại là trace: sổ ghi ai đã viết, nên nó trung thực rằng mình là presence gate — actor là attribution, không phải bằng chứng danh tính. Gắn workflow CI receipts-gate (tùy chọn) vào CI của repo bạn nếu muốn một lần chạy lại bắt được nó nữa.