@rmyndharis/aimhooman 0.1.7 → 0.2.0

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.
@@ -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.7",
12
+ "version": "0.2.0",
13
13
  "license": "MIT",
14
14
  "keywords": [
15
15
  "git",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aimhooman",
3
- "version": "0.1.7",
3
+ "version": "0.2.0",
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"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aimhooman",
3
- "version": "0.1.7",
3
+ "version": "0.2.0",
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",
package/CHANGELOG.md CHANGED
@@ -5,6 +5,162 @@ 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
+ ## [0.2.0] - 2026-07-19
9
+
10
+ This release works through the findings of the cross-ecosystem field test
11
+ (8 upstream clones, 6 language loops, a local bare remote, and a private
12
+ GitHub sandbox). The headline: `allow` no longer says yes when it means no —
13
+ a path allow on a file whose content holds a secret is refused up front,
14
+ with the working escape hatch named in the same breath.
15
+
16
+ ### Fixed
17
+
18
+ - Tracked-tree scans (`audit`, `check --tracked`, `init --grandfather-secrets`)
19
+ no longer die with `spawnSync git EPIPE` on a partial clone of a repository
20
+ with submodule pins. A gitlink names a commit of another repository, so
21
+ asking `cat-file` about it triggered a promisor fetch that aborted the
22
+ whole metadata batch ("not our ref"). Gitlinks now skip the metadata read;
23
+ their type comes from the mode. Found by the OpenSSL field run, whose 11
24
+ submodule pins made the grandfather flag seed zero allows.
25
+ - `init --grandfather-secrets` now runs its one-shot tracked scan with the
26
+ total-byte budget raised to the env cap and the finding budget raised to
27
+ 100,000. The commit-time defaults (64 MiB, 1,000 findings) silently missed
28
+ fixtures beyond them in exactly the large, fixture-heavy repositories the
29
+ flag exists for; the per-file budget and an explicit env override still
30
+ apply.
31
+ - `aimhooman allow <path>` on a file whose content matches a secret rule
32
+ (e.g. a private key inside an ordinary-looking filename) no longer reports
33
+ `allowed` while the commit stays blocked. The guard now runs the engine's
34
+ secret content rules over the file's bytes, refuses the allow, and points
35
+ at `--scope secret-path`. Files over the scan budget or unreadable skip
36
+ the check; the commit-time scanner still fails closed on those.
37
+ - The scan-incomplete summary now names what was skipped
38
+ (`skipped: size-limit=1 file`) instead of `(size-limit=1)`, which read as
39
+ a one-byte budget rather than a count of files.
40
+
41
+ ### Added
42
+
43
+ - `aimhooman init --grandfather-secrets`: after a successful init, scan the
44
+ tracked tree once and write a `--scope secret-path` allow for every path
45
+ already tracking secret-looking material (test certs, sample keys). New
46
+ secrets stay blocked; only paths found in that scan are allowed. A failed
47
+ or incomplete scan warns without failing the init.
48
+ - Provider-token findings name the provider in human output
49
+ (`A provider access token (GitHub) must not enter Git history.`), so the
50
+ developer knows which credential to revoke. The token itself stays
51
+ redacted; the JSON report is unchanged.
52
+ - Secret content rules now carry a remediation line naming the fixture
53
+ escape hatch: `aimhooman allow <path> --scope secret-path --reason
54
+ "test fixture"`.
55
+ - The pre-commit hook now names locally-ignored AI artifacts once per set
56
+ change (`3 AI artifact(s) present locally are kept out of commits: ...`).
57
+ The prevention layer keeps them out of `git status`, which also kept their
58
+ exclusion silent: a `git add .` never told the developer the chat log did
59
+ not make the commit. The worktree walk is pathspec-pruned to the managed
60
+ exclude patterns, so it costs ~15ms; informational only, it never changes
61
+ an exit code.
62
+ - The reference-transaction veto now notes that the rejected commit object
63
+ remains in the local object store — collected by `git gc --prune=now` when
64
+ nothing else references it — so a secret payload is not mistaken for gone.
65
+
66
+ ### Changed
67
+
68
+ - Repeated findings of the same rule print the remediation once, then
69
+ `fix: as above for <rule id>`, instead of reprinting an identical fix
70
+ block for every hit.
71
+ - `init` output now prints `undo: aimhooman uninstall` and notes that known
72
+ AI artifacts are ignored locally (`git status --ignored` shows them).
73
+
74
+ ### Performance
75
+
76
+ - `openRepo` resolves the repository in one `git rev-parse` call instead of
77
+ three; every hook spawn pays this, so it was the cheapest milliseconds on
78
+ the commit path. The common-dir answer is resolved against the invoking
79
+ cwd and canonicalized, preserving the previous spelling on symlinked
80
+ paths (macOS `/tmp`), and a path containing a newline falls back to one
81
+ flag per call.
82
+ - The reference-transaction dispatcher exits before the Node spawn for a
83
+ `prepared` transaction that moves neither a branch nor HEAD (ORIG_HEAD,
84
+ tags, remote-tracking refs). Such payloads carry nothing `refcheck`
85
+ scans — but the skip first proves the four dispatchers are still
86
+ installed, so a hook manager wiping them mid-operation is answered with
87
+ a stop, not silence. An ordinary commit's hook time drops by roughly a
88
+ third in the field measurement (982ms → 649ms).
89
+ - Installed Git hook shims export `NODE_COMPILE_CACHE` pointing at a
90
+ per-install directory under the state dir (removed by
91
+ `uninstall --purge-state`), shaving the module parse/compile cost off
92
+ each hook spawn. An unwritable cache dir degrades to the old cold start,
93
+ never to a hook failure.
94
+
95
+ ## [0.1.8] - 2026-07-18
96
+
97
+ This release works through the findings of the real-world scenario report
98
+ (191 scenarios across 11 repos, 8 languages). The headline: a read-only
99
+ command copied from `gh`'s own docs no longer gets denied, and editing an
100
+ unrelated line in a file that carries a private-key header elsewhere no
101
+ longer blocks the commit.
102
+
103
+ ### Fixed
104
+
105
+ - Read-only commands with unquoted braces (`gh api repos/{owner}/{repo}/pulls`,
106
+ `ls {owner}`, `cp x.{js,ts}`) are no longer denied as opaque commit-hiding
107
+ pipelines. Brace expansion is argument-level and cannot feed code into a pipe
108
+ sink; brace groups (`{ list; }`) and PowerShell script blocks remain opaque.
109
+ The opaque-deny message also no longer names a pipe when the command has none.
110
+ - Editing an unrelated line in a file that contains a private-key header
111
+ elsewhere (e.g. a PEM fixture inside a Go test string) no longer blocks the
112
+ commit. Content scanning is now narrowed to the changed hunks; a header added
113
+ in the diff still blocks, a header carried outside the diff stays silent.
114
+ Binary blobs keep their whole-blob secret scan.
115
+ - AWS's documented example secret access key (`wJalrXUtnFEMI/...EXAMPLEKEY`)
116
+ no longer blocks commits. Its access-key-ID pair was already excepted; the
117
+ secret-key half now is too. Real keys — including ones containing `EXAMPLEKEY`
118
+ as a substring — still block.
119
+ - `aimhooman <subcommand> --help` now prints usage and exits 0 instead of
120
+ erroring on the unknown `--help` option.
121
+ - The human finding report renders every remediation entry (a rule's second
122
+ line, e.g. "rotate the key if it was ever exposed", was silently dropped), and
123
+ its summary line agrees on number (`1 finding`, not `1 findings`). A scan
124
+ firing many findings (a vendored OpenSSL corpus can produce 99) now caps the
125
+ printed blocks at 20 and collapses the rest into one truncation line; the JSON
126
+ report stays uncapped.
127
+ - The `secret.private-key` message now states the match is by filename, not by
128
+ content, and offers renaming the file when the name is coincidental.
129
+ - A chained hook predecessor that resolves sibling scripts via `$(dirname "$0")`
130
+ — the dominant husky and vanilla `.githooks` pattern — no longer breaks after
131
+ `aimhooman init`. The dispatcher now sources the predecessor in a subshell,
132
+ which preserves the original `$0`. (Bash-only predecessors remain out of
133
+ scope.)
134
+
135
+ ### Changed
136
+
137
+ - **Breaking:** an untracked `core.hooksPath` inside the worktree (a freshly
138
+ created `.husky` before its first commit, a team-local `.team-hooks`) is now
139
+ treated as repository content and refuses to receive a dispatcher — the next
140
+ `git add` would otherwise stage the dispatcher's machine-local absolute CLI,
141
+ Node, and PATH into history. Add the path to `.gitignore` or
142
+ `.git/info/exclude` to keep it local; the refusal message names this and
143
+ points at `aimhooman uninstall`. A `.git/hooks/` path and a tracked `.husky`
144
+ are unaffected.
145
+ - `aimhooman review` advisories now persist per path across edits on the
146
+ `clean` and `compliance` profiles, so editing a reviewed agent-instruction
147
+ file (CLAUDE.md, AGENTS.md, `.github/copilot-instructions.md`) no longer
148
+ re-surfaces the review message on every edit. The `strict` profile keeps the
149
+ exact-blob binding unchanged; reviewed deletions (tombstones) keep it in every
150
+ profile.
151
+ - The `aimhooman init` refusal message names the two remedies (unset
152
+ `core.hooksPath`, or exclude the worktree path) and points at
153
+ `aimhooman uninstall`, so a refused init is no longer a dead end.
154
+
155
+ ### Performance
156
+
157
+ - A commit no longer pays a duplicate tree scan in `commit-msg` for the staged
158
+ tree that `pre-commit` just verified. `pre-commit` records the staged tree sha
159
+ after a clean, complete scan; `commit-msg` skips its ~170 ms tree scan when the
160
+ sha matches. The marker is self-invalidating (any index mutation changes the
161
+ sha) and a missing/stale/mismatched marker falls back to the full scan, so
162
+ this is purely an optimization. Net ~150 ms saved per commit.
163
+
8
164
  ## [0.1.7] - 2026-07-18
9
165
 
10
166
  ### Fixed
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.7-blue" alt="v0.1.7">
12
+ <img src="https://img.shields.io/badge/version-v0.2.0-blue" alt="v0.2.0">
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">
@@ -130,6 +130,7 @@ Guard a repository:
130
130
 
131
131
  ```sh
132
132
  aimhooman init # git hooks + local excludes; normally no worktree files
133
+ aimhooman init --grandfather-secrets # also allow --scope secret-path for every secret already tracked (fixtures); new secrets stay blocked
133
134
  aimhooman status
134
135
  aimhooman uninstall # restore hooks/excludes; keep local policy state
135
136
  aimhooman uninstall --purge-state # also delete common Git-directory state