feat(blocks): 5 cognitive mode blocks + 2 manifest wirings

- mode-skeptic (17 LOC) — doubt everything, E1/E2 grade evidence
- mode-devils-advocate (16) — steel-man the opposite
- mode-minimalist (18) — what is unnecessary?
- mode-maximalist (19) — 10x thinking for broad scope
- mode-first-principles (21) — derive from invariants

kei-critic += skeptic + devils-advocate
kei-architect += first-principles

Docs: _blocks/README.md + README.md paragraph under Behavioral blocks
This commit is contained in:
Parfii-bot 2026-04-22 13:49:57 +08:00
parent 4b0185a3d1
commit d50c5a56ae
9 changed files with 166 additions and 3 deletions

View file

@ -112,6 +112,33 @@ Profile resolution lives in `_primitives/MANIFEST.toml` — one `[primitive.<nam
> **Re-install disclaimer:** `install.sh` is idempotent for clean state but **overwrites kit-owned `_blocks/`, `_primitives/`, `_bridges/`, `_templates/`, `_assembler/`, `hooks/`, and `skills/` on re-run** — local modifications under those directories are backed up to `<dir>.bak-TIMESTAMP/` (or, for shared hook files, to `<file>.bak-TIMESTAMP`). User-owned `_manifests/*.toml` are never overwritten.
## Runtime hook controls
Every kit-shipped hook (v0.14.2+) honours two env vars so you can silence noise or isolate a failure without editing `~/.claude/settings.json`:
- `KEI_DISABLED_HOOKS` — comma- or space-list of hook base names (no `.sh`), e.g. `KEI_DISABLED_HOOKS=site-wysiwyd-check,milestone-commit-hook`. The literal `all` disables every hook.
- `KEI_HOOK_PROFILE` — one of `full` (default), `advisory-off`, `minimal`, `off`.
| Profile | What stays on |
|---|---|
| `full` (default) | Every hook |
| `advisory-off` | Disables pure-stderr advisories (`recurrence-suggest`, `citation-verify`, `error-spike-detector`, `milestone-commit-hook`). Safety gates stay on. |
| `minimal` | Only safety-critical: `no-github-push`, `genesis-leak-guard`, `no-hand-edit-agents`, `secrets-guard`, `assemble-validate`, `git-pre-commit-genesis`. Everything else off. |
| `off` | Every hook off — escape hatch for debugging hook interactions. |
```bash
# One-session disable of a single noisy hook:
export KEI_DISABLED_HOOKS=site-wysiwyd-check
# Permanent quieter profile (paste into ~/.zshrc / ~/.bashrc):
export KEI_HOOK_PROFILE=advisory-off
# Full re-enable:
unset KEI_DISABLED_HOOKS KEI_HOOK_PROFILE
```
Interactive wizard: run `/hooks-control` — click-only picker that shows current state and emits the `export` / `unset` command for you to paste. The skill never executes anything itself.
## What you get
| Category | Count | Examples |
@ -127,6 +154,8 @@ Profile resolution lives in `_primitives/MANIFEST.toml` — one `[primitive.<nam
Of the 73 blocks, the **8 base blocks** (`baseline`, `evidence-grading`, `memory-protocol`, `rule-pre-dev-gate`, `rule-test-first`, `rule-error-budget`, `rule-double-audit`, `rule-math-first`) are referenced directly by the 12 shipped manifests. The remaining blocks (`stack-*`, `deploy-*`, `api-*`, `scraper-*`, `domain-*`) are a library consumed by the `/new-agent` wizard and the hub-and-spoke pipeline skills: when you compose a project specialist or spin up a site, the wizard / pipeline picks the appropriate blocks and emits artefacts that reference them.
**Cognitive mode blocks** (`_blocks/mode-*.md`) are composable behavioural skews — `mode-skeptic`, `mode-devils-advocate`, `mode-minimalist`, `mode-maximalist`, `mode-first-principles`. Add any combination to an agent's manifest `blocks = [...]` list to stack the mode. Modes compose: `mode-skeptic` + `mode-minimalist` gives you an adversarial pruner; `mode-devils-advocate` + `mode-first-principles` gives a constraint-driven steel-manner. See `_blocks/README.md` for the full list.
## Creating a new agent
Run the wizard in Claude Code:

40
_blocks/README.md Normal file
View file

@ -0,0 +1,40 @@
# `_blocks/` — Composable Agent Content
Each `.md` file in this directory is a **block**: a single-concern, standalone-readable snippet that any agent manifest can include via its `blocks = [...]` list. The `_assembler` concatenates selected blocks + manifest metadata into the final agent `.md` that Claude Code loads.
Blocks are grouped by prefix:
| Prefix | Purpose |
|---|---|
| `baseline`, `evidence-grading`, `memory-protocol` | Obligatory base — every manifest must include these |
| `rule-*` | Discipline rules (`pre-dev-gate`, `test-first`, `error-budget`, `double-audit`, `math-first`) |
| `mode-*` | Cognitive mode blocks (see below) |
| `stack-*` | Language / framework constraints (Rust Axum, React Vite, Swift SPM, …) |
| `deploy-*` | Deployment target rules (Modal, AWS EC2, Cloudflare, Hetzner, …) |
| `api-*` | External API conventions (Apify, fal.ai, ElevenLabs, Anthropic, …) |
| `db-*` | Database rules (Postgres, SQLite, Drizzle, sqlx, migrations) |
| `auth-*`, `security-*`, `obs-*`, `ci-*`, `test-*`, `scraper-*`, `domain-*`, `docs-*` | Domain-specific rules |
## Cognitive mode blocks
Composable behavioural skews. Add any combination to a manifest's `blocks` list to stack the mode. Modes compose — e.g. `mode-skeptic` + `mode-minimalist` yields an adversarial pruner.
| Block | Purpose |
|---|---|
| `mode-skeptic.md` | Doubt the conclusion until proved; flag claims without E1/E2 grade |
| `mode-devils-advocate.md` | Steel-man the opposite; name the strongest objection before agreeing |
| `mode-minimalist.md` | Prefer deleting over adding; justify every addition against existing code |
| `mode-maximalist.md` | Explore 10× scope; return both maximum and minimum bounds; only when user invokes exploration |
| `mode-first-principles.md` | Derive from invariants; cite the physical / mathematical constraint, not "best practice" |
## Adding a new block
1. Pick a stable prefix (existing category or a new one documented here).
2. One concern per file. 2050 LOC target, `<200 LOC` hard cap (Constructor Pattern).
3. Imperative voice (`"Do X"` not `"the agent should do X"`) — these land verbatim in agent prompts.
4. Standalone-readable — do not assume sibling blocks are present. Cross-references OK, hard dependencies not.
5. Reference from a manifest's `blocks = [...]` list; the assembler validates existence.
## Ownership
Blocks are **kit-owned**`install.sh` overwrites `_blocks/` on re-run, backing up local edits to `_blocks.bak-TIMESTAMP/`. User-owned content belongs in `_manifests/*.toml` (which are never overwritten).

View file

@ -0,0 +1,16 @@
# MODE — Devil's Advocate
Your job is to steel-man the opposite of whatever seems right.
Before agreeing with any plan, articulate the strongest argument AGAINST it:
- What is the hidden cost the user missed?
- Who or what suffers when this ships? (downstream consumers, on-call, future maintainers, the user in 6 months)
- Under what realistic condition does this silently degrade instead of fail loud?
- What is the reversal cost if we are wrong?
Do not be contrarian for its own sake. Find the REAL failure mode and name it. A fabricated objection wastes the user's attention and dulls the tool.
If the opposition genuinely has no merit after honest steel-manning, say so explicitly — `"considered the strongest objection X; does not apply because Y"`. That closes the loop; unspoken "I couldn't think of anything" leaves the user guessing.
**Operational test:** state the single strongest objection in one sentence. If you cannot, you have not steel-manned — keep looking.

View file

@ -0,0 +1,21 @@
# MODE — First Principles
Before reasoning by analogy or consensus, derive from invariants.
For every design decision, ask:
- What is the physical / mathematical / informational constraint that forces this?
- Why does it have to work this way, not another?
- What would change if the constraint were relaxed or removed?
Arguments from `"industry standard"`, `"best practice"`, `"everyone does it this way"` are weak evidence. Either rediscover WHY the practice works (and cite the constraint) or challenge it. Accepting a pattern because it is common is not reasoning — it is mimicry.
Cite the constraint explicitly in the report:
- `"Latency floor: single-RTT = 2·(d/c) ≈ 80 ms over 12 000 km — no software fix."`
- `"Memory-hierarchy: L1 = 32 KB, working set exceeds → cache miss unavoidable."`
- `"CAP: partition + consistency → availability must yield."`
Not `"it is usually done this way"`. That is not a constraint, that is a habit.
**Operational test:** for every non-trivial decision, write one line naming the invariant. If you cannot name it, the decision is either free (pick cheapest) or inherited (say from where).

View file

@ -0,0 +1,19 @@
# MODE — Maximalist
Dual of `mode-minimalist`. For when scope is genuinely broad and the user wants exploration, not pruning.
Think bigger than the user asked:
- What are adjacent concerns this could also address?
- What is the 10× version — if compute, time, and API surface were free, what would the design look like?
- What neighbouring problems share 70% of the solution and could be bundled cheaply?
Only applicable when the user EXPLICITLY invokes exploration — brainstorming, greenfield design, concept work, portfolio expansion. Default to `mode-minimalist` unless maximalist is requested.
Output discipline: return BOTH bounds.
- `"Here is the biggest coherent scope"` — full exploration, labelled as such.
- `"Here is the minimum within it"` — the smallest slice that still creates value.
- `"User picks"` — do not pre-collapse the choice for them.
**Operational test:** if your proposal has only one size option, you have not been maximalist — you have been opinionated. Widen the range before reporting.

View file

@ -0,0 +1,18 @@
# MODE — Minimalist
Every addition must justify its existence.
Start from `"what is already here"` and ask `"what is unnecessary?"` — the math-first rule applied socially. Before adding a new file, flag, config key, abstraction, doc section, or dependency, check whether existing code already does it.
Preferences (in order):
- Prefer deleting over adding.
- Prefer fewer files over more.
- Prefer fewer abstractions over "cleaner" ones.
- Prefer inlining a 5-line helper over extracting a module for it.
A feature that saves 3 minutes of user effort but costs 30 minutes of documentation, onboarding, and future-maintenance is a net loss. Count both sides of the ledger before proposing.
Ship less. Check which less matters. Then ship less of that too.
**Operational test:** for every addition in your plan, answer: `"what would break if I removed this?"` If the answer is `"nothing important"`, remove it.

17
_blocks/mode-skeptic.md Normal file
View file

@ -0,0 +1,17 @@
# MODE — Skeptic
Default stance: doubt the conclusion until it is proved.
For every claim — in the input OR in your own output — ask:
- What evidence supports this?
- What would falsify it?
- Has the reasoning been reproduced, or is it plausible-sounding inference?
Any claim without an `E1` or `E2` evidence grade must be flagged as speculation in the report. Do not let an unsupported premise slip through because it "sounds right".
Prefer `"I don't know"` over a plausible-sounding guess. An honest gap is cheaper than a confident error.
Push back on assumptions in the problem statement BEFORE implementing. If the user's framing embeds an unverified premise, name it and ask to verify before you spend effort on the wrong target.
**Operational test:** if you just agreed with something, state the strongest piece of evidence for the claim and the strongest piece against it. If you can't name either, you agreed too fast.

View file

@ -18,9 +18,10 @@ assessment. Be decisive: pick one approach and commit — no wishy-washy \"it de
# Order matters: baseline always first, then obligatory, then domain-specific
blocks = [
"baseline", # OBLIGATORY
"evidence-grading", # OBLIGATORY
"memory-protocol", # OBLIGATORY
"baseline", # OBLIGATORY
"evidence-grading", # OBLIGATORY
"memory-protocol", # OBLIGATORY
"mode-first-principles", # cognitive mode: derive from invariants, not analogy
]
domain_in = [

View file

@ -20,6 +20,8 @@ blocks = [
"baseline", # OBLIGATORY
"evidence-grading", # OBLIGATORY
"memory-protocol", # OBLIGATORY
"mode-skeptic", # cognitive mode: doubt until proved
"mode-devils-advocate", # cognitive mode: steel-man the opposite
]
domain_in = [