Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .claude/skills/boot/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ description: Đọc doctrine + diagram + evidence gần nhất của agent-hub,
đó không xuất hiện trong phiên này.
3. Đọc `agent-hub/doctrine/MEMORY.md` — lấy path, stack, lệnh chính xác.
4. Đọc `agent-hub/doctrine/domains/PROJECT.md` — invariants/traps/decisions.
5. Đọc mọi file trong `agent-hub/haven/diagrams/` — đếm node theo PM status.
5. Đọc mọi file trong `agent-hub/haven/diagrams/` **TRỪ** file có chữ
`archive` trong tên (`dev-loop-archive.md`...) — [sửa 2026-09-05] đó là
cold storage theo thiết kế (xem ghi chú token-discipline trong
`dev-loop.prime-mermaid.md` + `hub-tokens.md`), đọc lại mỗi phiên phá
vỡ đúng mục đích archive. Chỉ đếm node + PM status từ file KHÔNG phải
archive.
6. Đọc `agent-hub/haven/workers/*/manifest.yaml` — roster worker khả dụng.
7. Đọc tối đa 5 evidence note gần nhất trong `agent-hub/evidence/`
(implementer + verifier, mới nhất trước). Để liệt kê, dùng
Expand Down
80 changes: 80 additions & 0 deletions .claude/skills/persona-load/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
name: persona-load
description: "Load an on-demand expert-persona or a named panel from this project's own persona library (outside agent-hub/), printing the loader's SEALED output for the current worker session to read. Advisory only, read-only, no side effects."
argument-hint: "<category>/<name> | -p <panel> | -l [category]"
---

# /persona-load — load an expert persona or panel on demand

Read-only. Wraps this project's own `scripts/load_persona.sh` (lives in
the code repo, NOT in `agent-hub/` — a persona loader is code, and
`CODE_IN_HAVEN` forbids code inside `haven/`). Prints one persona or a
whole panel so the current implementer/verifier pass can borrow that
expert's judgment on a domain-specific question — advisory only, never a
substitute for real evidence.

## Why this exists
A persona is a high-precision pointer into the model's latent space:
naming a real expert activates a cluster of domain knowledge that would
otherwise take paragraphs to restate. Loading ALL personas up front gives
zero lift and wastes tokens (empirically, per the persona-system brief
this skill implements) — this command is the on-demand hook so a worker
only pays for the 1 persona (or panel of 2-4) actually relevant to the
task at hand.

## Steps
1. **Locate the loader.** Check `scripts/load_persona.sh` exists at the
project root (or whatever `<<root>>` this project declared in
`doctrine/domains/PROJECT.md`, if it did). If it doesn't exist, stop
and report: "persona system not set up in this project — build it
first via `/worker implementer` using the persona-system brief, then
retry" — never fabricate a persona inline as a fallback.
2. **Parse `$ARGUMENTS`**:
- `<category>/<name>` → load that one persona file.
- `-p <panel>` → load every member of that named panel (2-4 files).
- `-l [category]` → list available personas (all, or filtered to one
category) instead of loading content — for browsing.
- No/invalid arguments → run `scripts/load_persona.sh -h` and print
its usage output verbatim, don't invent your own usage text.
3. **Run the loader for real** (`scripts/load_persona.sh <args>`), READ
BACK its stdout verbatim — this includes the `=== SEAL ===` header +
sha256 the script itself prints. Never paraphrase a persona's content
into your own summary; print what the script actually returned.
4. **Use the result as a lens, not a ruling.** Whatever the loaded
persona/panel says informs the current implementer's or verifier's
judgment on a domain-specific question. It NEVER overrides a hard rule
(`TestsBeforeDone`, `EvidencePerAction`, `NeverVerifyOwnWork`, the 5
forbidden states, this project's own `doctrine/`) and never counts as
evidence by itself — a verifier still needs a real cited test/output
to SEAL; "persona X approved this" is not an acceptance criterion.

## Hard rules honored
- `PersonaAsLensNotAuthority` — a persona/panel informs judgment, never
grants capability, never overrides `doctrine/`/the 5 forbidden
states/a safety file, never substitutes for real evidence. Layering:
`<<project's safety file>> > agent-hub doctrine > repo conventions >
persona`.
- `CodeStaysOutOfHaven` — the loader script and persona library live in
the project's own code tree, never inside `agent-hub/haven/` or
`agent-hub/doctrine/` (would trip `CODE_IN_HAVEN`, and would silently
inflate the recurring per-session token cost `/hub-tokens` tracks).
- `ReadBackBeforeClaim` — always print the loader's real stdout, never a
paraphrase of what a persona file "probably says".

## Failure branches
| Failure | Handling |
|---|---|
| `scripts/load_persona.sh` missing | Report "not set up yet", point at building it via `/worker implementer`, stop — don't invent persona content inline |
| Requested `<category>/<name>` or panel not found | Let the loader's own "fail loudly with a suggestion" behavior surface — print its real stderr, don't guess a substitute persona |
| Loader script errors out (bad permissions, syntax) | Report the real error verbatim, don't retry with `sudo`/`chmod` or work around it silently |

## Runtime
`/persona-load <category>/<name>` — load one persona.
`/persona-load -p <panel>` — load a whole panel.
`/persona-load -l [category]` — list available personas.
Requires the project to already have its persona system built (loader +
library in its own code tree — see `doctrine/domains/PROJECT.md` for this
project's `<<root>>`/safety-file names if declared there). Building that
system the first time is a normal code change — run it through
`/worker implementer "build the on-demand expert-persona system"` like
any other task, not through this command.
15 changes: 14 additions & 1 deletion .claude/skills/worker/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ argument-hint: <implementer|verifier> "<task>"
> Chạy MỘT worker cho MỘT task. Không bao giờ làm việc "chung chung" ngoài
> vai trò — mọi hành động phải trace về `haven/workers/<wid>/`.

> [thêm 2026-09-05] Riêng `verifier`, tham số task có thể là 1 đường dẫn
> evidence note, NHIỀU đường dẫn cùng lúc (batch), hoặc từ khoá
> `all-pending` (mọi node đang `sealed_pending_verifier` trên diagram
> active) — xem "Batch verify" trong `recipes/verify_seal.md`. Batch chỉ
> gộp chi phí spawn subagent (load bundle 1 lần cho cả lô), verdict vẫn
> tính RIÊNG, ĐỘC LẬP cho từng node.

## Vòng chạy bắt buộc
1. **Load bundle** — đọc đúng thứ tự:
`agent-hub/haven/workers/<wid>/manifest.yaml` →
Expand All @@ -26,7 +33,13 @@ argument-hint: <implementer|verifier> "<task>"
chấm, và node liên quan trên diagram. Subagent tự đọc note + diagram +
`CLAUDE.md`, tự viết verdict vào `evidence/verifier/`, tự cập nhật PM
status nếu SEAL. Đây chính là cách hiện thực `NeverVerifyOwnWork` thật
— subagent không có lịch sử hội thoại của lượt implement.
— subagent không có lịch sử hội thoại của lượt implement. [thêm
2026-09-06] Không có hook nào chặn thật việc bỏ qua bước spawn này —
`NeverVerifyOwnWork` là ràng buộc hạ tầng, không phải lời hứa tự
giác. Phòng vệ thật là dấu vết citeable: `recipes/verify_seal.md`
bước 1b bắt verifier ghi bằng chứng spawn riêng vào dòng
`## Isolation proof` của verdict note, để 1 audit sau này phát hiện
được nếu bước tách context bị bỏ qua.
3. **Follow recipe** — chọn recipe khớp `quick_actions` của worker:
- `implementer`: `pick_next` rồi `implement` (xem
`recipes/pick_next.md`, `recipes/implement.md`).
Expand Down
1 change: 1 addition & 0 deletions agent-hub/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
haven/diagrams/*.prime-mermaid.md merge=union
6 changes: 6 additions & 0 deletions agent-hub/evidence/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ Date as `YYYY-mm-dd`, slug kebab-case from the task name.
## Format — verifier verdict
- Worker (subagent, dispatched via Agent tool) · Node · New PM status
(PENDING/SEALED/REOPEN)
- `## Isolation proof` — [added 2026-09-06, fed back from real production
use in `datvt243.github.io`] cites whatever makes this a genuinely
separate subagent spawn (see `recipes/verify_seal.md` step 1b) — not
technically enforced by a hook, but a missing/suspicious line here is
itself citeable evidence for a later audit that `NeverVerifyOwnWork`'s
subagent-isolation step was skipped.
- `## Reasoning` — cite evidence for each criterion
- `## Missing` — only present on REOPEN
- `## Re-run` — [added 2026-09-02] `none`/`partial`/`full`, declared
Expand Down
4 changes: 4 additions & 0 deletions agent-hub/haven/workers/implementer/manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,9 @@ hard_rules:
- SmallestDiff # prefer the smallest diff, no extra rename/refactor
- TestsBeforeDone # must run real tests before reporting done
- NodeBeforeCode # must have a diagram node before writing code
- AppendOnly # [added 2026-09-05] new node rows always appended at
# the end of the PM status table, never inserted mid-
# table — required for agent-hub/.gitattributes'
# merge=union to merge cleanly across branches
reads: [NORTHSTAR.md, doctrine/MEMORY.md, doctrine/domains/, haven/diagrams/]
writes: [evidence/implementer/]
7 changes: 5 additions & 2 deletions agent-hub/haven/workers/implementer/recipes/pick_next.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
— reuse from `/boot` if available (see GUARD above), else `Read` fresh.
2. Get every diagram in `haven/diagrams/`, list every node + PM status —
reuse from `/boot` if available (see GUARD above), else `Read` fresh.
[clarified 2026-09-05] "every diagram" means every file WITHOUT
`archive` in its name — an archive file is cold storage, not re-read
here, matching `/boot` step 5's rule exactly.
3. Find the earliest PENDING node on the critical path (e.g. the seed node
`fix-chrome-executable-path` in `dev-loop.prime-mermaid.md`).
4. No match → don't invent work; report "no PENDING node" clearly, stop.
Expand All @@ -36,12 +39,12 @@
the line `## Hub bytes before: <N>` from step 7.

## Hard rules honored
`NodeBeforeCode` | `EvidencePerAction` | `NoSilentFailure`
`NodeBeforeCode` | `EvidencePerAction` | `NoSilentFailure` | `AppendOnly`

## Failure branches
| Failure | Handling |
|---|---|
| No diagram exists yet | Create `haven/diagrams/<slug>.prime-mermaid.md` matching the `dev-loop` format |
| No diagram exists yet | Create `haven/diagrams/<slug>.prime-mermaid.md` matching the `dev-loop` format. [added 2026-09-05] Always APPEND the new row at the END of the PM status table, never insert it in the middle — required for `agent-hub/.gitattributes`' `merge=union` to merge cleanly when 2 branches each add a different new node around the same time. |
| Task is ambiguous | Stop and ask, don't guess |

## Runtime
Expand Down
3 changes: 3 additions & 0 deletions agent-hub/haven/workers/verifier/manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ hard_rules:
- EvidenceOnly # never trust inference over real evidence
- NeverVerifyOwnWork # never grade a diff you wrote yourself
- RatchetOnly # PM status only moves forward, never backward
- AppendOnly # [added 2026-09-05] update a node's own row IN PLACE
# on SEAL — never reorder/move rows in the PM status
# table, same reason as the implementer's AppendOnly
reads: [evidence/implementer/, haven/diagrams/, doctrine/MEMORY.md, CLAUDE.md]
# doctrine/MEMORY.md: recipe step 4 needs it to check the note's command.
# No NORTHSTAR.md — recipe never uses it, was dead weight on every spawn.
Expand Down
61 changes: 52 additions & 9 deletions agent-hub/haven/workers/verifier/recipes/verify_seal.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,38 @@
> the gate.

# Contract
- Input: path to an evidence note under `evidence/implementer/`.
- Output: `{verdict: SEAL|REOPEN, node, cited: string[], missing: string[],
forbidden_hit: string|null, pm_updated: boolean}`
- Input: path to an evidence note under `evidence/implementer/`, OR
multiple paths (batch), OR `all-pending` (every node currently
`sealed_pending_verifier` on the active diagram — see "Batch verify"
below). [batch added 2026-09-05]
- Output: AN ARRAY, 1 element per node: `{verdict: SEAL|REOPEN, node,
cited: string[], missing: string[], forbidden_hit: string|null,
pm_updated: boolean, rerun: none|partial|full, isolation_proof:
string}` — `isolation_proof` is a real self-declaration (step 1b), not
inferred from outside.
- REFUSAL: if this exact session wrote the diff under review → refuse
immediately: "I wrote this, a separate verifier pass is required."
(`NeverVerifyOwnWork`) — in practice moot, since verify_seal runs as a
fresh subagent dispatched via the Agent tool with no implementation
history.
history. In a batch, this check still applies PER NODE: refuse just a
self-written node, don't cancel the rest of the batch.

## Batch verify [added 2026-09-05]
The heaviest cost of a verify pass isn't the act of verifying — it's
reloading the whole bundle + doctrine on every subagent spawn. Batch
verify pays that cost EXACTLY ONCE for N nodes instead of N times,
without changing anything about the substance of verifying:
- The fresh-subagent-context guarantee + self-refusal check (step 1)
apply ONCE for the whole batch.
- Steps 2-13 (read note, check criteria, scan forbidden states, verdict,
write verdict, Re-run declaration) run REPEATEDLY, INDEPENDENTLY, for
EACH node — using node A's evidence/reasoning to infer node B's verdict
is forbidden, even if the two notes look similar. Each node still gets
its own evidence, own verdict, own verdict note.
- Being in a batch is NEVER an excuse to loosen any criterion in steps
2-13 — batching only folds the SPAWN COST, never the VERDICT.
- `all-pending`: first list every `sealed_pending_verifier` node on
`dev-loop.prime-mermaid.md`, then run the full procedure below on each.

## Re-run scope [cost-driven, added 2026-09-02]
Default: AUDIT the note, don't independently re-run `npm test`/`npm run
Expand Down Expand Up @@ -38,8 +62,16 @@ asks for — this section pins the boundary.
## Steps
1. REFUSE SELF-GRADING FIRST — did I write this diff in this session? (No,
by construction — subagent has a fresh context.)
2. Read the NOTE — only the note, do NOT open the diff directly.
(`EvidenceOnly`)
1b. [added 2026-09-06, fed back from real production use in
`datvt243.github.io`] Record proof this pass is really a separate
subagent context, not a self-report: cite whatever this invocation was
actually spawned with that the implementer pass didn't have (e.g. the
`description`/task string passed to the Agent tool for this spawn) —
write it into the note's `## Isolation proof` line (step 12a). No hook
technically blocks a skipped isolation — this only leaves a citeable
trail for a later audit.
2. [LOOP STARTS HERE FOR EACH NODE if batch] Read the NOTE — only the
note, do NOT open the diff directly. (`EvidenceOnly`)
3. Read the NODE — pull acceptance criteria from `haven/diagrams/`,
forbidden states from `CLAUDE.md`. [GUARD, added 2026-08-31] Don't `Read
agent-hub/CLAUDE.md` yourself for this — same mechanism as
Expand All @@ -61,8 +93,14 @@ asks for — this section pins the boundary.
10. Verdict is exactly one of: SEAL (every criterion has cited evidence)
or REOPEN (one important gap is enough).
11. Only on SEAL: update the ratchet/PM status on
`haven/diagrams/dev-loop.prime-mermaid.md`.
`haven/diagrams/dev-loop.prime-mermaid.md`. [added 2026-09-05] Update
the node's own row IN PLACE (state column → SEALED) — never reorder,
move, or re-sort rows in the table (`AppendOnly`); this keeps
`agent-hub/.gitattributes`' `merge=union` able to merge cleanly
across branches.
12. Write the verdict to `evidence/verifier/<date>/<slug>-{seal|reopen}.md`.
12a. [added 2026-09-06] In that note, include the `## Isolation proof`
line from step 1b.
12b. [added 2026-09-02] In the verdict note, truthfully declare 1 line
`## Re-run`: `none` (audit-only, the correct default per "Re-run
scope" above), `partial` (name exactly which command was re-run), or
Expand All @@ -84,7 +122,8 @@ asks for — this section pins the boundary.
rest of `evidence/`.

## Hard rules honored
`NeverVerifyOwnWork` | `EvidenceOnly` | `VerdictOnly` | `RatchetOnly`
`NeverVerifyOwnWork` | `EvidenceOnly` | `VerdictOnly` | `RatchetOnly` |
`AppendOnly`

## Failure branches
| Failure | Handling |
Expand All @@ -96,4 +135,8 @@ asks for — this section pins the boundary.
## Runtime
Dispatched as a subagent (Agent tool) by `/worker verifier "<task or
note>"` or by `/todo` round 2 — never run in the implementer's own
session.
session. [added 2026-09-05] `/worker verifier "<path1> <path2> ..."`
(multiple evidence note paths) or `/worker verifier all-pending` spawns
ONE subagent that verifies every queued node independently — use this
after several small implementer passes have piled up, instead of one
`/worker verifier` call per node.
Loading