Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
29a1cea
fix(skillscan): a quoted sensitive path no longer hides its upload (R2)
joyful-ii-V-I Oct 1, 2026
922feac
fix(report): multi-root refusals probe every mined root for a shallow…
joyful-ii-V-I Oct 1, 2026
2fd7774
docs(limits): kMentionsNameMaxDepth is an INDEXING cap that discloses…
joyful-ii-V-I Oct 1, 2026
f9cc7de
docs(commands): --impact sample carries d=, no duplicated caveat, no …
joyful-ii-V-I Oct 1, 2026
8b8313f
chore: review-body nitpicks — null-parent guard, closed-name ASSUME, …
joyful-ii-V-I Oct 1, 2026
885cc52
refactor(skillscan): word() keeps its train-22 signature; quote-glued…
joyful-ii-V-I Oct 1, 2026
25f39de
fix(quality): log-only recognises loggers spelled with a call, a sigi…
joyful-ii-V-I Oct 1, 2026
976d306
docs(readme): eleven quality kinds, not ten
joyful-ii-V-I Oct 1, 2026
3d7badf
changelog: log-receiver recall entry; no backticked curl flag in the …
joyful-ii-V-I Oct 1, 2026
8df82d8
test: re-pin printf parity help_all after the --impact/--quality-delt…
joyful-ii-V-I Oct 1, 2026
589e1fa
Merge remote-tracking branch 'origin/main' into lane/train22-cr2-067
joyful-ii-V-I Oct 1, 2026
7d4c380
fix(skillscan): read a split word once, linearly, with its redirect, …
joyful-ii-V-I Oct 1, 2026
70e0d41
docs(lineage): eleven quality kinds; reuse-decline is new-clone-of-re…
joyful-ii-V-I Oct 1, 2026
ce097b4
fix(skillscan): a runner option's value or flag split by quotes stays…
joyful-ii-V-I Oct 1, 2026
67cb40a
fix(skillscan): reader state per command context; a split upload opti…
joyful-ii-V-I Oct 1, 2026
4d2322e
fix(quality): a paren inside a quoted call argument is not a call del…
joyful-ii-V-I Oct 1, 2026
985d5c1
changelog: skill-scan entry names split option values, split upload o…
joyful-ii-V-I Oct 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,37 @@ per page instead. Gate: `test/impactdepthcheck.sh`.
placeholder changes). Every ingest cache written by an earlier build is refused and re-indexed once, and every
cached quality snapshot is recomputed. The session legend dictionary is `dictv=0e543e1e6a3fe37d entries=750`.

### Fixed — `--scan-skill(s)`: quoting a sensitive path no longer hides its upload (sensitive-read-upload)

`cat /etc/passwd | curl … @- URL` grades CRITICAL, but `cat "/etc/passwd" | curl …` scanned clean: an
opening quote put the flow scan back in command position, so the reader's quoted file was read as a command and its
read was never noted. A quote no longer re-arms command position inside a reader's segment (it still does elsewhere,
so `sh -c "…"` and `echo "…" | sh` are read as code), and a shell word split by quotes or escapes (`/etc/"passwd"`,
`@"/etc/passwd"`, `/etc/pass\wd`, `< /etc/"passwd"`) is also read whole, once, when it ends — and in command position
names the command (`\cat`, `c"a"t`, `\curl`). A runner option's split value stays a value (`sudo -u ro''ot cat`), a split upload
option still marks its file (`curl -""T /etc/passwd`), and a reader's state stays inside its own command context
(`cat <(sh -c 'curl … @/etc/passwd …')` is an upload). Single-quoted, mixed, redirected and `head -c "N" FILE` forms are
covered by `test/skillscan.sh`. Against the previous scanner no finding is lost on the skill fixtures, an adversarial
set or this repository's own Markdown and scripts; two CRITICAL rows gain `why="sensitive-read-upload"`.

### Fixed — `--cochange` / `--owners` / `--hotspots` in a multi-root workspace name a shallow secondary root when they refuse

When no workspace root had a commit to mine, the refusal probed only the primary root for a shallow clone, so a full
primary next to a depth-limited secondary still said "git unavailable / no history". The refusal now probes every
mined root (the one root `--owners=SYM` mines) and names the shallow root it found, as the success paths' `shallow="1"`
already did. Single-root output is unchanged. Gate: `test/shallowhistorycheck.sh` section 3m.

### Fixed — `--quality-delta` error-masking: log-only recognises loggers spelled with a call, a sigil, an acronym or a digit

The whole-word logger rule split a receiver only on `_`, `-` and camelCase, so `logging.getLogger(__name__).error(…)`,
`get_logger()`, `structlog.get_logger()`, `@logger`, `$logger`, `this.#logger`, `HTTPLogger`, `logger2`, `mylog` and
`vlog` were no longer loggers, and Python's gating log-only rows were lost. Trailing call arguments now come off before
the last `.` segment, words split on every non-alphanumeric byte, at acronym-to-word and at letter-to-digit steps, and a
logger package spelled as one word (structlog, logfire, logbook, loguru) or log/logger/logging behind a one- or
two-letter prefix counts (so clog, flog and clogging do too). Longer English words that end in "log" (catalog,
dialog, backlog, analog, changelog), blog and
technology still log nothing. Still a miss: a logger behind a longer one-word prefix (`auditlog`).

### Fixed — review round on train 22: false gates, a stack overflow, silent cuts

- `--quality-delta` log-only handlers: a receiver is a logger only when the first or last word of its last segment is `log`, `logger` or `logging` (words split on `_`, `-` and camelCase), or a known logger package, not whenever it contains "log". A Python `except Exception: store.catalog.write(x)` no longer gates as log-only.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
**The ripgrep of AI context. A map before your agent reads the repo — and a check on what it writes.**

Ranked, deterministic call graph: what to touch, what it breaks, which tests to run. On the edit: blast
radius, tests that reach it, ten quality kinds reporting only what got worse, forgotten co-changes, fields
radius, tests that reach it, eleven quality kinds reporting only what got worse, forgotten co-changes, fields
read and written, names that resolve more than one way.

**Just want to use it?** Install it with the one line below, then start each coding session by telling your agent to
Expand Down
60 changes: 30 additions & 30 deletions docs/COMMANDS.md

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions docs/LIMITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ None of them truncates anything, so none can be judged by `shown=`/`total=` and
a disclosure — labelling them OUTPUT would ask for a `capped="1"` that could never honestly fire.
The distinction was named in review on #108 and the rows below now carry it.

The `class` column below carries that answer where it is known. **127 of 230 caps are classified
(42 INDEXING, 41 OUTPUT, 44 BOUNDARY); the remaining 103 render `—`, which means NOT YET
The `class` column below carries that answer where it is known. **128 of 230 caps are classified
(43 INDEXING, 41 OUTPUT, 44 BOUNDARY); the remaining 102 render `—`, which means NOT YET
CLASSIFIED — never "neither".** Classifications live in `docs/limits_classes.tsv`, a sidecar with
a known expiry:
the tag belongs on the declaration itself, and this file exists only because the round that
Expand Down Expand Up @@ -360,7 +360,7 @@ Discloses: **none**

| constant | value | class | note |
| --- | --- | --- | --- |
| `kMentionsNameMaxDepth` | `512` | — | — |
| `kMentionsNameMaxDepth` | `512` | INDEXING | undisclosed: a deeper subtree answers "mentions it", so a log-only handler that deep is never flagged |

### `src/handoff.h`

Expand Down
2 changes: 1 addition & 1 deletion docs/LINEAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ left to look like a paper.
| ONTO — [arXiv:2604.17512](https://arxiv.org/abs/2604.17512) | Genuinely tabular rows re-encode far cheaper as parallel arrays than as repeated per-row markup. | `--format=columnar` (`src/columnar.h`) |
| Controlled serialization study — [arXiv:2603.03306](https://arxiv.org/abs/2603.03306) | The same compact re-encoding collapses on *nested* data, and the headline savings are measured against pretty-printed JSON — a baseline minified XML already beats. | `--format=columnar` refuses every non-tabular verb with exit 1 instead of degrading quietly; the nested map is never re-encoded |
| Tokenizer and formatting cost — [arXiv:2508.13666](https://arxiv.org/abs/2508.13666) | A single characters-per-token divisor is 20–35% wrong on code, and the spread is dominated by language, not by the tokenizer. | The per-language calibration behind `est_tokens` — and the decision *not* to vendor a byte-pair table, which would buy exactness for the wrong tokenizer |
| AI-generated code smells — [arXiv:2605.02741](https://arxiv.org/abs/2605.02741) | Bloat tracks architectural decay almost perfectly, and the named failure modes are god-class growth, inline re-implementation of existing interfaces, and file separation mistaken for cohesion. | Three of `--quality-delta`'s ten kinds: verbosity, duplication, and reuse-decline (`src/quality.h`) |
| AI-generated code smells — [arXiv:2605.02741](https://arxiv.org/abs/2605.02741) | Bloat tracks architectural decay almost perfectly, and the named failure modes are god-class growth, inline re-implementation of existing interfaces, and file separation mistaken for cohesion. | Three of `--quality-delta`'s eleven kinds: verbosity, duplication, and new-clone-of-reused-helper (`src/quality.h`) |
| Agent-code maintainability — [arXiv:2606.21804](https://arxiv.org/abs/2606.21804) | Classical complexity did not predict real agent-code maintenance failures. Contract drift and code growth did. | The api-surface kind in `--quality-delta`, and `--edit-check` as a standalone contract check (`src/editcheck.h`) |
| Metric feedback into the loop — [arXiv:2505.23953](https://arxiv.org/abs/2505.23953) | Feeding measured complexity back after a failed attempt raised Pass@1 from 12.5% to 35.7%; the oracle has to be re-readable, not just a verdict. | `--quality-delta` reports only what a change made *worse*, itemised, in a form meant to go back into the next prompt |
| ARISE — [arXiv:2605.03117](https://arxiv.org/abs/2605.03117) | Statement-level definition-use edges exposed as a queryable agent primitive lifted Function Recall@1 by 17 points over an unmodified SWE-agent — the graph's granularity floor, not its ranking, was the binding constraint. | `--slice=SYM[:VAR]` and the rung-2 `--slice-flow` (`src/slice.h`) — per-line def/use rows inside one resolved definition, plus the bounded transitive BFS over reaching-definition edges. **Bounded, and the output says so**: name-based, intra-procedural, no alias analysis, no control dependence, disclosed depth truncation; the paper's three-tier graph API remains a design note. The reference implementation is now published ([FARD-Lab/ARISE](https://github.com/FARD-Lab/ARISE), MIT) and was audited line-by-line against this slicer 2026-08-31 — the core reaching-definition rule matches; the divergences (their traversal is seed-variable-filtered and unbounded, ours chains operand variables under a disclosed bound) are recorded in [`EVALS.md`](EVALS.md) |
Expand Down
Loading
Loading