@rmyndharis/aimhooman 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,7 +5,7 @@ This repository uses aimhooman to keep AI tooling artifacts out of Git history.
5
5
  Its policy:
6
6
 
7
7
  - Never stage or commit local AI session/state files. Examples include
8
- `.claude.json`, `.claude/.credentials.json`, `.claude/session*.json`,
8
+ `.claude.json`, `.claude/session*.json`,
9
9
  `.claude/history*`, `.claude/todos/*`, `.claude/shell-snapshots/*`,
10
10
  `.claude/statsig/*`, `.claude/projects/*`, `.claude/logs/*`,
11
11
  `.codex/sessions/*`, `.codex/history*`, `.codex/log/*`, `.codex/logs/*`,
@@ -15,8 +15,10 @@ Its policy:
15
15
  exhaustive; the packaged `rules/paths.json` is the detection source of truth.
16
16
  If one is staged, unstage it and keep it out of Git instead.
17
17
  - Never commit secrets: a real `.env` (not `.env.example`), private keys
18
- (`id_rsa` and files containing a private-key header), `.aws/credentials`, or
19
- service-account keys. Public certificates are allowed.
18
+ (`id_rsa` and files containing a private-key header), `.aws/credentials`,
19
+ `.claude/.credentials.json`, service-account keys, or a provider API key
20
+ (GitHub, GitLab, npm, Slack, Anthropic, OpenAI, Google, Stripe, Hugging Face,
21
+ SendGrid). Public certificates are allowed.
20
22
  - Never add AI attribution to commit messages: no `Co-authored-by` trailer naming
21
23
  an AI (Claude, Copilot, Codex), no "Generated with/by <AI>" lines, no AI-service
22
24
  noreply emails. A commit message reads as if a human wrote it.
@@ -9,7 +9,7 @@
9
9
  "name": "aimhooman",
10
10
  "source": "./",
11
11
  "description": "Keeps AI session files, secrets, and unwanted attribution out at the agent and Git boundary.",
12
- "version": "0.1.1",
12
+ "version": "0.1.3",
13
13
  "license": "MIT",
14
14
  "keywords": [
15
15
  "git",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aimhooman",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "AI works. Hoomans ship. Keeps AI session files, secrets, and unwanted attribution out at the agent and Git boundary.",
5
5
  "author": {
6
6
  "name": "aimhooman"
@@ -5,7 +5,7 @@ This repository uses aimhooman to keep AI tooling artifacts out of Git history.
5
5
  Its policy:
6
6
 
7
7
  - Never stage or commit local AI session/state files. Examples include
8
- `.claude.json`, `.claude/.credentials.json`, `.claude/session*.json`,
8
+ `.claude.json`, `.claude/session*.json`,
9
9
  `.claude/history*`, `.claude/todos/*`, `.claude/shell-snapshots/*`,
10
10
  `.claude/statsig/*`, `.claude/projects/*`, `.claude/logs/*`,
11
11
  `.codex/sessions/*`, `.codex/history*`, `.codex/log/*`, `.codex/logs/*`,
@@ -15,8 +15,10 @@ Its policy:
15
15
  exhaustive; the packaged `rules/paths.json` is the detection source of truth.
16
16
  If one is staged, unstage it and keep it out of Git instead.
17
17
  - Never commit secrets: a real `.env` (not `.env.example`), private keys
18
- (`id_rsa` and files containing a private-key header), `.aws/credentials`, or
19
- service-account keys. Public certificates are allowed.
18
+ (`id_rsa` and files containing a private-key header), `.aws/credentials`,
19
+ `.claude/.credentials.json`, service-account keys, or a provider API key
20
+ (GitHub, GitLab, npm, Slack, Anthropic, OpenAI, Google, Stripe, Hugging Face,
21
+ SendGrid). Public certificates are allowed.
20
22
  - Never add AI attribution to commit messages: no `Co-authored-by` trailer naming
21
23
  an AI (Claude, Copilot, Codex), no "Generated with/by <AI>" lines, no AI-service
22
24
  noreply emails. A commit message reads as if a human wrote it.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aimhooman",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "AI works. Hoomans ship. Keeps AI session files, secrets, and unwanted attribution out at the agent and Git boundary.",
5
5
  "author": {
6
6
  "name": "aimhooman maintainers",
@@ -11,7 +11,7 @@ This repository uses aimhooman to keep AI tooling artifacts out of Git history.
11
11
  Its policy:
12
12
 
13
13
  - Never stage or commit local AI session/state files. Examples include
14
- `.claude.json`, `.claude/.credentials.json`, `.claude/session*.json`,
14
+ `.claude.json`, `.claude/session*.json`,
15
15
  `.claude/history*`, `.claude/todos/*`, `.claude/shell-snapshots/*`,
16
16
  `.claude/statsig/*`, `.claude/projects/*`, `.claude/logs/*`,
17
17
  `.codex/sessions/*`, `.codex/history*`, `.codex/log/*`, `.codex/logs/*`,
@@ -21,8 +21,10 @@ Its policy:
21
21
  exhaustive; the packaged `rules/paths.json` is the detection source of truth.
22
22
  If one is staged, unstage it and keep it out of Git instead.
23
23
  - Never commit secrets: a real `.env` (not `.env.example`), private keys
24
- (`id_rsa` and files containing a private-key header), `.aws/credentials`, or
25
- service-account keys. Public certificates are allowed.
24
+ (`id_rsa` and files containing a private-key header), `.aws/credentials`,
25
+ `.claude/.credentials.json`, service-account keys, or a provider API key
26
+ (GitHub, GitLab, npm, Slack, Anthropic, OpenAI, Google, Stripe, Hugging Face,
27
+ SendGrid). Public certificates are allowed.
26
28
  - Never add AI attribution to commit messages: no `Co-authored-by` trailer naming
27
29
  an AI (Claude, Copilot, Codex), no "Generated with/by <AI>" lines, no AI-service
28
30
  noreply emails. A commit message reads as if a human wrote it.
@@ -5,7 +5,7 @@ This repository uses aimhooman to keep AI tooling artifacts out of Git history.
5
5
  Its policy:
6
6
 
7
7
  - Never stage or commit local AI session/state files. Examples include
8
- `.claude.json`, `.claude/.credentials.json`, `.claude/session*.json`,
8
+ `.claude.json`, `.claude/session*.json`,
9
9
  `.claude/history*`, `.claude/todos/*`, `.claude/shell-snapshots/*`,
10
10
  `.claude/statsig/*`, `.claude/projects/*`, `.claude/logs/*`,
11
11
  `.codex/sessions/*`, `.codex/history*`, `.codex/log/*`, `.codex/logs/*`,
@@ -15,8 +15,10 @@ Its policy:
15
15
  exhaustive; the packaged `rules/paths.json` is the detection source of truth.
16
16
  If one is staged, unstage it and keep it out of Git instead.
17
17
  - Never commit secrets: a real `.env` (not `.env.example`), private keys
18
- (`id_rsa` and files containing a private-key header), `.aws/credentials`, or
19
- service-account keys. Public certificates are allowed.
18
+ (`id_rsa` and files containing a private-key header), `.aws/credentials`,
19
+ `.claude/.credentials.json`, service-account keys, or a provider API key
20
+ (GitHub, GitLab, npm, Slack, Anthropic, OpenAI, Google, Stripe, Hugging Face,
21
+ SendGrid). Public certificates are allowed.
20
22
  - Never add AI attribution to commit messages: no `Co-authored-by` trailer naming
21
23
  an AI (Claude, Copilot, Codex), no "Generated with/by <AI>" lines, no AI-service
22
24
  noreply emails. A commit message reads as if a human wrote it.
@@ -5,7 +5,7 @@ This repository uses aimhooman to keep AI tooling artifacts out of Git history.
5
5
  Its policy:
6
6
 
7
7
  - Never stage or commit local AI session/state files. Examples include
8
- `.claude.json`, `.claude/.credentials.json`, `.claude/session*.json`,
8
+ `.claude.json`, `.claude/session*.json`,
9
9
  `.claude/history*`, `.claude/todos/*`, `.claude/shell-snapshots/*`,
10
10
  `.claude/statsig/*`, `.claude/projects/*`, `.claude/logs/*`,
11
11
  `.codex/sessions/*`, `.codex/history*`, `.codex/log/*`, `.codex/logs/*`,
@@ -15,8 +15,10 @@ Its policy:
15
15
  exhaustive; the packaged `rules/paths.json` is the detection source of truth.
16
16
  If one is staged, unstage it and keep it out of Git instead.
17
17
  - Never commit secrets: a real `.env` (not `.env.example`), private keys
18
- (`id_rsa` and files containing a private-key header), `.aws/credentials`, or
19
- service-account keys. Public certificates are allowed.
18
+ (`id_rsa` and files containing a private-key header), `.aws/credentials`,
19
+ `.claude/.credentials.json`, service-account keys, or a provider API key
20
+ (GitHub, GitLab, npm, Slack, Anthropic, OpenAI, Google, Stripe, Hugging Face,
21
+ SendGrid). Public certificates are allowed.
20
22
  - Never add AI attribution to commit messages: no `Co-authored-by` trailer naming
21
23
  an AI (Claude, Copilot, Codex), no "Generated with/by <AI>" lines, no AI-service
22
24
  noreply emails. A commit message reads as if a human wrote it.
@@ -9,7 +9,7 @@ This repository uses aimhooman to keep AI tooling artifacts out of Git history.
9
9
  Its policy:
10
10
 
11
11
  - Never stage or commit local AI session/state files. Examples include
12
- `.claude.json`, `.claude/.credentials.json`, `.claude/session*.json`,
12
+ `.claude.json`, `.claude/session*.json`,
13
13
  `.claude/history*`, `.claude/todos/*`, `.claude/shell-snapshots/*`,
14
14
  `.claude/statsig/*`, `.claude/projects/*`, `.claude/logs/*`,
15
15
  `.codex/sessions/*`, `.codex/history*`, `.codex/log/*`, `.codex/logs/*`,
@@ -19,8 +19,10 @@ Its policy:
19
19
  exhaustive; the packaged `rules/paths.json` is the detection source of truth.
20
20
  If one is staged, unstage it and keep it out of Git instead.
21
21
  - Never commit secrets: a real `.env` (not `.env.example`), private keys
22
- (`id_rsa` and files containing a private-key header), `.aws/credentials`, or
23
- service-account keys. Public certificates are allowed.
22
+ (`id_rsa` and files containing a private-key header), `.aws/credentials`,
23
+ `.claude/.credentials.json`, service-account keys, or a provider API key
24
+ (GitHub, GitLab, npm, Slack, Anthropic, OpenAI, Google, Stripe, Hugging Face,
25
+ SendGrid). Public certificates are allowed.
24
26
  - Never add AI attribution to commit messages: no `Co-authored-by` trailer naming
25
27
  an AI (Claude, Copilot, Codex), no "Generated with/by <AI>" lines, no AI-service
26
28
  noreply emails. A commit message reads as if a human wrote it.
package/AGENTS.md CHANGED
@@ -5,7 +5,7 @@ This repository uses aimhooman to keep AI tooling artifacts out of Git history.
5
5
  Its policy:
6
6
 
7
7
  - Never stage or commit local AI session/state files. Examples include
8
- `.claude.json`, `.claude/.credentials.json`, `.claude/session*.json`,
8
+ `.claude.json`, `.claude/session*.json`,
9
9
  `.claude/history*`, `.claude/todos/*`, `.claude/shell-snapshots/*`,
10
10
  `.claude/statsig/*`, `.claude/projects/*`, `.claude/logs/*`,
11
11
  `.codex/sessions/*`, `.codex/history*`, `.codex/log/*`, `.codex/logs/*`,
@@ -15,8 +15,10 @@ Its policy:
15
15
  exhaustive; the packaged `rules/paths.json` is the detection source of truth.
16
16
  If one is staged, unstage it and keep it out of Git instead.
17
17
  - Never commit secrets: a real `.env` (not `.env.example`), private keys
18
- (`id_rsa` and files containing a private-key header), `.aws/credentials`, or
19
- service-account keys. Public certificates are allowed.
18
+ (`id_rsa` and files containing a private-key header), `.aws/credentials`,
19
+ `.claude/.credentials.json`, service-account keys, or a provider API key
20
+ (GitHub, GitLab, npm, Slack, Anthropic, OpenAI, Google, Stripe, Hugging Face,
21
+ SendGrid). Public certificates are allowed.
20
22
  - Never add AI attribution to commit messages: no `Co-authored-by` trailer naming
21
23
  an AI (Claude, Copilot, Codex), no "Generated with/by <AI>" lines, no AI-service
22
24
  noreply emails. A commit message reads as if a human wrote it.
package/CHANGELOG.md CHANGED
@@ -5,7 +5,183 @@ All notable changes to this project are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## [Unreleased]
8
+ ## [0.1.3] - 2026-07-18
9
+
10
+ ### Fixed
11
+
12
+ - Repair that empties the index no longer mints an empty commit. Stage only a `.env`,
13
+ run `git commit -m "add config"`, and the pre-commit repair unstages it and prints
14
+ "the commit will be empty" — then Git made that empty commit anyway. Git refuses a
15
+ commit with nothing staged, but repair runs after Git has already decided to proceed,
16
+ so carrying on created a commit Git would never have made and left a junk commit to
17
+ `git reset --hard`. Pre-commit now exits 10 when the repair empties the index, so Git
18
+ stops. Nothing else staged means nothing to commit.
19
+ - `build && git add . && git commit` is no longer denied. Each half already passed on its
20
+ own; only the pair was refused. The commit-time-staging deny asked the wide bypass
21
+ predicate — the one that decides whether the staged-content backstop reads the blobs —
22
+ instead of the narrow question of whether anything will scan the commit. An unmodelled
23
+ prefix is not a bypass, and pre-commit still scans the real index at commit time. The
24
+ deny now asks that narrow question. A prefix that reaches the hooks, `--no-verify`, and
25
+ a real `core.hooksPath` override all keep the deny, where the staged files really would
26
+ go unscanned. The refusal message no longer names "--no-verify or shell indirection"
27
+ when neither is present.
28
+ - The `PreToolUse` guard stops refusing more everyday read-only pipelines. Building on the
29
+ 0.1.1 filter allowance, a read-only Git subcommand is now an allowed pipe source, so
30
+ `git log | head`, `git status | grep modified`, `git diff | cat`, and
31
+ `cd repo && git log | head` run. Build and test toolchains (`npm`, `cargo`, `make`,
32
+ `jest`, `eslint`, `tsc`, `pytest`) are allowed as a source. The listing forms of
33
+ branch/tag/remote/stash/notes run (`git branch | grep`, `git remote -v | grep origin`),
34
+ while their mutating forms (`git branch -D`, `git tag v1`) stay denied. Git as a pipe
35
+ sink, `git commit --no-verify`, and `git push` still deny; the reference-transaction and
36
+ pre-commit hooks remain the boundary.
37
+
38
+ ## [0.1.2] - 2026-07-17
39
+
40
+ ### Removed
41
+
42
+ - The legacy per-clone state migration is gone, and with it the failure paths it
43
+ created. `openRepo` used to look for state under `.git/worktrees/<name>/aimhooman`
44
+ and migrate it into `<commonDir>/aimhooman`, fingerprinting both and refusing to
45
+ continue when two copies disagreed. No released version ever wrote to that
46
+ location — v0.1.0 already resolved state to `<commonDir>/aimhooman` on the line
47
+ above the migration — so the predecessor it protected never existed. What it did
48
+ produce was real: any error other than ENOENT while listing `.git/worktrees` was
49
+ re-raised through every command, including `uninstall`, so a directory Git itself
50
+ reads without trouble could freeze a repository with no supported way out.
51
+ `.git/worktrees` belongs to Git and can be owned by another uid after a
52
+ `sudo git worktree add`. Repository state resolves to `<commonDir>/aimhooman`, as
53
+ it always has.
54
+
55
+ ### Fixed
56
+
57
+ - Unstaging residue no longer stages the deletion of tracked files. The HEAD probe
58
+ reused the options object carrying the pathspec on stdin, and `git rev-parse`
59
+ never reads stdin, so once the pathspec passed the 64 KiB pipe buffer the write
60
+ failed with `EPIPE`. The catch read that as "this repository has no HEAD" and ran
61
+ `git rm --cached` where `git restore --staged` was meant, staging the deletion of
62
+ every tracked path it had been asked to restore, printing "unstaged N AI
63
+ artifact(s)", and exiting 0 so the commit carried the deletions into history. It
64
+ takes roughly 470 paths to cross that buffer, which a tracked `.claude/projects/`
65
+ tree passes without trying, and the repair loop could not see it: the staged
66
+ deletions read as still-staged, so it retried, made no progress, and reported
67
+ success anyway. The probe no longer receives the pathspec, and only git's own exit
68
+ status may pick the branch — a timeout or a missing git stops the commit instead
69
+ of guessing that HEAD is absent. Present since 0.1.0.
70
+ - A stuck `git` no longer holds a repository open indefinitely. `execFileSync` has
71
+ no default timeout, so a child that never exited blocked its caller for as long as
72
+ it lived, with nothing printed and nothing logged; one held a CI runner for six
73
+ hours and died to the platform's ceiling rather than to anything here. Every child
74
+ process now carries a bound: 120 seconds for git, far above any real call, and 5
75
+ seconds for the `ps` identity probe, which runs inside the lock retry loop and only
76
+ on macOS and BSD (Linux reads `/proc`, Windows returns early). Both throw into the
77
+ handling that was already there, so a bounded failure degrades the way a missing
78
+ git already did instead of hanging. A test walks `src/` and `bin/` and fails on any
79
+ child process without a bound.
80
+ - Renaming or moving a repository no longer freezes it. The dispatcher bakes
81
+ absolute paths, so a move changes the `CHAINED` value it carries, and ownership
82
+ was decided by comparing that string — overruling the SHA-256 fingerprint on the
83
+ line above, which had already proved the file was ours. Every commit, every
84
+ `--no-verify`, and every branch creation then failed; `status` reported the guard
85
+ as belonging to another repository; `aimhooman init`, the remedy each message
86
+ named, refused too. Ownership inside the repository's own `.git` is now settled
87
+ by the fingerprint alone, because no second repository can own a file there. The
88
+ baked path keeps its vote only where a hooks directory can genuinely be shared —
89
+ two repositories pointing `core.hooksPath` at one place — which is the case it
90
+ was written for.
91
+ - `uninstall` no longer reports success while leaving its own dispatchers behind.
92
+ Refusals were recorded as warnings, the exit code only consulted failures, and
93
+ the "uninstalled" headline printed before either was known, so a moved
94
+ repository was told it was free while four dispatchers still blocked every
95
+ commit. uninstall now checks the hooks directory instead of trusting its own
96
+ report: anything of ours still on disk is named with its full path, the headline
97
+ is withheld, and the exit code is 30. A chained backup that is a symlink is
98
+ still never read or copied through, but the dispatcher above it is now removed
99
+ rather than held as collateral, and the report says the original hook was not
100
+ restored.
101
+ - A `HOME` behind a symlink no longer makes every global dispatcher look foreign.
102
+ `hookDiagnostics` compared the effective hooks directory to the global one with
103
+ `resolve`, which does not follow symlinks, while Git reports the realpath — so
104
+ on a distribution that ships `/home` as a link, or an NFS or autofs home, the
105
+ two spellings differed and every global hook was diagnosed as managed for
106
+ another repository.
107
+ - A failed excludes refresh no longer disables the `PreToolUse` guard. Writing
108
+ `.git/info/exclude` sat inside the same `try` as the engine load, and the shared
109
+ `catch` allowed the command on every non-strict profile, so an unwritable
110
+ `.git/info` — a CI checkout, a read-only volume, a repository owned by another
111
+ user — turned a staged AWS key plus `git commit --no-verify` from `deny` into
112
+ `allow`. Nothing about the policy was wrong: the rules had loaded, and the
113
+ reported cause ("could not load policy rules") named the wrong thing. Refreshing
114
+ the excludes is gitignore hygiene, which `pre-commit` never does and still
115
+ answers correctly, so it now runs outside the verdict and reports as a warning.
116
+
117
+ - A local rule pack that cannot load no longer produces a report claiming a
118
+ complete scan. `strict` already failed closed, but `clean` and `compliance`
119
+ turned the load error into a stderr warning and left the accumulator untouched,
120
+ so `--json` returned `complete: true`, `findings: []`, `skipped: {}` and exit 0
121
+ while the team's own rules had never run. The pack most teams write is a
122
+ detector for their internal token format; one typo took it out of the scan, and
123
+ the report actively certified that nothing was missed. A failed pack is now the
124
+ counted skip reason `local-pack-error` and marks the scan incomplete, which is
125
+ the treatment `local-input-limit` already had in every profile: a rule that
126
+ never ran is a coverage gap, not an empty result. `clean` and `compliance`
127
+ therefore stop at exit 31 where they previously continued. The hint now points
128
+ at the pack instead of suggesting the caller reduce the target or limits, which
129
+ was never the remedy for a pattern that will not compile.
130
+ - Creating a branch no longer rescans the entire repository. A new branch arrives
131
+ with an all-zero old tip, so `rev-list` ran with no negative boundary and every
132
+ ancestor was re-read, tree and blob sizes included: 24.7s at 200 commits, growing
133
+ linearly, on an operation `--no-verify` cannot skip. Reachability from
134
+ `refs/heads/*` is now trusted, because those commits passed this same guard when
135
+ their branch was written, which puts `git checkout -b` back at ordinary commit
136
+ cost (0.95s in the same repository). Only `refs/heads/*` counts: tags and remote
137
+ refs are not gated here and still cannot pre-poison reachability, the refs under
138
+ review are never their own proof, and a commit no local branch reaches is still
139
+ scanned in full. Commits that predate `aimhooman init` are outside the guard's
140
+ scope; audit them with `check --range`.
141
+ - `init` no longer writes dispatchers into a hooks directory that Git tracks.
142
+ Ownership was tested by location alone, so any `core.hooksPath` inside the
143
+ worktree counted as the repository's own — including the committed `.husky` and
144
+ `.githooks` directories that husky and the vanilla pattern rely on. init edited
145
+ those tracked files in place, and the dispatcher it wrote carries this machine's
146
+ absolute CLI, Node, and PATH: once committed, the hook is dead for every
147
+ teammate, and the PATH alone discloses the author's home directory and installed
148
+ tooling. Ownership now also requires that Git is not tracking the directory, and
149
+ a directory Git cannot be asked about counts as tracked. A refusal now names the
150
+ cause instead of reporting a bare incomplete installation; as before, integrate
151
+ aimhooman into the existing hook manager or remove the override.
152
+ - A moved Node interpreter no longer disables the guard silently. 0.1.1 made the
153
+ dispatcher degrade gracefully when the CLI or Node was missing, which is right
154
+ for a half-removed install but wrong for a relocated interpreter: `brew upgrade
155
+ node`, `nvm`, `fnm`, and `volta` all move the `process.execPath` that `init`
156
+ pins, and every hook then warned once and allowed the commit unprotected. The
157
+ conditions now separate by what the user can still do about them. A missing CLI
158
+ still allows the operation, because the package is gone and no guard is wanted.
159
+ A missing pinned interpreter stops the operation and names the path and the
160
+ remedy — but only while a Node exists to run that remedy with, since `init` and
161
+ `uninstall` are both Node programs and the CLI file is inert without one.
162
+ Where no Node is present at all, the dispatcher degrades and says so, because
163
+ refusing there would leave the repository unusable with no supported way to
164
+ remove the hooks. Stopping matches what the CLI already believed —
165
+ `installedHooks` treats an unreachable Node as an inactive dispatcher, so the
166
+ shell was short-circuiting the CLI's own fail-closed path — but only where
167
+ stopping is recoverable. Re-run `aimhooman init` after upgrading Node to re-pin it.
168
+ - Attribution rules no longer miss current AI footers. `attribution.generated-with`
169
+ pinned the literal vendor link `https://claude.ai/code`, and the co-author rules
170
+ pinned the display names `Claude`, `Claude Code`, and `Codex`. Once the link was
171
+ rebranded and the display name grew a model suffix, the default footer passed
172
+ through untouched with exit 0 while the older form was still repaired perfectly.
173
+ The rules now anchor on what identifies the machine rather than what marketing
174
+ changes: a co-author trailer is matched by its `noreply@` service address alone,
175
+ and the generated-with link is matched by its shape. A new contract test rejects
176
+ any attribution pattern that pins a vendor URL, so the pack cannot rot back into
177
+ this state without failing CI.
178
+ - `attribution.ai-noreply` no longer backtracks catastrophically. `\s*[^<>]+\s*`
179
+ placed three ambiguous quantifiers before a literal `<`, which cost 49s on a
180
+ 6400-character trailer that never closes; built-in patterns are exempt from the
181
+ local input cap, so a commit message reached it directly. The redundant
182
+ whitespace quantifiers are gone (`[^<>]+` already spans them), leaving the
183
+ matched language unchanged, and a bounded-cost test now covers the built-in
184
+ message patterns.
9
185
 
10
186
  ## [0.1.1] - 2026-07-16
11
187
 
package/CONTRIBUTING.md CHANGED
@@ -88,7 +88,39 @@ Personal, per-clone detection belongs in `<git-common-dir>/aimhooman/rules/*.jso
88
88
  (local, never committed). Linked worktrees share it. Contribute general-purpose
89
89
  rules to `rules/` instead.
90
90
 
91
- ## Commit policy (important)
91
+ ## Commits
92
+
93
+ Subject lines follow [Conventional Commits](https://www.conventionalcommits.org/):
94
+ `type(scope): summary`.
95
+
96
+ | Type | Use for |
97
+ | --- | --- |
98
+ | `feat` | a new rule, host adapter, or CLI capability |
99
+ | `fix` | a bug fix |
100
+ | `docs` | documentation only |
101
+ | `test` | tests and fixtures only |
102
+ | `refactor` | restructuring that leaves behavior identical |
103
+ | `perf` | a speedup you can measure |
104
+ | `ci` | workflows and release automation |
105
+ | `chore` | dependency bumps, version stamping, housekeeping |
106
+
107
+ Scopes track the project layout: `rules`, `hook`, `githooks`, `cli`, `state`,
108
+ `adapter`, `deps`, `release`. Drop the scope when a change spans several.
109
+
110
+ The `type(scope):` prefix is the only part that is a format. Everything after the
111
+ colon stays a plain imperative sentence that names what actually changed:
112
+
113
+ ```
114
+ fix(state): retry the rename when Windows reports a transient lock
115
+ fix(hook): allow Git operations when the aimhooman CLI or Node is missing
116
+ ci: run the test matrix once per change instead of twice
117
+ chore(release): 0.1.1
118
+ ```
119
+
120
+ PRs land as squash merges, so the PR title is the commit message that lands on
121
+ `main`. Title the PR the same way.
122
+
123
+ ### Policy (important)
92
124
 
93
125
  This project keeps AI tooling residue out of history — **including its own**.
94
126
  Commits must read as if a human wrote them:
@@ -100,10 +132,11 @@ Commits must read as if a human wrote them:
100
132
 
101
133
  ## Pull requests
102
134
 
103
- 1. Open a PR against `main`.
135
+ 1. Open a PR against `main`. Title it `type(scope): summary` — it becomes the
136
+ commit message on `main`.
104
137
  2. Include tests for any new behavior and run `npm run verify`.
105
138
  3. Update `CHANGELOG.md` and `docs/` where relevant.
106
- 4. Make sure the PR follows the commit policy above.
139
+ 4. Make sure the PR follows the commit conventions above.
107
140
 
108
141
  By participating, you agree to abide by the [Code of Conduct](CODE_OF_CONDUCT.md).
109
142
 
package/GEMINI.md CHANGED
@@ -5,7 +5,7 @@ This repository uses aimhooman to keep AI tooling artifacts out of Git history.
5
5
  Its policy:
6
6
 
7
7
  - Never stage or commit local AI session/state files. Examples include
8
- `.claude.json`, `.claude/.credentials.json`, `.claude/session*.json`,
8
+ `.claude.json`, `.claude/session*.json`,
9
9
  `.claude/history*`, `.claude/todos/*`, `.claude/shell-snapshots/*`,
10
10
  `.claude/statsig/*`, `.claude/projects/*`, `.claude/logs/*`,
11
11
  `.codex/sessions/*`, `.codex/history*`, `.codex/log/*`, `.codex/logs/*`,
@@ -15,8 +15,10 @@ Its policy:
15
15
  exhaustive; the packaged `rules/paths.json` is the detection source of truth.
16
16
  If one is staged, unstage it and keep it out of Git instead.
17
17
  - Never commit secrets: a real `.env` (not `.env.example`), private keys
18
- (`id_rsa` and files containing a private-key header), `.aws/credentials`, or
19
- service-account keys. Public certificates are allowed.
18
+ (`id_rsa` and files containing a private-key header), `.aws/credentials`,
19
+ `.claude/.credentials.json`, service-account keys, or a provider API key
20
+ (GitHub, GitLab, npm, Slack, Anthropic, OpenAI, Google, Stripe, Hugging Face,
21
+ SendGrid). Public certificates are allowed.
20
22
  - Never add AI attribution to commit messages: no `Co-authored-by` trailer naming
21
23
  an AI (Claude, Copilot, Codex), no "Generated with/by <AI>" lines, no AI-service
22
24
  noreply emails. A commit message reads as if a human wrote it.
package/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  <p align="center">
11
11
  <img src="https://img.shields.io/github/actions/workflow/status/rmyndharis/aimhooman/test.yml?branch=main&label=CI" alt="CI">
12
- <img src="https://img.shields.io/badge/version-v0.1.1-blue" alt="v0.1.1">
12
+ <img src="https://img.shields.io/badge/version-v0.1.3-blue" alt="v0.1.3">
13
13
  <img src="https://img.shields.io/badge/node-%E2%89%A522.8-339933?logo=node.js&logoColor=white" alt="Node 22.8+">
14
14
  <img src="https://img.shields.io/badge/dependencies-0-brightgreen" alt="Zero dependencies">
15
15
  <img src="https://img.shields.io/badge/license-MIT-111111" alt="MIT">
@@ -151,9 +151,14 @@ Prefer repository `init` unless the global ordering is understood.
151
151
 
152
152
  When `core.hooksPath` is set, Git reads hooks only from that effective directory and
153
153
  ignores `.git/hooks`. Repository `init` installs and chains predecessors only when
154
- that directory is absent or is proven to be owned by the repository. It refuses to
155
- modify a global, shared, or external hook directory. In that case, integrate
156
- aimhooman into the existing hook manager or remove the override before retrying.
154
+ that directory is absent or is proven to be owned by the repository: inside it and
155
+ not tracked by Git. It refuses to modify a global, shared, external, or tracked
156
+ hook directory, because a dispatcher committed from one machine names paths that
157
+ exist only on that machine. Those repositories are not guarded, and there is no
158
+ way to guard them today. Calling `aimhooman precommit` from an existing hook
159
+ manager runs the check but registers no managed guard, so the agent hook still
160
+ refuses the commit. Remove the override before retrying, or accept that the
161
+ repository is unguarded and do not run `init` there.
157
162
 
158
163
  Repository `init` installs `pre-commit`, `pre-merge-commit`, `commit-msg`, and
159
164
  `reference-transaction`, and preserves an existing hook as a predecessor. For
@@ -236,7 +241,8 @@ files automatically.
236
241
  `.agent/`. [`rules/paths.json`](rules/paths.json) is the complete catalog.
237
242
  - **Secrets**: a real `.env` (not `.env.example`), private-key content,
238
243
  `.aws/credentials`, service-account private keys, recognized AWS secret/session
239
- assignments, and provider token prefixes for GitHub, GitLab, npm, and Slack.
244
+ assignments, and provider token prefixes for GitHub, GitLab, npm, Slack,
245
+ Anthropic, OpenAI, Google, Stripe, Hugging Face, and SendGrid.
240
246
  Public certificates are allowed.
241
247
  - **AI attribution** in commit messages: known AI `Co-authored-by:` identities,
242
248
  exact "Generated with/by ..." lines, and AI-service noreply attribution trailers.
@@ -408,9 +414,13 @@ that would open an editor, and commits with an active foreign `prepare-commit-ms
408
414
  It still cannot prove that every program already selected by local Git config is safe.
409
415
  Commands assembled from files, encoded data, or network input may also be invisible to
410
416
  its non-executing shell parser (POSIX shells — bash, sh, zsh, dash, ksh — and
411
- `git.exe`; command nesting, pipelines, background jobs, and non-POSIX executors
412
- such as PowerShell or fish are classified uncertain and, on `strict`, denied
413
- with a retry instruction). Repository selection written in non-POSIX shell syntax
417
+ `git.exe`). Everyday read-only pipelines run, because a read-only source cannot hide or
418
+ feed a commit: `git log | head`, `git status | grep modified`, `git diff | cat`,
419
+ `git branch | grep`, `npm test | tail`, `cargo build 2>&1 | grep error`, and
420
+ `cd repo && git log | head` all pass. What stays uncertain and, on `strict`, is denied
421
+ with a retry instruction: a git command as a pipe *sink* (`cat patch | git apply`),
422
+ pipe-to-shell (`curl x | bash`), command nesting, background jobs, and non-POSIX
423
+ executors such as PowerShell or fish. Repository selection written in non-POSIX shell syntax
414
424
  is denied before policy lookup on every profile. Guarded Git changes, including
415
425
  `add`, commit, and ref updates, also reject shell-expanded targets, any leading-tilde
416
426
  target, POSIX targets beginning with exactly `//`, and an explicit split