KeiSeiKit-1.0/_assembler/tests/mode_blocks.rs
Parfii-bot d95a3ba48c feat(v0.16.1): dynamic schema SSoT + KNOWN_SCHEMAS drift-test + mode-matrix Phase 3.6
Three polish items from post-audit parallel agent.

1. Dynamic schema whitelist (drops hardcoded const drift)
   _assembler/src/schemas_export.rs (NEW, 136 LOC) — loader cube,
     priority path $AGENT_ROOT/artifacts/schemas.json →
     ~/.claude/agents/artifacts/schemas.json → BUILTIN fallback.
     Hand-rolled JSON parser (no serde_json dep).
   _assembler/src/validator.rs delegates to schemas_export::load,
     keeps KNOWN_ARTIFACT_SCHEMAS alias for back-compat.
   _primitives/_rust/kei-artifact/src/export.rs (NEW, 82 LOC) —
     write() + render() + default_path().
   _primitives/_rust/kei-artifact/src/cli_cmds.rs (NEW, 126 LOC) —
     extracted cmd_emit/get/list/chain so main stays <200 LOC.
   ExportSchemas + ListSchemas subcommands; cmd_register
     auto-refreshes export file (best-effort).

2. KNOWN_SCHEMAS SSoT — documented-dual-const + drift-test
   (Option "simpler than new crate"). SSoT in kei-artifact's
   BUILTIN; schemas_export::BUILTIN is a documented mirror;
   builtin_schemas_do_not_drift_from_kei_artifact test in
   validator.rs parses the primitive's source at test time and
   diffs. <30 LOC change. No workspace structural change —
   assembler stays decoupled from runtime primitive.

3. Agent-to-mode matrix + wizard Phase 3.6
   _blocks/mode-matrix.md (NEW, 24 LOC) — 11-row table mapping
     agent role × recommended mode blocks.
   skills/new-agent/SKILL.md — new Phase 3.6 (between name-confirm
     3.5 and manifest-write 4). AskUserQuestion with 5
     cognitive-mode options (skeptic/devils-advocate/minimalist/
     maximalist/first-principles, multiSelect). Appends picked
     labels to manifest's blocks array. Defaults to NONE.
   _blocks/README.md adds one-line reference to the matrix.
   _assembler/tests/mode_blocks.rs (NEW, 78 LOC) — 3 integration
     tests lock the wiring.

README.md — all accumulated count + pre-built-binaries + plugin
section edits from the v0.16 cycle consolidated here (will be
replaced by markers in v0.17 counts-autogen refactor).

Tests: assembler 24 → 33 (+9), kei-artifact 24 → 31 (+7), total
48 → 64. cargo check --workspace clean.

Constructor Pattern: largest new file validator.rs 180 LOC.

Pre-existing flagged for separate refactor: kei-artifact
validate.rs 268 LOC (not touched by this polish).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 15:10:46 +08:00

78 lines
2.4 KiB
Rust

//! Mode-picker integration test.
//!
//! The `skills/new-agent` wizard Phase 3.6 appends `mode-*` block names to
//! the `blocks` array. This test locks the contract that such a manifest
//! validates cleanly AND the expected mode files ship in `_blocks/` (either
//! in the fixture set or alongside the real kit).
//!
//! We use the real `_blocks/` so the test protects the kit's mode surface —
//! if anyone renames or deletes a mode block, the wizard's Phase 3.6
//! selection would silently break at runtime otherwise.
use std::path::PathBuf;
fn kit_root() -> PathBuf {
// `CARGO_MANIFEST_DIR` points at `_assembler/`; kit root is one up.
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.parent()
.unwrap()
.to_path_buf()
}
#[test]
fn all_five_mode_blocks_ship_in_kit() {
let blocks = kit_root().join("_blocks");
for mode in [
"mode-skeptic",
"mode-devils-advocate",
"mode-minimalist",
"mode-maximalist",
"mode-first-principles",
] {
let p = blocks.join(format!("{mode}.md"));
assert!(
p.exists(),
"mode block '{mode}' is missing from _blocks/ — Phase 3.6 of skills/new-agent would break"
);
}
}
#[test]
fn mode_matrix_doc_ships_in_kit() {
let p = kit_root().join("_blocks/mode-matrix.md");
assert!(
p.exists(),
"mode-matrix.md is missing from _blocks/ — SKILL.md Phase 3.6 references it"
);
let text = std::fs::read_to_string(&p).unwrap();
// The matrix must enumerate each mode by block basename.
for mode in [
"skeptic",
"devils-advocate",
"minimalist",
"maximalist",
"first-principles",
] {
assert!(
text.contains(mode),
"mode-matrix.md is missing row for '{mode}'"
);
}
}
#[test]
fn skill_md_phase_3_6_wiring_exists() {
// The wizard adds mode-* blocks only if Phase 3.6 is present.
let p = kit_root().join("skills/new-agent/SKILL.md");
assert!(p.exists(), "skills/new-agent/SKILL.md is missing");
let text = std::fs::read_to_string(&p).unwrap();
assert!(
text.contains("Phase 3.6"),
"SKILL.md is missing the Phase 3.6 mode picker"
);
assert!(
text.contains("mode-skeptic")
|| text.contains("skeptic — doubt-first"),
"SKILL.md Phase 3.6 does not reference the skeptic mode"
);
}