Closing the intent-to-code chasm - specification-driven development with BDD verification chain
94
92%
Does it follow best practices?
Impact
95%
1.82xAverage score across 14 eval scenarios
Advisory
Suggest reviewing before use
IIKit's pre-commit hook enforces assertion integrity. By default it lives at .git/hooks/pre-commit; if you had an existing pre-commit hook at install time, IIKit installs to .git/hooks/iikit-pre-commit and your hook chain-calls it. To layer additional checks (formatters, linters, secret scanners) without disturbing that enforcement, use the .git/hooks/pre-commit.d/ extension point.
Linked worktrees / submodules:
/iikit-core initand/iikit-core uninitresolve the hooks dir viagit rev-parse --git-path hooks, so running them from a worktree installs to (and removes from) the gitdir'shooks/— the main repo's.git/hooks/for worktrees,.git/modules/<name>/hooks/for submodules. All worktrees of a given repo share the same hooks dir by design; install once from any of them.
IIKit's pre-commit hook executes every file in .git/hooks/pre-commit.d/ that:
chmod +x)README (no exec bit)Files run in deterministic byte-collation order (LC_ALL=C sort). Each runs with no arguments — use git diff --cached --name-only to discover staged files. Exit non-zero to block the commit.
Extensions run before IIKit's assertion-integrity check. IIKit is the final gate — if an extension mutates a .feature file, test-specs.md, or context.json (whether a formatter accidentally reflows assertions or a hostile extension tampers deliberately), IIKit verifies the post-extension staged state and blocks the commit. Extensions are skipped only when no git repo is detected. A failing extension blocks the commit and the IIKit check does not run.
Hook managers (lefthook, husky, pre-commit) install their own .git/hooks/pre-commit and either overwrite the IIKit hook or rename it to pre-commit.old. Either path violates the assertion-integrity rule — the IIKit enforcement must not be removed or silently disabled. Use pre-commit.d/ instead; a single executable script there can shell out to whatever tool you prefer.
Place these as executable files in .git/hooks/pre-commit.d/ (no extension required).
The examples use NUL-delimited pipelines (--name-only -z + xargs -0 -r) so paths containing spaces, tabs, or newlines are handled correctly. They use set -eu rather than set -euo pipefail and wrap grep in { ... || true; } so a successful no-op commit (no files match the regex) does not abort the script.
#!/usr/bin/env bash
# .git/hooks/pre-commit.d/prettier-write
set -eu
PATTERN='\.(ts|tsx|js|jsx|json|md|yml|yaml|html|css)$'
git diff --cached --name-only --diff-filter=ACMR -z \
| { grep -zE "$PATTERN" || true; } \
| xargs -0 -r bunx prettier --write
git diff --cached --name-only --diff-filter=ACMR -z \
| { grep -zE "$PATTERN" || true; } \
| xargs -0 -r git add#!/usr/bin/env bash
# .git/hooks/pre-commit.d/eslint-fix
set -eu
PATTERN='\.(ts|tsx|js|jsx)$'
git diff --cached --name-only --diff-filter=ACMR -z \
| { grep -zE "$PATTERN" || true; } \
| xargs -0 -r npx eslint --fix
git diff --cached --name-only --diff-filter=ACMR -z \
| { grep -zE "$PATTERN" || true; } \
| xargs -0 -r git add#!/usr/bin/env bash
# .git/hooks/pre-commit.d/secret-scan
exec gitleaks protect --staged --redact#!/usr/bin/env bash
# .git/hooks/pre-commit.d/spotless
set -eu
./mvnw -q spotless:apply
git diff --cached --name-only --diff-filter=ACMR -z \
| { grep -zE '\.java$' || true; } \
| xargs -0 -r git add.git/hooks/ is per-clone and not tracked. To share extensions:
scripts/git-hooks/..git/hooks/pre-commit.d/:find scripts/git-hooks -maxdepth 1 -type f -print0 \
| while IFS= read -r -d '' hook; do
ln -sf "../../../$hook" ".git/hooks/pre-commit.d/$(basename "$hook")"
doneRun this once per fresh clone (or as part of a project bootstrap script). -type f skips subdirectories; NUL-delimited iteration handles filenames with any valid characters.
ls -la .git/hooks/pre-commit.d/ for the exec bit. Files without chmod +x are skipped silently.git add the modified files; otherwise the commit captures the unfixed staged version..feature file and now the commit is blocked — IIKit verifies the post-extension staged state, so any extension-side mutation of .feature / test-specs.md / context.json re-triggers the hash check. Re-run /iikit-04-testify to regenerate hashes against the new content, or stop the extension from touching those paths.evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10
scenario-11
scenario-12
scenario-13
scenario-14
rules
skills
iikit-00-constitution
scripts
dashboard
iikit-01-specify
iikit-02-plan
iikit-03-checklist
scripts
bash
dashboard
iikit-04-testify
iikit-05-tasks
iikit-06-analyze
iikit-07-implement
iikit-08-taskstoissues
iikit-bugfix
scripts
dashboard
iikit-clarify
iikit-core
scripts
bash
dashboard
powershell
templates