nah
AGENTS.md486 starsChanged 29 days agoMITView on GitHub
- For pipeline, feature ownership, or verification, start with docs/architecture.md. - The effect engine is the crates/effinterp-* packages, an unconditional dependency. crates/nah-effinterp/ is Nah's bridge to it. nah test (crates/nah-cli/src/commands/test.rs) is the one dry-run command and renders the engine plan through commands/engineplanrendering.rs. - Source bytes for the engine are served by crates/nah-effinterp/src/sourceobservation.rs, which owns admission and the observation manifest; the filesystem reads themselves belong to crates/nah-observe/src/sourcefiles.rs. Keep filesystem effects out of crates/nah-effinterp/. - Effinterp annotations are produced in crates/nah-effinterp/src/annotate.rs; crates/nah-proto/src/effectannotation.rs…
We split this AGENTS.md into the rules it gives an agent
8 rules. About 0 are common, 7 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈7
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 133
Prefer the fewest controls that preserve useful choices.
- Distinctive: line 138
Before adding or widening a guard, explain:
- Distinctive: line 145
Keep the full guard inventory in the README accurate.
- Distinctive: line 156
Keep documentation changes proportional.
- Distinctive: line 158
Do not expand surrounding copy or refresh demos and recordings unless requested.
- Distinctive: line 163
Add an entry only when an existing user might change how they use or upgrade Nah, or a prospective user would care that the capability …
- Very specific: line 166
Keep one concise Unreleased bullet per user outcome, with a bold label and plain technical summary.
- Distinctive: line 170
Keep newest releases first and never rewrite shipped entries.
≈ “Common” is an estimate: at least 1 in 5 of the 36,368 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Agent instructions
Contributor search conventions
- For pipeline, feature ownership, or verification, start with docs/architecture.md.
- The effect engine is the
crates/effinterp-*packages, an unconditional dependency.crates/nah-effinterp/is Nah's bridge to it.nah test(crates/nah-cli/src/commands/test.rs) is the one dry-run command and renders the engine plan throughcommands/engine_plan_rendering.rs. - Source bytes for the engine are served by
crates/nah-effinterp/src/source_observation.rs, which owns admission and the observation manifest; the filesystem reads themselves belong tocrates/nah-observe/src/source_files.rs. Keep filesystem effects out ofcrates/nah-effinterp/. - Effinterp annotations are produced in
crates/nah-effinterp/src/annotate.rs;crates/nah-proto/src/effect_annotation.rsowns their types, and no later stage re-validates them. The pure path classifiers the bridge uses live incrates/nah-proto/src/labels/; extend them there rather than copying them into the bridge. What an effect's selection takes is answered once, incrates/nah-effinterp/src/observation_request.rs: link following (reads_through_links,opens_through_links,writes_through_links), a producer's narrowing (selection_narrowing,subtree_reached_whole), and the read or delete a move states (stated_by_move). Call these instead of re-reading effect attributes;reads_through_linkshas a twin over occurrences incrates/effinterp-matcher/src/evaluate.rsthat must stay identical. - Nah crates name the engine's plan contract
nah_proto::effinterp_proto; do not alias it. Each runtime adapter is entered as<runtime>_adapter::runincrates/nah-cli/src/, and its hook installation exposesmutate_<runtime>_hook,<runtime>_hook_status, and<runtime>_self_protection_pathsincommands/<runtime>_installation.rs. Installers take their hook lock throughacquire_hook_lockincommands/hook_paths.rs, and adapters read tool input through thetool_input_*readers inadapter_fields.rs; a private copy exists only where its behavior differs. - Production decides every call with the engine alone:
crates/nah-cli/src/pipeline.rscomposes the engine plan, the bridge's evidence and observations, andnah-policy. Two separate gates hold it. Nah decision qualification runscorpus/*.jsonlfixtures throughcrates/nah-corpus, with reviewed exceptions incorpus/TRIAGE.md(Expected-fail). Frozen engine effect and flow parity runs ineffinterp-benchagainstbench/nah/goldens/effects.json,bench/nah/ceilings.json, andbench/scoreboard.json. The bench scores the engine's plan, not the decision the bridge reaches from it, so it never substitutes for the corpus gate. effinterp-benchhas two verbs over a run record inbench/runs/<id>/:measurerecords it and prints its verdict, andpublishmakes it the baseline;publish --dry-runcomputes the verdict alone. Searchpublish, not accept, promote or check:crates/effinterp-bench/src/run/publish.rsowns verdicts and publication;run/measure.rs(measure_run) owns measurement. A plane is one measured group (correctness, coverage, repositories, performance), selected with--group; thebench/invocationrows are the invocation corpus, not a plane.- The coverage headline, "understood what it could", counts successfully
analysed plans outside the
gapbucket, so a boundary reason's tier incrates/effinterp-bench/src/invocation/tiers.rssets that number. Move a reason out ofgaponly when every site that emits it qualifies: no static analyser given the fixture's inputs, including the files and context the fixture supplies, could resolve it. A reason with any resolvable site stays ingapuntil that site emits a different reason. State the per-site evidence in the commit and review; a better number alone is never the reason. - Engine frontends recover a
SemanticValue(crates/effinterp-engine/src/value.rs), which lowers to a protocolResourceExprwhere it reaches an effect.substitute_valuebinds call arguments into semantic values;substitute_resource_expr(summary.rs) binds them into resource expressions; build an unresolved one withvalue::unresolved_resource(family), a concrete path withfs_path_resourceand an endpoint withurl_endpoint_resource, never a per-file helper. Frontend types carry their language (<Lang>ControlFlowBuilder,<Lang>Walker), while the entry points keep the shared namesanalyzeandsummarize_ast. Model document types belong tocrates/effinterp-model-schema; import them fromeffinterp_model_schema, not througheffinterp_engine, which compiles them insrc/models/registry/. - The git command model is
crates/effinterp-engine/src/models/git.rs: global options, alias expansion, theSubCtxeffect emitters and thedispatchtable. A subcommand's effects live in themodels/git/git_<question>.rsmodule itsdispatcharm calls, in a function named for the subcommand (gc,reflog,history_rewrite); a few short arms (commit,init,clone, andmerge/cherry-pick/revert/am/apply) stay inline, and theconfigarm callsgit/git_config_command.rs. effinterp-repocomposition and linking must not dispatch on source language;tests/suite/effect_ir_linker.rschecks an explicit list ofcompose/*.rsandlinker/*.rsfiles, so add a new file there.
Edit this guidance in .mdmanager/sections/agents.md, then run
mdmanager project apply agents. .mdmanager/project.toml owns the
composition; AGENTS.md is generated and CLAUDE.md links to it.
Build and test layout
Integration tests are one binary per crate: crates/<crate>/tests/suite/main.rs
declares each sibling file as a module. Add new integration tests there, not
as top-level tests/*.rs files, and run one module with
cargo test -p <crate> --test suite <module>::. The layout gate
tools/gates/tests/suite/test_layout.rs fails on any other test binary.
Build output stays under one profile. Never set CARGO_PROFILE_* or
CARGO_INCREMENTAL environment variables and do not pass --release: every
distinct profile value makes Cargo link a second full copy of every test
binary under target/, and each sddr worktree carries its own target/.
Built-in guard design
Build guards around a concrete loss or exposure that Nah can establish from modeled evidence. State what the guard catches, which legitimate workflows it interrupts, and what context Nah cannot determine.
Factory defaults
Ship on when a human handoff is justified by proven broad loss of working state, destruction of recovery paths, raw credential exposure, or bypassing checks that prevent substantial loss.
Ship off when the same operation is routine legitimate work and its danger depends on context Nah cannot establish. Whole-stack teardown, for example, may be ordinary cleanup of a disposable environment.
Judge the interruption when the guard matches. Users who never invoke the affected operation are not a reason to ship it off. Conversely, severity alone does not justify default-on: examine realistic legitimate uses and recovery.
Granularity
One guard should represent a protection a user can meaningfully choose.
Extend an existing guard when the new behavior protects against the same kind of loss. Split only when a concrete workflow needs independent controls or different defaults. Separate commands, providers, or internal effect codes do not by themselves justify separate guards.
Prefer the fewest controls that preserve useful choices. Keep applicable protections independent: matching one guard must not suppress another.
Review
Before adding or widening a guard, explain:
- The consequential mistake it prevents.
- A realistic legitimate workflow it could interrupt.
- Why its scope and factory default fit those cases.
- Why an existing guard can or cannot own the behavior.
Keep the full guard inventory in the README accurate. Keep contributor reasoning here; command behavior and options belong in help and product docs.
A guard's prose and examples live only in its record,
crates/nah-cli/guards/<guard>.toml, which generates the TUI text,
nah docs guards, and docs/guard-reference.md. Each example names a corpus
row; crates/nah-corpus/tests/suite/guard_knowledge.rs holds the rules that row
must meet.
Documentation scope
Keep documentation changes proportional. Edit the README or homepage only when a change makes them inaccurate, and then make the smallest factual correction. Do not expand surrounding copy or refresh demos and recordings unless requested.
Keep the changelog curated
CHANGELOG.md is the public news feed on nahguard.ai, not a development log.
Add an entry only when an existing user might change how they use or upgrade
Nah, or a prospective user would care that the capability exists.
- Keep one concise
Unreleasedbullet per user outcome, with a bold label and plain technical summary. Fold related follow-up work into that bullet. - Omit docs and copy edits, site polish, internal work, tests, and minor edge case or message fixes.
- Keep newest releases first and never rewrite shipped entries.
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 28,693 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository2 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- homepage/llms.txtllms.txt
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

