Skip to content

fix: tighten audit rules from RepoPrompt review (itd-85 follow-up) - #66

Merged
REPPL merged 2 commits into
mainfrom
fix/itd-85-audit-review
Jul 13, 2026
Merged

fix: tighten audit rules from RepoPrompt review (itd-85 follow-up)#66
REPPL merged 2 commits into
mainfrom
fix/itd-85-audit-review

Conversation

@REPPL

@REPPL REPPL commented Jul 13, 2026

Copy link
Copy Markdown
Owner

What

Follow-up to the itd-85 abcd audit work (merged as #59#65), applying the three clear correctness fixes an independent RepoPrompt oracle review surfaced. Each is test-first.

  1. Tier/router checks accepted the wrong file type. three-tier-layout and conventions-router used fsutil.Exists, which follows symlinks and accepts any type — so a regular file at .abcd/development / .abcd/work, or a directory named AGENTS.md, satisfied the rule. Tiers now require a directory (IsDir); the router now requires a non-directory.
  2. docs-currency silently passed when it could not run. With docs/ present but .abcd/docs-lint.json missing, it returned no findings — a check that cannot run reading as clean. It now emits a warn naming the gap, consistent with the engine's fail-closed stance elsewhere.
  3. JSON skipped key vanished when empty. Result.Skipped had omitempty, contradicting the command doc's { findings, skipped } shape. It is now an always-present array, guarded nil→[] in the serializer like findings.

Not changed (accurate findings, but deliberate)

The oracle also flagged, and I confirmed as by-design / documented: the privacy regex's precision-over-recall scope (misses /Users/alice with no trailing separator — also flagged by the earlier security review), the fail-open behaviour when git can't enumerate tracked files, and the unix-only build constraint (repo targets darwin/linux). The "presence vs tracked-durability" strictness point is a spec-interpretation the M3 review already settled on the looser reading; left as-is.

  1. A tier that is a file aborted the audit (found while verifying fix feat: harness-name prevention gate + name-banlist intent (itd-74) #1). With .abcd/work a regular file, decision-durability stats .abcd/work/DECISIONS.md, which returned ENOTDIR; fsutil.Exists propagated it and Evaluate aborted with a path-bearing stat error before three-tier could report the violation — so fix feat: harness-name prevention gate + name-banlist intent (itd-74) #1 silently no-op'd for the work tier specifically. fsutil.Exists/IsDir/DirHasEntries now treat ENOTDIR (a file in the path prefix) the same as ErrNotExist: the path cannot exist, so "not present" is the correct answer, not a fault to abort on. General correctness fix to the shared primitive (lint uses it too, same semantics).

Notes

  • TestAC_PrivacyWaiverSuppresses's fixture was moved out of docs/ so fix docs: acknowledgements, AI-attribution policy, badge fix #3's new warn doesn't perturb the exit code it asserts — it isolates the privacy-waiver behaviour, no coverage lost.
  • The rule_layout comment is corrected: IsDir follows symlinks, so a symlink-to-directory does satisfy a tier — acceptable for a layout check (not the owned-store trust boundary).

Each fix has a watched-fail-then-pass test; abcd audit still exits 0 on this repo; preflight clean. Correctness review of the first three fixes: PROMOTE (its two NOTES are both resolved by fix #4 and the comment correction).

Assisted-by: Claude:claude-opus-4-8

REPPL added 2 commits July 13, 2026 21:12
An independent RepoPrompt oracle review of the merged itd-85 work surfaced three
clear correctness gaps, each fixed here test-first:

- three-tier-layout and conventions-router used fsutil.Exists, which accepts any
  file type — a regular file at .abcd/development or .abcd/work, or a directory
  named AGENTS.md, satisfied the rule. They now require a directory for the tiers
  and a non-directory for the router.
- docs-currency silently passed when docs/ exists but .abcd/docs-lint.json is
  missing — a check that could not run reading as clean. It now emits a warn
  naming the gap, consistent with the engine's fail-closed stance elsewhere.
- the audit JSON omitted the "skipped" key when empty (omitempty), contradicting
  the command doc's { findings, skipped } shape. It is now an always-present
  array, guarded nil->[] in the serializer like findings.

Each fix has a watched-fail-then-pass test. abcd audit still exits 0 on this
repo; preflight clean.

Assisted-by: Claude:claude-opus-4-8
Completes the tier-type hardening: with the IsDir change, a repo whose
.abcd/work is a regular file should report the layout violation — but
decision-durability stats .abcd/work/DECISIONS.md first, which returned ENOTDIR
(a file in the path prefix), and fsutil.Exists propagated it, so Evaluate
aborted before three-tier could report. The audit errored out with a
path-bearing stat message instead of naming the violation.

fsutil.Exists/IsDir/DirHasEntries now treat ENOTDIR the same as ErrNotExist:
a path whose parent component is a file cannot exist, so "not present" is the
correct answer, not a fault a fail-closed caller should abort on. This is a
general correctness fix to the shared primitive (lint uses it too, where the
same semantics are right).

Watched-fail-then-pass tests: the fsutil ENOTDIR case, and the audit case where
.abcd/work is a file now surfaces the three-tier finding instead of aborting.
Also corrects the rule_layout comment: IsDir follows symlinks, so a
symlink-to-directory does satisfy a tier (fine for a layout check).

Assisted-by: Claude:claude-opus-4-8
@REPPL
REPPL merged commit a9b58cd into main Jul 13, 2026
12 checks passed
@REPPL
REPPL deleted the fix/itd-85-audit-review branch July 13, 2026 20:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant