Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
350 commits
Select commit Hold shift + click to select a range
e4cb1d8
Cherry-pick 7434a4f from autoresearch/hackathon
manuelschipper Mar 17, 2026
c128cef
Cherry-pick db21a50 from autoresearch/hackathon
manuelschipper Mar 17, 2026
492375c
Cherry-pick d009c2d from autoresearch/hackathon
manuelschipper Mar 17, 2026
71be8dd
Cherry-pick 651ccf1 from autoresearch/hackathon
manuelschipper Mar 17, 2026
d0afe32
Cherry-pick d092333 from autoresearch/hackathon
manuelschipper Mar 17, 2026
dfd7a3f
Cherry-pick 9f8aa67 from autoresearch/hackathon
manuelschipper Mar 17, 2026
31e97b7
Merge pull request #34 from manuelschipper/integrate/c2-redirect-writ…
manuelschipper Mar 17, 2026
bd39351
Release 0.5.0 — shell redirect write classification, substitution blo…
manuelschipper Mar 17, 2026
24edf7a
Docs: add active_allow examples to README and site
creatbot-ai Mar 17, 2026
51784f0
db_write default policy: ask → context (nah-10a)
manuelschipper Mar 17, 2026
e7c62fe
Merge pull request #35 from manuelschipper/docs/active-allow-examples
manuelschipper Mar 17, 2026
19d5886
Merge pull request #36 from manuelschipper/fix/nah-10a-db-write-conte…
manuelschipper Mar 17, 2026
3765287
molds: close nah-10a (db_write context default) and nah-5c1 (active_a…
manuelschipper Mar 17, 2026
8720cd4
Update molds section — add auto-sync watcher note
manuelschipper Mar 17, 2026
b633158
Fix /dev/null redirect false asks and hint proportionality
manuelschipper Mar 17, 2026
bab6b17
Merge pull request #37 from manuelschipper/fix/hint-correctness-battery
manuelschipper Mar 17, 2026
c4cf395
Update tagline and add CLA + contributing guidelines
creatbot-ai Mar 17, 2026
4fb7925
Remove stale branch protection note — main is no longer protected
manuelschipper Mar 17, 2026
22a7725
Script execution inspection — lang_exec context policy (FD-079)
manuelschipper Mar 17, 2026
7b70ee0
molds: Proofread fixes for FD-079
manuelschipper Mar 17, 2026
7c53779
Add azure, docker, terraform credential stores to sensitive paths
manuelschipper Mar 17, 2026
a1d1b1f
Strip more git global flags before classification
manuelschipper Mar 17, 2026
731f873
Strip git config-env and exec-path globals
manuelschipper Mar 17, 2026
57cb9bc
Strip git icase-pathspecs global flag
manuelschipper Mar 17, 2026
58a62ce
Strip git no-lazy-fetch global flag
manuelschipper Mar 17, 2026
090a7dd
Fail closed on malformed git config globals
manuelschipper Mar 17, 2026
726c946
Cover more git global flag stripping cases
manuelschipper Mar 17, 2026
2e3752d
Cover git long-form destructive flags and gh creds
manuelschipper Mar 17, 2026
f690aef
Cover git destructive parity variants
manuelschipper Mar 17, 2026
1bc854c
Tighten git push/add/tag flag classification
manuelschipper Mar 17, 2026
e66ab35
Reset config cache in test setup, not just teardown
manuelschipper Mar 17, 2026
e69b03c
Merge pull request #39 from manuelschipper/integrate/c6-c7-git-hardening
manuelschipper Mar 17, 2026
03b9260
feat: nah claude — per-session launcher (nah-ujc)
manuelschipper Mar 17, 2026
edacf05
molds: nah claude — per-session launcher (nah-ujc)
manuelschipper Mar 17, 2026
8281bb1
Inspect &> redirect content before allowing write
manuelschipper Mar 17, 2026
bf8bff9
Inspect heredoc redirect content before allowing write
manuelschipper Mar 17, 2026
07447f3
Cherry-pick 1a21284 from autoresearch/hackathon
manuelschipper Mar 17, 2026
00aacc0
Cherry-pick 3aa316a from autoresearch/hackathon
manuelschipper Mar 17, 2026
8054c43
Cherry-pick eddf8c0 from autoresearch/hackathon
manuelschipper Mar 17, 2026
a84cfaa
Cherry-pick 1ebbee8 from autoresearch/hackathon
manuelschipper Mar 17, 2026
737cdc3
Cherry-pick 0e0c407 from autoresearch/hackathon
manuelschipper Mar 17, 2026
ee370de
Cherry-pick e0d57f6 from autoresearch/hackathon
manuelschipper Mar 17, 2026
05d0ba1
Cherry-pick d196cc4 from autoresearch/hackathon
manuelschipper Mar 17, 2026
0630706
Cherry-pick 0515c62 from autoresearch/hackathon
manuelschipper Mar 17, 2026
44d558f
Cherry-pick 76e9719 from autoresearch/hackathon
manuelschipper Mar 17, 2026
1bd426d
Cherry-pick e348457 from autoresearch/hackathon
manuelschipper Mar 17, 2026
01a1141
Cherry-pick 7156de8 from autoresearch/hackathon
manuelschipper Mar 17, 2026
511ece4
Cherry-pick 301cb20 from autoresearch/hackathon
manuelschipper Mar 17, 2026
4911020
Cherry-pick 52724af from autoresearch/hackathon
manuelschipper Mar 17, 2026
0efcd63
Cherry-pick 6efa34a from autoresearch/hackathon
manuelschipper Mar 17, 2026
c589aba
Cherry-pick b6f55b6 from autoresearch/hackathon
manuelschipper Mar 17, 2026
eb77b84
Cherry-pick 171c6f2 from autoresearch/hackathon
manuelschipper Mar 17, 2026
ac66155
Cherry-pick 84dab0b from autoresearch/hackathon
manuelschipper Mar 17, 2026
84461df
Fix test expectations for C4+C5 passthrough unwrapping
manuelschipper Mar 17, 2026
6159adc
nah: add autoharden program + Docker/Podman read taxonomy
creatbot-ai Mar 17, 2026
fd78510
Merge pull request #40 from manuelschipper/integrate/c4-c5-content-wr…
manuelschipper Mar 17, 2026
0ab5359
FD-079 proofread fixes: LLM veto gate, value-taking flags, reason str…
manuelschipper Mar 17, 2026
adf02ae
FD-079 test suite — 97 tests for script execution inspection
manuelschipper Mar 17, 2026
2730624
FD-079 live LLM tests — 3 tests with real OpenRouter calls
manuelschipper Mar 17, 2026
22cb5ad
molds: Integrate autoresearch/hackathon branch into main
manuelschipper Mar 17, 2026
5df3152
nah: stabilize FD-025 config verification test
creatbot-ai Mar 17, 2026
e5ab4a4
autoharden: remove Telegram notification from program
creatbot-ai Mar 18, 2026
a1e1ea2
autoharden: add sync step — pull latest main + rebase stale PRs
creatbot-ai Mar 18, 2026
33a798d
Remove autoharden program from public repo — moved to private bots repo
creatbot-ai Mar 18, 2026
66dfb59
Merge pull request #41 from creatbot-ai/creatbot-cycle-1-stabilize-fd…
manuelschipper Mar 18, 2026
420470c
FD-079 evasion battery — 4 more live LLM tests
manuelschipper Mar 18, 2026
ce7c1bd
FD-103 Phase 1 — process substitution inspection
manuelschipper Mar 18, 2026
ac7dab1
molds: Review fix — unbalanced process substitution fail-closed
manuelschipper Mar 18, 2026
3e8a240
molds: Close nah-qk2 — Process Substitution Inspection (Phase 1)
manuelschipper Mar 18, 2026
3d95c0d
FD-080 LLM inspection for Write/Edit — veto gate + systemMessage warn…
manuelschipper Mar 18, 2026
633db86
nah-1o5: versioned interpreter normalization — python3.12, node22, ba…
manuelschipper Mar 18, 2026
f73a3b7
molds: review fix — normalize exec_sinks remove path
manuelschipper Mar 18, 2026
539150f
molds: Close nah-1o5 — Versioned Interpreter Normalization
manuelschipper Mar 18, 2026
683ae92
docs: fix lang_exec policy — context not ask
manuelschipper Mar 18, 2026
2be96ee
Release 0.5.1 — LLM Write/Edit inspection, passthrough wrappers, git …
manuelschipper Mar 18, 2026
d66d8c4
FD-103 Phase 2 — command substitution and backtick inspection
manuelschipper Mar 18, 2026
2f5b30b
molds: Review fix — stale "process substitution" error messages
manuelschipper Mar 18, 2026
d59dc30
molds: Close nah-5mb — Command Substitution Inspection Phase 2
manuelschipper Mar 18, 2026
b63f22c
nah-ge4 git_remote_write — prompt for remote GitHub operations
manuelschipper Mar 18, 2026
50cdd50
molds: git_remote_write — prompt for remote GitHub operations
manuelschipper Mar 18, 2026
9301733
nah-3f5 Supabase MCP tool guard — classify 25 tools by risk
manuelschipper Mar 18, 2026
c990721
molds: Supabase MCP Tool Guard
manuelschipper Mar 18, 2026
f0284c6
Release 0.5.2 — Supabase MCP guard, git_remote_write, command substit…
manuelschipper Mar 18, 2026
18b8bc8
Fix hook command paths breaking in bash on Windows
ZhangJiaLong90524 Mar 16, 2026
d90cdc9
Merge pull request #42 from ZhangJiaLong90524/fix/windows-hook-posix-…
manuelschipper Mar 19, 2026
1a28237
Update README.md
manuelschipper Mar 19, 2026
b24400c
Symlink regression tests — 8 cases confirming realpath resolution
manuelschipper Mar 24, 2026
463057d
docs: update tagline to match README
manuelschipper Mar 24, 2026
741a246
nah-06p: MultiEdit + NotebookEdit tool guard
manuelschipper Mar 24, 2026
55de6b7
Update molds section — add modesign, modebrief, remove mostatus/modemo
manuelschipper Mar 24, 2026
267c1e4
nah: block reads of /etc/shadow as sensitive path (#54)
creatbot-ai Mar 25, 2026
00e9bfb
molds: Close nah-06p — MultiEdit + NotebookEdit Tool Guard
manuelschipper Mar 24, 2026
dcf94fd
fix: cmd_update matcher format — one entry per tool, not nested dict
manuelschipper Mar 25, 2026
52065f0
fix: always log LLM metadata for write-like tools, even when LLM agrees
manuelschipper Mar 25, 2026
1fc9565
changelog: add nah update fix and LLM logging fix
manuelschipper Mar 25, 2026
92b32ad
nah-pfd LLM credential scrubbing + parser hardening (FD-068)
manuelschipper Mar 25, 2026
832e20e
molds: Review fix — move _redact_secrets before first call site
manuelschipper Mar 25, 2026
31f883b
molds: Close nah-pfd — LLM Credential Scrubbing + Parser Hardening
manuelschipper Mar 25, 2026
f834ffe
Allow read operations on ~/.claude/hooks/ without prompting
manuelschipper Mar 25, 2026
ce93748
Trust /tmp by default for profile: full + allow hook reads
manuelschipper Mar 25, 2026
66fefa9
changelog: /tmp trust + hook reads for v0.5.3
manuelschipper Mar 25, 2026
6d55684
v0.5.3 — security hardening, friction fixes, tool guards
manuelschipper Mar 25, 2026
f440c47
v0.5.4 — re-release with 12k context chars + /etc/shadow changelog
manuelschipper Mar 25, 2026
44e393e
v0.5.5 — fix __version__ mismatch (was 0.5.2, should match pyproject.…
manuelschipper Mar 26, 2026
921c337
docs: add release checklist to CLAUDE.md
manuelschipper Mar 26, 2026
7dae7ea
fix: LLM observability — stderr logging on all paths + uncertain prov…
manuelschipper Mar 26, 2026
5db4e8f
fix: log missing API keys + provider errors instead of silent None re…
manuelschipper Mar 26, 2026
1018d1b
fix: always log LLM field when LLM was attempted, even if all provide…
manuelschipper Mar 27, 2026
2e73543
fix: clean up LLM stderr logging — errors only, no success chatter
manuelschipper Mar 27, 2026
a45b179
nah-koi.1: inline code inspection — python3 -c, node -e content scanning
manuelschipper Mar 27, 2026
e83424c
fix: LLM veto gate fires on clean inline code, matching script file b…
manuelschipper Mar 27, 2026
8ce30ab
molds: Close nah-koi.1 — Inline Code Inspection
manuelschipper Mar 27, 2026
38b5749
molds: Upgrade CLAUDE.md to molds 1.0 skill names
manuelschipper Mar 28, 2026
c4e58ec
gitignore: add .beads-credential-key
creatbot-ai Mar 26, 2026
d826083
fix: track .beads/ config files — replace blanket gitignore with nega…
manuelschipper Mar 29, 2026
856d3a1
molds: nah-yt9 — LLM all-providers-failed returns None instead of esc…
creatbot-ai Mar 29, 2026
c242fb5
molds: Close nah-yt9 — LLM cascade failure should not override determ…
creatbot-ai Mar 29, 2026
0634cf0
fix: shell init file protection — guard ~/.bashrc, ~/.zshrc and 11 more
creatbot-ai Mar 29, 2026
151e6e8
fix: safety list hardening — credential dirs, exec sinks, decode comm…
creatbot-ai Mar 29, 2026
7dbc109
fix: shell comment parsing — shlex no longer chokes on # lines with a…
creatbot-ai Mar 30, 2026
9624679
molds: Close nah-2zt — Shell Comment Parsing
creatbot-ai Mar 30, 2026
e1cd049
chore: add sync-health.json to .beads/.gitignore
manuelschipper Mar 30, 2026
517e7b4
molds: Close nah-wdd + nah-brq — shell init protection, safety list h…
creatbot-ai Mar 30, 2026
1f838e1
nah-dhs: heredoc input classification — strip tokens, classify, bypass
manuelschipper Mar 30, 2026
70a459f
nah-dhs: add heredoc interpreter tests + changelog entry
manuelschipper Mar 30, 2026
8be1547
chore: add .worktrees/ to .gitignore
manuelschipper Mar 31, 2026
6932a4b
nah-dhs: heredoc input classification — strip tokens, classify, bypass
manuelschipper Mar 30, 2026
3935ecf
nah-dhs: add heredoc interpreter tests + changelog entry
manuelschipper Mar 30, 2026
f67237e
chore: add .worktrees/ to .gitignore
manuelschipper Mar 31, 2026
715a129
docs: adopt AGENTS.md as instruction source
manuelschipper Apr 2, 2026
54e2652
nah-5no: unified LLM mode — merge safety + intent into single call
manuelschipper Apr 2, 2026
be5db26
nah-5no: CLAUDE.md anti-injection framing + max_decision deprecation …
manuelschipper Apr 2, 2026
33adb55
nah-5no: review fixes — broken imports, dead code, veto prompt cleanup
manuelschipper Apr 2, 2026
0ae80f3
Merge mold/nah-5no-codex — unified LLM mode
manuelschipper Apr 2, 2026
6f20cb8
molds: Close nah-5no — Unified LLM mode
manuelschipper Apr 2, 2026
74561d5
nah-5no: disable deny_limit by default — opt-in via llm.deny_limit
manuelschipper Apr 3, 2026
10db056
nah-5no: surface LLM reasoning to user on uncertain decisions
manuelschipper Apr 3, 2026
347ec0f
nah-5no: show LLM reasoning in prompt, not after approval
manuelschipper Apr 3, 2026
dc531f0
nah-5no: emit compact systemMessage on uncertain — approval memory vi…
manuelschipper Apr 3, 2026
858ecfb
nah-5no: drop action_type from systemMessage — just LLM reasoning
manuelschipper Apr 3, 2026
335d9b5
nah-5no: cap LLM reasoning at source — prompt says max 50 chars
manuelschipper Apr 3, 2026
7341cf9
nah-5no: cap veto prompt reasoning to 50 chars too
manuelschipper Apr 3, 2026
4433f1f
nah-5no: show veto LLM reasoning in prompt too, not just after approval
manuelschipper Apr 3, 2026
c03a8d7
nah-5no: bump LLM reasoning cap from 50 to 80 chars
manuelschipper Apr 3, 2026
b32726e
nah-5no: copy _llm_reason into veto escalation dict
manuelschipper Apr 3, 2026
61a2f42
nah-5no: expand "default" keyword in llm.eligible list mode
manuelschipper Apr 3, 2026
bd10c63
molds: Close nah-nnj — superseded by llm.eligible default keyword exp…
manuelschipper Apr 3, 2026
061cf73
nah-5no: reweight unified prompt from safety to intent
manuelschipper Apr 3, 2026
f89549c
fix: SSH/SCP host extraction — rsync and ssh-copy-id edge cases
creatbot-ai Apr 6, 2026
481be0a
mold-2: comprehensive docker + systemctl taxonomy expansion
creatbot-ai Apr 7, 2026
bd82f90
Merge mold/mold-2 — comprehensive docker + systemctl taxonomy coverage
creatbot-ai Apr 7, 2026
27e74cd
infra: pytest pythonpath = src for worktree test isolation
creatbot-ai Apr 7, 2026
e103a0e
molds: mold-10 — classify playwright browser MCP tools
creatbot-ai Apr 7, 2026
d1790fb
mold-3: LLM transcript — surface skill invocations and meta blocks
creatbot-ai Apr 7, 2026
9554478
molds: mold-4 — add npm create package_run classification
creatbot-ai Apr 7, 2026
a5a1f99
mold-8: threat model coverage audit + CI test workflow
creatbot-ai Apr 8, 2026
99bcd92
mold-9: heredoc apostrophes inside $() no longer false-block as unbal…
creatbot-ai Apr 8, 2026
3e97ae6
test: pin cwd in test_output_process_sub_allow for CI determinism
creatbot-ai Apr 8, 2026
ec79450
molds: nah-vhy — harden wrapper exec and make classification
creatbot-ai Apr 8, 2026
a307e5d
molds: mold-27 — fix transcript tail giant-line reads
creatbot-ai Apr 9, 2026
2e58e0a
molds: mold-12 — unwrap sudo bash wrappers
creatbot-ai Apr 9, 2026
f6ed679
molds: mold-27 — merge
creatbot-ai Apr 9, 2026
0084cf3
molds: nah-vhy — merge
creatbot-ai Apr 9, 2026
c1aefbb
molds: mold-12 — fill sudo trust_project coverage
creatbot-ai Apr 9, 2026
54ee700
molds: mold-17 — allow benign env-only stages
creatbot-ai Apr 9, 2026
6bff10b
molds: mold-17 — merge
creatbot-ai Apr 9, 2026
7c90cf2
docs: update changelog for recent molds
creatbot-ai Apr 9, 2026
aff2489
docs: add mold-4 changelog entry
creatbot-ai Apr 10, 2026
d3f1e2b
Merge branch 'main' of github.com:manuelschipper/nah-dev
manuelschipper Apr 11, 2026
9f02125
remove beads taxonomy — bd CLI superseded by molds
creatbot-ai Apr 11, 2026
03eda12
molds: nah-856 — llm eligibility presets
creatbot-ai Apr 11, 2026
f0d2c73
molds: nah-856 — remove stale llm max_decision docs
creatbot-ai Apr 11, 2026
cd16603
molds: mold-12 — reject empty sudo option values
creatbot-ai Apr 11, 2026
f776b77
Merge branch 'mold/mold-12'
creatbot-ai Apr 11, 2026
bc0c8ea
Merge branch 'mold/nah-856'
creatbot-ai Apr 11, 2026
c6757cc
docs: update changelog for merged molds
creatbot-ai Apr 11, 2026
34d7a72
molds: mold-15 — classify Codex agent commands
creatbot-ai Apr 12, 2026
b39415a
molds: mold-15 — fix interactive Codex flags
creatbot-ai Apr 12, 2026
e68c19c
molds: mold-15 — fix prompt Codex interactive flags
creatbot-ai Apr 12, 2026
824d7d3
molds: mold-15 — refresh codex taxonomy docs
creatbot-ai Apr 12, 2026
435e511
molds: mold-15 — fix malformed Codex flags
creatbot-ai Apr 12, 2026
5fea14e
molds: mold-15 — fail closed malformed codex help
creatbot-ai Apr 12, 2026
865d774
molds: mold-15 — fix codex help globals
creatbot-ai Apr 12, 2026
414d6c7
molds: nah-858 — write LLM review refinement
creatbot-ai Apr 12, 2026
8a32331
Merge branch 'main' of github.com:manuelschipper/nah-dev
manuelschipper Apr 12, 2026
959a217
Merge branch 'vps-main-20260412'
manuelschipper Apr 12, 2026
06acf54
molds: nah-860 — classify shell source as lang_exec
creatbot-ai Apr 12, 2026
00f1c48
molds: nah-861 — classify subshell groups
creatbot-ai Apr 12, 2026
cd71b9d
molds: nah-862 — classify export assignments
creatbot-ai Apr 12, 2026
f2b3958
Merge branch 'mold/nah-858'
creatbot-ai Apr 12, 2026
4c8a1f4
Merge branch 'mold/nah-860'
creatbot-ai Apr 12, 2026
8943ad1
Merge branch 'mold/nah-861'
creatbot-ai Apr 12, 2026
45d2096
docs: update changelog for merged molds
creatbot-ai Apr 12, 2026
5ba53e9
molds: nah-859 — classify Codex companion script vars
creatbot-ai Apr 12, 2026
38fb607
Merge branch 'mold/nah-862'
creatbot-ai Apr 12, 2026
1906f67
Merge branch 'mold/nah-859'
creatbot-ai Apr 12, 2026
29494b7
docs: update changelog for codex companion vars
creatbot-ai Apr 12, 2026
26024fe
Merge remote-tracking branch 'origin/main'
manuelschipper Apr 12, 2026
30f0c37
llm: add long reasoning for observability
creatbot-ai Apr 12, 2026
bc08ad3
llm: harden long reasoning observability
creatbot-ai Apr 12, 2026
e15b3b4
test: make source hint tests cwd independent
creatbot-ai Apr 12, 2026
7e5bff1
molds: Public release docs readiness
creatbot-ai Apr 12, 2026
df0f9d7
v0.6.0 — public release
creatbot-ai Apr 13, 2026
5f18eca
molds: nah-865 — worktree project boundaries
creatbot-ai Apr 13, 2026
3698c74
molds: mold-6 — safe python module carve-out
creatbot-ai Apr 13, 2026
8a3f483
molds: mold-5 — transparent formatter suffixes
creatbot-ai Apr 13, 2026
bf4f1fd
molds: mold-5 — respect pipe suffix boundary
creatbot-ai Apr 13, 2026
4810eb3
molds: mold-6 — merge
creatbot-ai Apr 13, 2026
cc31952
molds: mold-5 — merge
creatbot-ai Apr 13, 2026
7a7392f
molds: close python module formatter work
creatbot-ai Apr 13, 2026
b66fea6
molds: nah-865 — merge
creatbot-ai Apr 13, 2026
5350bb8
molds: nah-868 — guard env and inline subprocess regressions
creatbot-ai Apr 13, 2026
644072e
molds: nah-867 — windows compatibility rewrite
creatbot-ai Apr 13, 2026
cbe4a2d
molds: nah-867 — scan windows shell payloads
creatbot-ai Apr 13, 2026
592bb7f
tests: verify demo battery default expectations
creatbot-ai Apr 13, 2026
2237aed
tests: load demo battery from package data
creatbot-ai Apr 13, 2026
f74df2f
nah: migrate molds workflow instructions
creatbot-ai Apr 13, 2026
1ee1b74
molds: nah-867 — integrate Windows compatibility
creatbot-ai Apr 13, 2026
b4fc153
docs: clarify default action policies
creatbot-ai Apr 13, 2026
18bf12a
molds: nah-869 — add Azure OpenAI provider
creatbot-ai Apr 13, 2026
067be37
molds: nah-869 — integrate Azure OpenAI provider
creatbot-ai Apr 14, 2026
302554d
molds: nah-jpv — add nah test defaults mode
creatbot-ai Apr 14, 2026
d91d9cb
v0.6.1 — Azure and Windows provider compatibility
creatbot-ai Apr 14, 2026
6b8a2f3
molds: nah-jpv — integrate nah test defaults mode
creatbot-ai Apr 14, 2026
e3c0364
molds: nah-870 — fix shell comment prefix bypass
creatbot-ai Apr 14, 2026
f5a1273
molds: nah-871 — harden find exec shell wrappers
creatbot-ai Apr 14, 2026
83c6327
nah: Refresh molds instructions
creatbot-ai Apr 14, 2026
07dcbd9
nah: Remove legacy beads state
creatbot-ai Apr 14, 2026
edd4010
nah: Stop tracking local molds state
creatbot-ai Apr 14, 2026
b679769
molds: nah-871 — cover find leading options
creatbot-ai Apr 14, 2026
639f628
molds: nah-871 — integrate find exec shell wrappers
creatbot-ai Apr 14, 2026
cc3bc83
v0.6.2 — find exec and comment bypass fixes
creatbot-ai Apr 14, 2026
c816987
molds: nah-874 — intra-chain var expansion closes sensitive-path bypass
creatbot-ai Apr 15, 2026
73039bb
molds: nah-875 — wildcard support in classify table
creatbot-ai Apr 16, 2026
ac68d61
molds: nah-875 — tests for wildcard classify support
creatbot-ai Apr 16, 2026
2308d44
molds: nah-875 — README: document classify wildcard support
creatbot-ai Apr 16, 2026
6aefeb6
molds: nah-875 — CHANGELOG entry for classify wildcards
creatbot-ai Apr 17, 2026
2190df7
molds: nah-876 — atomic _write_config via temp-file + os.replace
creatbot-ai Apr 17, 2026
7971ecb
molds: nah-876 — tests for atomic _write_config
creatbot-ai Apr 17, 2026
ed858d9
molds: nah-876 — CHANGELOG entry for atomic config writes
creatbot-ai Apr 17, 2026
2657e68
v0.6.3 — classify wildcards and atomic config writes
creatbot-ai Apr 17, 2026
dc9af11
Integrate Windows hook update fixes from PR 58
creatbot-ai Apr 18, 2026
201999e
molds: nah-877 — direct script args resolve script path
creatbot-ai Apr 18, 2026
7d9a4e9
molds: nah-877 — limit direct script path resolution
creatbot-ai Apr 18, 2026
cb3f3ca
molds: nah-32c — classify gh api flags
creatbot-ai Apr 18, 2026
b6d739b
molds: nah-878 — classify mise exec payloads
creatbot-ai Apr 18, 2026
05a0fcb
Classify safe kubectl reads conservatively
creatbot-ai Apr 18, 2026
e4f88f9
Clarify stdlib core install path
creatbot-ai Apr 18, 2026
f8b7909
v0.6.4 — conservative kubectl and wrapper fixes
creatbot-ai Apr 18, 2026
912be4d
Add Claude Code slash commands for in-session rule management
moyukhc Apr 18, 2026
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
283 changes: 283 additions & 0 deletions .claude/commands/nah-demo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,283 @@
# nah test-live — Security Demo

Demonstrate nah's protection by running curated test cases through the live classification pipeline. The user watches nah intercept tool calls in real-time.

## CRITICAL EXECUTION RULES

**Execute ONE case at a time. This is non-negotiable.**

For each case:
1. Print the story context and narration (the threat being demonstrated)
2. Execute the case (live tool call or dry-run classification)
3. Print the result with match indicator and technical explanation
4. Print a `---` separator before the next case

**NEVER batch cases into shell scripts or for-loops.** Each case gets its own individual tool call with narration. If you find yourself writing a loop or a script that runs multiple cases, STOP — you are violating the execution rules. The narration between cases IS the demo.

**NEVER include comments in Bash tool calls.** No `# description` lines before commands. Comments become the first token and change nah's classification. Put all narration in your text output, not in the command string.

## Phase 0: Introduction & Mode Selection

### Introduce the demo

Print this introduction (adapt the tone, don't copy verbatim):

> nah is a safety guard that intercepts every tool call Claude makes — Bash commands, file reads, writes, edits, searches — and classifies them in milliseconds with zero tokens. It blocks dangerous patterns (like remote code execution), asks for confirmation on risky operations (like force-pushing), and stays invisible for safe everyday work.
>
> This demo runs curated test cases through the live pipeline. For safe cases and blocked cases, you'll see nah's real interception in your terminal. For dangerous commands that shouldn't actually execute, we use dry-run classification.

### Permission setup check

Before proceeding, remind the user about the recommended permission setup (adapt the tone, don't copy verbatim):

> **Quick setup note:** Don't use `--dangerously-skip-permissions` — in bypass mode, hooks fire asynchronously, so commands can execute before nah blocks them.
>
> Make sure `Bash`, `Read`, `Glob`, and `Grep` are in `permissions.allow` in your `~/.claude/settings.json` — nah is guarding them. For **Write** and **Edit**, your call — nah inspects their content either way.
>
> This way, nah's live blocks and asks will show up properly during the demo.

### Config check

Run `nah config show` via Bash and inspect the output. If the user has any custom configuration (action overrides, classify entries, custom sensitive paths, content pattern changes, etc.), warn them:

> **Heads up:** You have a custom nah config. The expected results in this demo assume default settings (full profile, no overrides). Your custom config may change some decisions — I'll note any mismatches as we go, but they might be intentional on your part rather than bugs.

If the config is default/empty, say so briefly and move on.

### Understanding config vs defaults

This is important context for interpreting results during the demo:

- The **test battery expected values assume default config** (full profile, no overrides).
- **Live tool calls use the active config** because they exercise the real hook path. If a user's config changes a policy (e.g., adds `~/.ssh` to allowed paths, or relaxes `network_outbound` to allow), live results may differ from the battery's expected value. **This is the config working correctly, not a bug in the test battery.**
- **Dry-run base cases use `nah test --defaults`** so they ignore global/project config and compare against packaged defaults.
- **Config variants use `nah test --config`** because they intentionally test a temporary override. Do not combine `--defaults` and `--config`.
- Only flag a base-case mismatch as a real issue if it still mismatches under `nah test --defaults`, or if a live-case mismatch cannot be explained by active config.

### Select mode

Check `$ARGUMENTS`:

- If argument is **`full`**: use full mode (90 base + 21 config variants)
- If argument is **`story:NAME`**: use story mode for that story
- If **no argument**: ask the user which mode they want:

> **Which mode would you like?**
> - **Demo** (recommended) — 25 curated cases across 8 security stories. Takes ~5 minutes. Covers all the highlights.
> - **Full** — All 90 base cases + 21 config variants + log verification. Comprehensive regression suite.
> - **Single story** — Deep-dive into one threat category. Stories: `safe_operations`, `remote_code_execution`, `data_exfiltration`, `obfuscated_execution`, `path_boundary_protection`, `destructive_operations`, `credential_secret_detection`, `network_context`.

Wait for the user's answer before proceeding.

### Select pacing

After the user picks a mode, ask:

> **Pacing?**
> - **Pause between cases** — I'll stop after each case so you can inspect the result. Say "next" or "continue" to advance.
> - **Run straight through** — I'll run all cases back-to-back without stopping.

Wait for the user's answer. If they choose to pause, after printing each case's result, wait for the user to respond before continuing to the next case.

---

## Phase 1: Setup

1. Read `src/nah/data/test_battery.json`
2. Filter cases based on selected mode:
- **demo**: base cases with `quick: true` (25 cases)
- **full**: all base cases (90) + all variants (21)
- **story:NAME**: base cases where `story` field matches NAME
3. Print header:

```
## nah test-live — N cases (demo|full|story:NAME)
```

---

## Phase 2: Story-Based Execution

Group selected base cases by their `story` field. Process stories in this order:

| Story key | Header |
|-----------|--------|
| `safe_operations` | Safe Operations — nah stays out of your way |
| `remote_code_execution` | Remote Code Execution — download-and-execute pipelines |
| `data_exfiltration` | Data Exfiltration — stealing sensitive data |
| `obfuscated_execution` | Obfuscated Execution — hiding malicious intent |
| `path_boundary_protection` | Path & Boundary Protection — sensitive files and directories |
| `destructive_operations` | Destructive Operations — irreversible changes |
| `credential_secret_detection` | Credential & Secret Detection — scanning for secrets |
| `network_context` | Network Context — who are you talking to? |

For each story group, print a story header:

```
## [Story Header]
```

Then for each case in the story, print:

```
### [N/total] `input_summary`

**Threat:** [narration field from JSON]
```

Execute the case (see Execution Mechanics below), then print:

```
**Result:** decision ✓
**Why:** [description field from JSON]

---
```

If mismatch: `**Result:** actual ✗ (expected: expected)`

---

## Execution Mechanics

### Live cases (`mode: "live"`)

Actually invoke the real tool. The user sees nah's real decision in their terminal.

**Bash**: Use the Bash tool with `input.command`.
**Read**: Use the Read tool with `input.file_path`.
**Write**: Use the Write tool with `input.file_path` and `input.content`. nah intercepts at the tool-call level, so blocked writes never need a prior Read.
**Glob**: Use the Glob tool with `input.pattern` and `input.path` (if present).
**Grep**: Use the Grep tool with `input.pattern` and `input.path` (if present).

Detection:
- Tool denied with reason starting with `nah.` → record as **block**
- Tool denied with reason starting with `nah?` → record as **ask**
- Tool executed normally → record as **allow**

### Dry-run cases (`mode: "dry_run"`)

Never execute the real tool. Use `nah test --defaults` via the Bash tool for base/story dry-run cases. Parse the `Decision:` line from output. Map: `ALLOW` → allow, `ASK` → ask, `BLOCK` → block.

**Bash**:
```bash
nah test --defaults "the command here"
```

**Write** (with content inspection):
```bash
nah test --defaults --tool Write --path ./config.py --content "AWS_SECRET_ACCESS_KEY=AKIA1234567890ABCDEF"
```

**Edit** (with content inspection):
```bash
nah test --defaults --tool Edit --path ./app.py --content "api_secret = \"hunter2hunter2\""
```

**Read/Glob** (path-only):
```bash
nah test --defaults --tool Read ~/.ssh/id_rsa
nah test --defaults --tool Glob ~/.ssh
```

**Grep** (with search pattern for credential detection):
```bash
nah test --defaults --tool Grep --path /tmp --pattern "password\s*="
```

**MCP tools**:
```bash
nah test --defaults --tool mcp__example__tool
```

---

## Phase 3: Summary

After all cases, print a summary.

**Demo mode:**
```
## Demo Complete

| Story | Cases | Passed |
|-------|-------|--------|
| Safe Operations | N/N | ✓ |
| Remote Code Execution | N/N | ✓ |
| ... | | |

**Passed:** N/N | **Allow:** N | **Ask:** N | **Block:** N
```

If any mismatches, list them with case ID, expected, and actual.

**Full mode:** Same summary, plus note the report file path.

---

## Full Mode: Additional Phases

These phases run only in `full` mode, after the base battery.

### Config Variants

Run each variant using `nah test --config` with the variant's `config` object as inline JSON. This applies a temporary config override for that single invocation — no file writes, no backup/restore needed. Do not add `--defaults`; config variants are intentionally override-based.

For each variant, announce it:
```
### [V#] Config variant (feature): `input_summary`
Config: config_description
Expected: expected (default: default_expected)
```

Then execute using `nah test --config '<JSON>' ...` — convert the variant's `config` object to a JSON string and pass it via the `--config` flag. Construct the rest of the command from the variant's `tool` and `input` fields.

Examples:
```bash
# Bash variant with classify override
nah test --config '{"classify": {"git_safe": ["git push --force"]}}' "git push --force"

# Bash variant with profile: none
nah test --config '{"profile": "none"}' "git status"

# Write variant with content pattern suppression
nah test --tool Write --path ./config.py --content "secret=abc" --config '{"content_patterns": {"suppress": ["private key"]}}'
```

### Log Cross-Check

1. Run `nah log -n 50 --json` via Bash
2. For each base case that resulted in block or ask, check for a matching log entry
3. Report: `Log verified: ✓` or list missing entries

### Report File

Create `command_test_runs/` directory if it doesn't exist, then write a markdown report to `command_test_runs/YYYY-MM-DD_HHMMSS.md`:

```markdown
# nah test report

**Date:** YYYY-MM-DD HH:MM:SS
**Mode:** full
**Cases:** N total (X base + Y variants)

## Results

| # | Story | Tool | Input | Expected | Actual | Mode | Match |
|---|-------|------|-------|----------|--------|------|-------|

## Config Variants

| V# | Feature | Config | Input | Expected | Actual | Match |
|----|---------|--------|-------|----------|--------|-------|

## Summary

- **Passed:** N/N (X%)
- **Live/Dry-run:** N/N
- **Log verification:** ✓ or N missing

## Mismatches

(only if any — include case ID, tool, input, expected vs actual, full output)
```
11 changes: 11 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## Summary

<!-- Brief description of what this PR does -->

## Test plan

<!-- How was this tested? -->

---

By submitting this pull request, I confirm that I have read and agree to the [Contributor License Agreement](../CLA.md).
40 changes: 40 additions & 0 deletions .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Deploy docs to schipper.ai

on:
push:
branches: [main]
paths:
- 'site/**'
- 'mkdocs.yml'

workflow_dispatch:

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- uses: actions/setup-python@v6
with:
python-version: '3.12'

- name: Install mkdocs
run: pip install mkdocs-material

- name: Build docs
run: python -m mkdocs build

- name: Push to schipper.ai
run: |
git clone --depth 1 https://x-access-token:${{ secrets.SCHIPPER_AI_DEPLOY }}@github.com/manuelschipper/schipper.ai.git /tmp/schipper.ai
rm -rf /tmp/schipper.ai/static/nah
mkdir -p /tmp/schipper.ai/static
cp -r _build /tmp/schipper.ai/static/nah
cd /tmp/schipper.ai
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add static/nah
git diff --cached --quiet && echo "No changes" && exit 0
git commit -m "Update nah docs from nah@${GITHUB_SHA::7}"
git push
48 changes: 48 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Publish to PyPI

on:
push:
tags: ['v*']

workflow_dispatch:

permissions:
contents: write
id-token: write

jobs:
publish:
runs-on: ubuntu-latest
environment: pypi
steps:
- uses: actions/checkout@v6

- uses: actions/setup-python@v6
with:
python-version: '3.12'

- name: Install build tools
run: pip install build

- name: Build package
run: python -m build

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1

- name: Extract changelog for release
id: changelog
run: |
VERSION="${GITHUB_REF_NAME#v}"
# Extract the section between ## [VERSION] and the next ## [
NOTES=$(awk "/^## \\[${VERSION}\\]/{found=1; next} /^## \\[/{if(found) exit} found{print}" CHANGELOG.md)
# Write to file to preserve newlines
echo "$NOTES" > /tmp/release_notes.md

- name: Create GitHub Release
run: |
gh release create "$GITHUB_REF_NAME" \
--title "$GITHUB_REF_NAME" \
--notes-file /tmp/release_notes.md
env:
GH_TOKEN: ${{ github.token }}
Loading