# Your First Intent-Logged Commit *Why stating what you meant to do — before the commit hook inspects what you actually did — changes how bugs get caught.* Every Aura commit carries two pieces of information: the code change itself, and your stated *intent* for the change. The intent is a short natural-language description of what you were trying to accomplish. Aura compares it against the AST-level diff at commit time and flags any mismatch. This single mechanism is the most effective thing in the system for catching a specific, expensive failure mode: **intent poisoning**. Intent poisoning is when a commit *claims* to do one thing and silently does another. It happens in human commits ("fix typo" that removes a validation check), and it happens much more frequently in AI-generated commits, where an over-eager model rewrites a helper it was told to leave alone. Aura cannot stop a determined attacker, but it can stop almost every accidental case, and it creates an audit trail for the rest. This page explains what makes a good intent message, shows examples of good and bad intents against the same diff, and walks through the commit flow end-to-end. ## The minimum viable flow From inside an Aura-initialized repository: ```bash # Edit some files vim src/auth.rs # Stage the change as usual git add src/auth.rs # Log what you meant to do aura log-intent "Switched password hashing from bcrypt to argon2id" # Commit normally — the hook validates intent vs. diff git commit -m "Switch to argon2id for password hashing" ``` If your intent and diff agree, the commit succeeds. If they diverge, the hook prints a semantic diff report and exits non-zero: ``` aura pre-commit: intent/diff mismatch Stated intent: "Switched password hashing from bcrypt to argon2id" Actual semantic changes: Modified auth::hash_password Modified auth::verify_password Deleted auth::legacy_md5_fallback <-- not mentioned in intent Added auth::Argon2Config Fix one of: 1. Update your intent to include the deletion. 2. Unstage the unrelated changes. 3. Override with `aura log-intent --amend`. ``` You then either update the intent with `aura log-intent --amend "..."` or re-stage the files to match what you actually meant to commit. The hook re-runs on the next `git commit`. ## Why intent matters Consider this scenario, which happens often enough that the Aura core team has a name for it: **scope creep by accident.** You asked Claude Code to rename `getUserById` to `fetchUserById` across the codebase. The agent did that, correctly, *and* also inlined a helper function it thought was redundant, *and* removed a deprecation warning because it looked like dead code. Two of those three changes were not in the plan. Your tests pass because the inlined helper was equivalent and the deprecation warning had no runtime effect. You review the diff, see a lot of `fetchUserById` appearing, skim past the other two changes, and merge. Three weeks later, a customer's integration breaks because the deprecation warning was how they learned about the impending API change. The agent did not do anything *wrong* — it made reasonable choices — but it did more than it was asked. Without a stated intent, there is no mechanical way to catch "more than it was asked." Aura's hook catches it because the intent said "Rename getUserById to fetchUserById" and the diff contained a deletion of a function unrelated to that rename. The same mechanism catches accidental human over-commits: staging a dotfile edit by mistake, leaving a debug `println!` in a refactor, or committing two unrelated features in one go. ## Writing a good intent A good intent is **specific about the semantic change**, not about the mechanics. It should answer: *what logic did I intend to add, modify, or remove, and why?* **Good intents** share a few properties: - They name the functions, classes, or modules touched. - They describe the *why*, not just the *what*. - They are scoped to the diff — if the diff touches ten things, the intent covers all ten or the diff should be split. - They are short. One sentence, occasionally two. **Bad intents** tend to be: - Generic ("fix bug", "refactor", "cleanup"). - Lying by omission — mentioning one change, ignoring another in the same commit. - Scoped to implementation detail ("changed line 42") rather than semantics. - Copied from the commit message when the commit message itself is useless. ### Examples Given a diff that modifies `parse_config` to return `Result` instead of panicking, and adds a new `ConfigError` enum: **Good:** `Made parse_config return Result instead of panicking on malformed input; added ConfigError enum with variants for each failure mode.` **Also good:** `Switched parse_config to fallible error handling to support the new --validate-only CLI flag.` **Bad:** `error handling` — too vague. The hook accepts it; your future self will curse you. **Bad:** `Added ConfigError enum.` — omits the signature change to `parse_config`. Hook will flag the mismatch. **Wrong:** `Added retry logic to network fetch.` — describes a different change entirely. This is the intent-poisoning failure mode; the hook catches it. Given a diff that deletes three deprecated helpers and their tests: **Good:** `Removed deprecated helpers: user::legacy_login, user::legacy_logout, user::legacy_session_check. All three were behind a deprecation warning since v0.9 and no longer called anywhere in the tree.` **Bad:** `Cleanup.` — technically true. Useless as an audit record. In strict mode, the hook requires an explicit enumeration of deletions and this intent is rejected. **Wrong:** `Renamed legacy_login to login.` — would suggest the functions moved, not that they were deleted. The hook would flag a mismatch because no `user::login` appears in the diff as a new symbol. ## The mechanics of `aura log-intent` `aura log-intent` writes an entry to `.aura/intent_log.jsonl`. Each entry records: - A timestamp. - The current session ID. - The current branch. - The Git `HEAD` at the time of logging. - The natural-language intent. - A hash of the staged diff (so later rebases can detect that the intent was recorded against a different base). The entry is *append-only*. Later log entries do not overwrite earlier ones; they supersede. This is deliberate — the log is an audit trail, not a working file. ### Amending an intent If the pre-commit hook rejects your commit because the intent and diff disagree, and the right fix is to update the intent rather than unstage files: ```bash aura log-intent --amend "Switched password hashing from bcrypt to argon2id; also removed legacy_md5_fallback which was unused." ``` `--amend` appends a new entry that supersedes the previous intent for the current staged diff. The hook re-runs on the next `git commit`. ### Listing recent intents ```bash aura log-intent --list ``` Prints the last ten intents with timestamps, branches, and the commit SHAs they eventually became (or a "pending" marker if the commit has not happened yet). ### Intent for work-in-progress commits For a WIP commit that will be amended or rebased later, log an intent anyway. Use `--wip`: ```bash aura log-intent --wip "Stubbed out Argon2Config; real implementation coming next" ``` WIP intents are not enforced as strictly — the hook tolerates unrelated changes — but they still enter the audit trail. When you eventually finalize the work, log a non-WIP intent that supersedes them. ## Strict mode The behavior above is the *default*. In strict mode, the rules tighten: - Every commit must have an intent. No implicit commits. - `git commit --no-verify` is blocked. - Deletions must be enumerated in the intent by name. - AI-authored commits (detected via `Co-Authored-By` or the MCP agent signature) must carry an intent produced by `aura_log_intent` from within an MCP tool call, not a shell wrapper. Enable strict mode in `.aura/config.toml`: ```toml [policy] strict_mode = true strict_mode_locked = true # requires passcode to disable ``` If `strict_mode_locked` is true, turning strict mode off requires a passcode recorded at lock time. This is how teams ensure that an AI agent cannot disable its own guardrails; see the [CLAUDE.md protocol](/claude-md-integration) for how Claude Code interacts with this. ## Doing it from an AI agent When Claude Code or another MCP-aware agent is the one committing, the flow is the same but the entry points are MCP tools rather than CLI commands: 1. `aura_status` — the agent checks session and sync state. 2. `aura_snapshot` — the agent snapshots files before editing. 3. The agent writes code. 4. `aura_log_intent` — the agent logs its stated intent. This automatically pushes the changed functions to any connected Mothership for teammates' Live Sync. 5. `git commit` — the hook fires and validates. Every MCP tool invocation is recorded. An agent that skips `aura_log_intent` and tries to commit will be stopped by the hook the same way a human would be. ## Common first-time mistakes **"The hook says mismatch, but my intent looks right."** — Check whether you staged files you did not mean to. `git diff --cached --stat` often reveals a stray change. **"I logged an intent, committed, then amended the commit with `git commit --amend`. The hook complains."** — `git commit --amend` changes the diff under the already-logged intent. Re-log with `aura log-intent --amend "..."` before amending. **"I rebased and the intents look detached."** — Rebasing changes commit SHAs. The intent log tracks semantic identity, not SHAs, so the entries remain valid, but `aura log-intent --list` may show "pending" for a beat until the rebase settles. `aura doctor` can resynchronize if needed. **"My intent is fine but the hook still fails."** — Run `aura pr-review --base HEAD~1` to see the exact semantic diff. The hook's view and your mental model may disagree about what changed, especially in generated code. ## Next steps - [Use `aura save`](/your-first-aura-save) to combine snapshot, intent, and commit in one step once the pattern is second nature. - [Connect to a Mothership](/connecting-to-team) so your intent-logged commits also sync in real time to teammates. - [Wire Claude Code via CLAUDE.md](/claude-md-integration) so your agent logs intents automatically. - [Troubleshooting](/troubleshooting-install) for hook-not-firing and related issues.