Glossary¶
The vocabulary used across these docs. Architecture terms mean what they usually mean in the DDD and Clean Architecture literature. Where Inwards uses a word more narrowly, the entry says so.
How the architecture terms fit together¶
flowchart TB
subgraph outer["Interface / adapters (outermost)"]
root["Composition root<br/><small>wires adapters into ports</small>"]
api["HTTP handlers, CLI, consumers"]
subgraph infra["Infrastructure"]
db["SQL repositories, HTTP clients"]
subgraph app["Application"]
uc["Use cases / commands"]
subgraph dom["Domain (innermost)"]
ent["Entities, value objects"]
port["Ports (Protocols)"]
end
end
end
end
api --> uc
uc --> ent
uc --> port
db -. "implements" .-> port
root --> api
root --> db
Arrows point in the direction of imports. Every solid arrow points inward, and that's the rule INW001 enforces. The dashed arrow is "implements": the infrastructure class satisfies a Protocol that the domain owns.
Architecture terms¶
- Adapter
- Code that connects a port to a real technology: a SQL repository, an HTTP client, a message consumer. Adapters live in outer layers.
- Bounded context
- A part of the system with its own model and language (DDD). In a Python codebase, usually a top-level package such as
billingorshipping. Contexts are declared in[[tool.inwards.contexts]]; INW002 lets one import another only when itsdepends-ondeclares it. - Clean Architecture
- Robert C. Martin's layering: entities at the centre, then use cases, then interface adapters, then frameworks. Its dependency rule is that source code dependencies point only inward.
- Composition root
- The one place, in the outermost layer, where concrete adapters are created and handed to the code that needs them. Inwards' fix steps send wiring here.
- Dependency rule
- Inner layers must not know about outer ones. INW001 is this rule, applied to imports.
- Domain layer
- Business rules and the vocabulary of the problem, free of frameworks and I/O. In Inwards configs it's usually listed first.
- Hexagonal architecture / Ports and adapters
- Alistair Cockburn's style: the application core talks to the world only through ports, and adapters plug into them. Inwards treats it as a layered config whose inner layer owns the ports.
- Layer
- In Inwards, a named set of module prefixes in
[tool.inwards].layers. The order of the list is the order from inside to outside. - Port
- An interface the inner code owns and the outer code implements. In Python, usually a
typing.Protocol. - Vertical slice
- Organising code by feature (
orders/,invoices/) rather than by technical layer, with each slice holding its own handlers and data access. Slices shouldn't reach into each other. Each slice can be declared as a context, and INW002 keeps slices apart unlessdepends-onsays otherwise; a layer can cover every slice with one selector, such asshop.*.domain.
Inwards terms¶
- Agent hook
- A command that an AI coding tool runs automatically around its own actions, for example Claude Code's
PostToolUseandStophooks. Inwards' main integration point.inwards init --agent claudeinstalls four of them. See chapter 4. - Baseline
- The violations a project already had when it adopted Inwards, recorded by
inwards baselineininwards-baseline.jsonnext topyproject.toml. They don't fail the check; new ones do (UC6). Entries match by rule, module and message, not by line. - Config guard
- The
PreToolUsehook that denies an agent's edits to[tool.inwards], to.inwards/, toinwards-baseline.jsonand to the Claude Code settings that hold the Inwards hooks, before they happen. See chapter 4. - Confirming parse
- The full tree-sitter parse the engine runs when the import skeleton reports a violation, so that only real imports are ever reported. See ADR-004.
- Diagnostic
- One reported violation: code, location, message, fix and docs link. Serialised as part of
inwards/diagnostics@1. - Differential test
src/core/scripts/prescan-diff.ts. It compares the imports found through the skeleton with those found by a full parse across a corpus, and fails if the skeleton misses any.- Engine
@inwards/core. Pure TypeScript that turns source text, config and grammars into diagnostics. It does no I/O (ADR-006).- Escalation
- What the hooks do once the same violation survives
escalate-afterattempts (default 3): the edit that reaches the limit doesn't block, the Stop gate lets the turn end after its last block, the agent is told to ask the user, and what is unresolved goes to the user and to the next session. It isn't sticky: the next edit with the violation blocks again. See chapter 4. - Evasion
- An agent changing code so that a check goes quiet without fixing the design, for example moving an import into a function. Chapter 4 lists the evasions Inwards handles.
- Extraction cache
.inwards/cache: whatinwards checkandinwards baselineread out of each file (its import skeleton, static imports and suppression comments), keyed by a hash of its content, module name and extraction rules. The hooks never read it; the language server keeps its own in memory.--no-cacheorINWARDS_NO_CACHE=1turns it off. See ADR-031.- Fingerprint
- A 16-hex-digit hash of a violation's rule code, module and message. The session state and the run log use it to recognise the same violation across edits, independent of its line number.
- Fix steps
- The ordered, concrete repair instructions attached to every diagnostic, built from the actual module and layer names.
- GrammarBinaries
- The port through which adapters hand the engine the tree-sitter runtime and Python grammar as bytes.
- Hallucinated module
- An import of a first-party module that doesn't exist, such as
shop.domain.pricingwhen there is nopricing. Agents produce these because the name looks plausible. INW010 catches them from the module index, before any test runs. - Hook daemon
inwards daemon(#60): a process per user and project that keeps the engine warm for the PostToolUse hook and answers it through a local socket (a named pipe on Windows). A hook starts it on demand and runs one-shot whenever it can't reach it; it exits after 10 idle minutes. The other hooks never use it, and the language server is a separate process. See ADR-039.- Import skeleton
- A copy of a file where every non-import line is blank and import lines are dedented. Line numbers are preserved, and it parses far faster than the whole file.
- Module index
- The engine's view of a project's first-party modules (
Engine.index), which every adapter passes to each check: the owner of an import, the list of modules, and the importers of any one module, each worked out on demand. INW006 uses the owner; INW010 uses the owner to tell whether a module exists, and a listing of the package it would live in to suggest the closest real ones. - Prescan refusal
- The prescan declining a file because
importappears somewhere it can't account for. The file then gets a full parse. 8.3 % of CPython's stdlib files are refused. - Rule code
INWor a family prefix such asFAPI(FastAPI rules), plus three digits. Codes are never reused, and a retired rule keeps its number.- Release PR
- The pull request release-please keeps open with the next version and its changelog. Merging it cuts the release (ADR-016).
- Run log
.inwards/runs.jsonl: with the log on, one line per hook run orinwards check;inwards check --logadds a line even when it is off. Each line has time, event, files, lines added and removed, violation fingerprints, exit code and duration. Local and off by default. It feeds the design-partner metrics. See chapter 8.- Session state
- What the Claude Code hooks record per session in
.inwards/state/: the start snapshot (HEAD, every[tool.inwards]table, a hash of every Python file) and one line per edit. Always on and local. The Stop gate and escalation read it. - Stop gate
- The check run from the agent's
Stophook. It checks every Python file the session changed, plus whether the config and the hooks are still intact, and keeps the agent from ending the turn while they aren't. - Suppression
- A comment on the line a finding points at,
# inwards: ignore[INW001] reason="why", that hides that finding. The reason is mandatory, every report counts suppressions, and by default the Claude Code hooks ignore one the agent added during the session. See ADR-028.
Tooling terms¶
- C4 model
- Simon Brown's four levels of architecture diagrams: context, containers, components, code. These docs use the first three.
- LSP
- Language Server Protocol. It's how the VS Code extension gets diagnostics from the Inwards language server.
inwards serverserves it over stdio from the binary, for any editor; the extension switches to it in #64. See ADR-041. - MCP
- Model Context Protocol. It lets an AI agent call external tools.
inwards mcpserves three of them over stdio:check_files,explain_ruleandwhere_should_this_go(guide). - SARIF
- Static Analysis Results Interchange Format 2.1.0, a JSON format for analysis results. GitHub code scanning ingests it.
- tree-sitter
- An incremental parser generator with grammars for many languages. Inwards uses its WASM build (
web-tree-sitter) withtree-sitter-python. - Zensical
- The static site generator that builds these docs, from the team behind Material for MkDocs.