Commit graph

5 commits

Author SHA1 Message Date
Parfii-bot
aa8333ccda feat(agent-substrate/phase-4): hook wiring — 3-line glue for kei-capability
PreToolUse hooks route through kei-capability check when orchestrator
registers a capability via KEI_CAPABILITY_NAME env var on agent spawn.

hooks/agent-capability-check.sh (22 LOC):
- Pass-through (exit 0) when KEI_CAPABILITY_NAME unset — no-op by default
- Fail-open (exit 0) when kei-capability binary missing — kit convention
- Sources _lib/gate.sh for KEI_DISABLED_HOOKS / KEI_HOOK_PROFILE respect
- exec kei-capability check "$CAP_NAME" when active

hooks/agent-capability-verify.sh (24 LOC):
- Orchestrator-driven, NOT a Claude Code native hook
- Carries env: AGENT_ID, TASK_TOML, WORKTREE_PATH, MAIN_REPO, RUN_MODE
- exec kei-capability verify "$CAP_NAME"

Registered in hooks/hooks.json + settings-snippet.json under both
PreToolUse:Bash and PreToolUse:Edit|Write matchers. Internal NotApplicable
returns exit 0 so non-matching tool calls cost nothing.

install.sh unchanged — hooks/*.sh glob picks up both new files.

tests/hook_wiring_integration.sh (64 LOC) — 3 contract assertions:
  (1) pass-through on unset KEI_CAPABILITY_NAME
  (2) deny+exit 2 on git-op pattern
  (3) allow+exit 0 on cargo-check pattern

Multi-capability routing (for phase 5): KEI_CAPABILITY_NAME currently
holds ONE name. When a role requires N capabilities, orchestrator will
either iterate or kei-capability gains a compose subcommand. Design
note left for phase 5.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 02:51:10 +08:00
Parfii-bot
59fd1a0362 test(substrate): integration now asserts real atom execution via Stream E
Previously expected NotImplemented stub (exit 64). Stream E wired real
subprocess exec to kei-task, so invoke now actually creates tasks.
Updated test:
- Builds kei-task in release + passes KEI_RUNTIME_BIN_DIR + KEI_TASK_DB
- Asserts exit 0 + stdout has 'id' field
- NEW assertion: invoke with empty KEI_RUNTIME_BIN_DIR → exit 127 (BinaryNotFound)
- Bad-input assertion stays (InputInvalid → exit 2)

4 end-to-end assertions now cover the full §Runtime contract.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 01:23:05 +08:00
Parfii-bot
f7e4725573 fix(substrate): amendment A-1 (input/output required all kinds) + integration test + jsonschema 0.18 relative-$id bug
Three post-E1/E2/E3-merge items:

1. Schema amendment A-1 (architect P0-a, non-breaking clarification):
   input.schema and output.schema are REQUIRED for all atom kinds. The
   shared kei-atom-discovery parses them as Option<PathBuf> only to allow
   tolerant skip-on-missing (stderr warn), not to permit absent schemas.
   Resolves Stream C / Stream D enforcement asymmetry documented in
   critic finding #6.

2. Cross-stream integration test (architect P0-b): tests/substrate_integration.sh
   builds release binaries, scaffolds a test atom corpus, runs
   schema-lint + list-atoms + atoms-discover + invoke; asserts all four
   streams agree on the same atom corpus and exit codes honour the
   locked §Runtime contract. Previously missing — only manual smoke
   checks existed.

3. Fix regression introduced by E1's jsonschema 0.18 upgrade:
   "relative URL without a base" on compile when schema declared a
   relative $id like "kei-task/atoms/schemas/create-input.json".
   validate.rs now synthesises an absolute file:// $id from the
   canonicalised schema path before compile. Internal $refs still
   resolve relative to the schema file; LocalFileResolver still confines
   to the schema's parent dir. Integration test catches this.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 00:56:27 +08:00
Parfii-bot
5993f32146 feat(v0.22): FS warn + battle-test matrix + USB docs platform split (Track C)
1. Filesystem type detection (architect P2 finding)
   _primitives/_rust/keisei/src/fs_type.rs (NEW, 103 LOC)
     - statfs(2)-based detection on unix (libc = '0.2' under
       [target.'cfg(unix)'.dependencies])
     - Recognizes exfat / msdos (FAT32) via f_fstypename on macOS,
       via f_type magic numbers on Linux (0x4d44, 0x2011bab0)
     - Windows stub returns Unknown (GetVolumeInformationW TBD)
     - warn_on_unsafe_fs(root) emits stderr warning on ExFat/Fat32
   brain.rs::load calls warn_on_unsafe_fs after canonicalize+symlink
     checks. Warning NOT fatal — user can opt into single-client use.

2. Battle-test matrix (architect P3 finding)
   tests/battle/Dockerfile.install-test-alpine (NEW)
     - alpine:3.19 + apk rust/cargo/pandoc
     - Exposes musl-vs-glibc issues in aws-sdk-s3, rusqlite, git2
   tests/battle/Dockerfile.install-test-debian (NEW)
     - debian:12 + rustup stable + pandoc
     - Default server distro, different apt structure from Ubuntu
   tests/battle/README.md rewritten — 3-distro matrix with run script

3. USB-BRAIN-GUIDE platform split
   docs/USB-BRAIN-GUIDE.md — restructured as TOC + platform-agnostic
     preamble + exFAT warning + cross-platform troubleshooting
   docs/USB-BRAIN-GUIDE-macos.md (NEW, 97 LOC) — Gatekeeper, diskutil,
     /Volumes, xattr -d com.apple.quarantine
   docs/USB-BRAIN-GUIDE-linux.md (NEW, 98 LOC) — /media/$USER,
     umount, ext4 recommended, systemd-udev auto-mount note
   docs/USB-BRAIN-GUIDE-windows.md (NEW, 115 LOC) — PowerShell
     Dismount-Volume, NTFS, FS-advisory Unknown caveat

REAL VERIFICATION (paste from agent):
  cargo check -p keisei: Finished (clean)
  cargo test -p keisei --release: 32 passed 0 failed (30 existing + 2 new)
  docker buildx outline: both new Dockerfiles parse

Constructor Pattern:
  fs_type.rs 103 LOC, brain.rs 198 LOC (at limit 200, held the line)
  All fns <30 LOC. Each USB guide sub-doc 97-115 LOC.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 20:56:42 +08:00
Parfii-bot
b1c5fd00d2 test(v0.21): Docker battle-test infra for install.sh on fresh ubuntu:24.04
tests/battle/Dockerfile.install-test — ubuntu:24.04 + deps
  (git, curl, ca-certificates, build-essential, jq, pandoc, rustup)
tests/battle/battle-entry.sh — ENTRYPOINT: runs install.sh with
  $PROFILE (default minimal), then verify.sh
tests/battle/verify.sh — POSIX sh gate: blocks >= 79, skills >= 39,
  top hooks >= 10, _lib hooks >= 2, test-gate.sh exits 0,
  settings.json valid JSON
tests/battle/README.md — build + run docs

SHIP-BLOCKER FOUND (for follow-up fix commit):
  kei-artifact crate fails to compile on fresh install because
  install/lib-primitives.sh::copy_rust_primitive copies only
  Cargo.toml + src/ + tests/. Crate has sibling schemas/ dir with
  5 JSON files that src/schemas.rs include_str!s at compile time.
  Missing → cargo build error, install exits 0 (soft-fail design)
  but full profile only produces 6/25 binaries instead of 25/25.

Real stdout verified:
  minimal: 80 blocks, 39 skills, 10 hooks, 3 _lib — exit 0 ✓
  dev:     same counts — exit 0 ✓ BUT 3/8 binaries (kei-artifact fail)
  full:    same counts — exit 0 ✓ BUT 6/25 binaries

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