Skip to content

fix(ai-slop): emit a parseable ISO-8601 date, and close three precision gaps found in post-merge verification - #3097

Merged
kyle-sexton merged 2 commits into
mainfrom
claude/ai-slop-followup-corrections
Aug 21, 2026
Merged

fix(ai-slop): emit a parseable ISO-8601 date, and close three precision gaps found in post-merge verification#3097
kyle-sexton merged 2 commits into
mainfrom
claude/ai-slop-followup-corrections

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

No linked issue.

Summary

Four independent corrections, each found by an adversarial verification pass on a merged PR (#3063, #3068) rather than by review of this diff. One is a real defect in emitted output; three are precision gaps in prose that describes behavior accurately elsewhere.

Nothing here changes routing, classification, or what any detector rule fires on.

Fix

1 — the findings emitter wrote a timestamp nothing can parse. emit-findings.sh used %Y-%m-%dT%H-%M-%SZ, producing date: 2026-08-21T13-36-00Z — hyphens where ISO-8601 needs colons in the time portion. The consumer (fix-pass-mode.md Step 1) classes an unparseable date: as UNREADABLE and fails open, so it cost one extra pass and dropped nothing; the staleness check simply degraded silently.

Measured by running both emitters and parsing the output with a real parser, not by reading the format string:

MAIN    date: 2026-08-21T13-36-00Z   fromisoformat -> ValueError
BRANCH  date: 2026-08-21T13:36:00Z   fromisoformat -> datetime(2026,8,21,13,36, tzinfo=UTC)

The bug was guarded by a passing test. detect.test.sh asserted T[0-9]{2}-[0-9]{2}-[0-9]{2}Z under the name "emit: colon-free UTC date", and main's suite was green with the bug. The replacement is discriminating — run against main's emitter it fails exactly one case:

FAIL: emit: ISO-8601 extended UTC date
  expected: YYYY-MM-DDThh:mm:ssZ
  actual:   date: 2026-08-21T13-37-13Z

Neither pattern matches both forms.

Colons rather than the ISO basic form because the field's owner, default-mode.md "Findings-writer contract", binds colon-free to the file name (TS="$(date -u +%Y%m%dT%H%M%SZ)" # colon-free, Windows-safe, used as ${TS}-<topic>.md) while its findings-file shape asks for date: <ISO-8601 UTC> three lines below. The strongest corroboration is that a sibling adopter already does it: testing:audit's cant-fail-scan.sh emits %Y-%m-%dT%H:%M:%SZ for the same type: review-findings frontmatter. ai-slop was the outlier.

2 — the cleanup route described as /simplify-only. Step 4 actually reads: "Invoke the /simplify skill when available in the session; otherwise apply the cleanup findings directly, one file at a time." Two live passages omitted the second branch. Both now name it, and say why the Auto-applicable cell reaches neither: on the /simplify branch no consumer reads it, and on the direct-apply branch the fence is the file, not auto-applicability. The conclusion was never at risk — a No cell cannot restrain the cleanup route under either branch — so this is precision, not a behavior change.

Two further occurrences are deliberately left as written. docs/conventions/detector-findings/CHANGELOG.md and plugins/review/CHANGELOG.md are published entries for released versions. They record what was written at the time; the correction is a closing note in the new 2.4.1 entry naming both locations, not an edit to history.

3 — an unqualified fence sentence. The contract said "Step 4 owns the criterion — a fix is auto-applied only when it is contained…", reading as an unconditional rule, while the surrounding text establishes it binds the correctness class only. Now scoped explicitly, with the class-independent half (settle it once per rule in the crosswalk) preserved verbatim.

Pre-existing, and proven so rather than asserted — it entered with the crosswalk in #2737 on 2026-08-15, six days before #3068:

$ git log -S'"Step 4" owns the criterion' -- docs/conventions/detector-findings/README.md
c8470efd  2026-08-15  docs(conventions): harden detector-findings with the rule-id to severity crosswalk (#2737)

4 — ai-slop eval case 2 lacked the tracked-file premise its siblings carry. It grades findings-file re-emission, which SKILL.md step 5 gates on the audit having "examined tracked files", but carried no premise — while cases 4 and 5 both do. Case 2 now carries the sibling sentence verbatim, and its expectation mirrors case 5's discriminating form, so a run that rewrites and re-runs but persists nothing no longer passes.

The fix flow's re-emit wording is left alone, and the entry records the question as open rather than settled. An earlier revision of the 0.3.3 entry argued the two conditions were equivalent because the audit's default target is the repo's tracked markdown. That argument does not hold: step 1 scopes that default to the empty-target branch, and every eval case passes a path argument. Cases 4 and 5 also word tracked-ness as gating, which an inert precondition would not need. The eval gap is real under either reading and stays fixed; the wording question is named, with the seam identified (context/persist-findings.md, not the fix flow), rather than closed by an argument the cited text does not support.

Verification

Gate Result
Emitter run, before/after, real ISO-8601 parser ValueError → tz-aware UTC instant
Branch test body vs main's emitter output fails exactly 1 of 92 — discriminating
detect.test.sh all 92 cases passed
check-detector-findings-crosswalk.sh --check + self-test PASS — 22 rule rows
check-changelog-parity.sh --check / --check-bump / --check-order / --check-preserved PASS — 83 changelogs; 16 headings preserved
check-changed-skills.sh PASS — 0 errors (2 warnings pre-existing, untouched files)
check-silent-revert.sh ok
check-evals-quality.sh + check-jsonschema PASS — 0 warnings
shellcheck, check-shell-portability.sh clean
markdownlint-cli2 on every changed file 0 issues
plugins/review/ tree hash vs main byte-identical — no bump needed there
detect.sh / fixtures/ / reference/ / context/ subtree hashes identical to base — no rule, ERE, threshold or fixture moved

The findings-file name is unaffected: DATE_UTC appears only in the frontmatter path, while the name is composed separately per persist-findings.md's own colon-free %Y%m%dT%H%M%SZ.

Related

Versions: ai-slop0.3.3 (main already ships 0.3.2, so 0.3.2 was unavailable). detector-findings2.4.1, argued as patch against the contract's own rule: major is a producer-owned field's rule or an enforceability verdict, minor is additive guidance or a new adopter row. Items 2 and 3 move none of those — the Auto-applicable obligation is preserved verbatim and nothing a producer emits or a consumer parses differs.

Adjacent, pre-existing, not fixed here

plugins/overengineering/context/findings-artifact.md specifies a frontmatter date: as "Colon-free UTC, Windows-safe, lexically sortable" — Windows-safety is a filename property and is meaningless for a frontmatter field. That artifact is a different type with a different consumer and is not a detector-findings adopter, so nothing here contradicts it, but after this PR it is the last surviving instance of the class item 1 fixed. Separately, cant-fail-scan.test.sh asserts only "date: 20", which would pass against the hyphenated bug exactly as ai-slop's guard did; that producer's emitter is already correct, so nothing is broken, but the guard has the same non-discriminating shape.

…up route, correctness-scoped fence

Four verified corrections to what #3063 and #3068 shipped. No detector rule,
no producer-owned field, and no consumer route changes behavior.

emit-findings.sh stamped `date:` with `%Y-%m-%dT%H-%M-%SZ` — an extended-form
date joined to a hyphenated time, which is ISO-8601 in neither the extended nor
the basic profile. fix-pass-mode.md "Step 1" reads that field only when it is a
full ISO-8601 date-time with an explicit UTC designator, so every emitted file
was classed UNREADABLE. Every clause on that path fails open, so nothing was
dropped, but Step 4's cleanup-route staleness note degraded silently. The unit
suite had pinned the malformed shape under the name "colon-free UTC date"; the
colon-free rule belongs to the FILE NAME (Windows-safe), never this field.

The relay's cleanup route has two branches — /simplify when available in the
session, otherwise the cleanup findings applied directly, one file at a time.
Two live documents described it as /simplify-only: the contract's
`Auto-applicable: No` bullet and ai-slop's Purpose section. Both conclusions are
unchanged and were never at risk (a `No` cell restrains neither branch), so this
is a precision fix to rationale. The same description in the 2.4.0 and
plugins/review published changelog entries is left as written; the correction is
noted in the new 2.4.1 entry instead.

"Auto-applicability is settled per rule" opened with an unqualified fence, while
its own neighbours and the Declared-dispositions table establish that Step 4
states that fence under its correctness-class heading. Pre-existing since #2737
(2026-08-15); #3068 only put a passage beside it that made the tension legible.
Scoped to the correctness class.

Eval case 2 graded the persistence step without the tracked-file premise its two
siblings carry for that exact purpose (0.3.0 established the pattern: a case
cannot verify real repository state). The fix flow's unconditional re-emit
wording was checked and deliberately left alone — persist-findings.md's
enumerated write conditions do not include tracked-ness, so step 5's clause is
the audit flow's phrasing of "nothing scanned, write nothing", which a fix pass
always satisfies.

plugins/ai-slop 0.3.2 -> 0.3.3; detector-findings 2.4.0 -> 2.4.1 (patch:
docs-only clarification under the contract's own rule). plugins/review needs no
bump — nothing under it changed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AqwX2njhiLMWGrMg3QNt4g
@claude

claude Bot commented Aug 21, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 42s —— View job


Security review complete

  • Gather context (PR diff, changed files)
  • Apply skip gate check
  • Review diff for security-relevant surface
  • Post findings (or none)

No security issues found.

This PR is documentation and precision-correction only, plus one shell-script fix:

  • docs/conventions/detector-findings/{CHANGELOG,README}.md, plugins/ai-slop/CHANGELOG.md, plugins/ai-slop/skills/audit/SKILL.md, plugins/ai-slop/skills/audit/evals/evals.json, plugins/ai-slop/.claude-plugin/plugin.json — prose corrections, changelog entries, eval prompt wording, and a version bump. No code path changes.
  • plugins/ai-slop/skills/audit/scripts/emit-findings.sh — changes the emitted date: timestamp format from %Y-%m-%dT%H-%M-%SZ to %Y-%m-%dT%H:%M:%SZ (colons instead of hyphens in the time portion) so it's valid ISO-8601. Still built from date -u, no external input reaches this string.
  • plugins/ai-slop/skills/audit/scripts/detect.test.sh — test assertion updated to match the corrected date format.

No authentication, authorization, injection surfaces, secret/token handling, or GitHub Actions workflow permissions are touched. Skip-gate condition 2 applies (no security-relevant surface after reading the diff) — nothing further to report.

@claude

claude Bot commented Aug 21, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 2m 38s —— View job


Code review complete ✅

  • Gather context (PR body, diff, changed files)
  • Invoke /review:code-review per repo instructions
  • Post inline comments for any findings
  • Summarize results in this comment

Lane scope: this repo carries .github/workflows/claude-security-review.yml, so this lane is scoped to correctness/design/conventions/tests/docs only (per REVIEW.md); security is left to that lane and none was found here regardless.

Findings

None. No inline comments posted.

What I checked

This PR is four precision corrections (three prose, one real emitter bug), all narrowly scoped and self-documenting. I independently verified rather than restating the PR's own claims:

  • emit-findings.sh date format (L113): confirmed DATE_UTC is used only for the frontmatter date: field via the awk call, not for the output file name (which stays caller-resolved and untouched by this change) — so the fix doesn't collide with the genuinely colon-free Windows-safe filename convention elsewhere in the repo.
  • detect.test.sh assertion update (L450): now pins the colon-bearing extended form, consistent with the emitter fix.
  • Two-branch cleanup route claim: read plugins/review/skills/fanout/context/fix-pass-mode.md directly — line 157 is exactly "Invoke the /simplify skill when available in the session; otherwise apply the cleanup findings directly, one file at a time." Confirms the SKILL.md, README.md, and CHANGELOG.md corrections describe the real two-branch behavior rather than the old /simplify-only description.
  • Correctness-class scoping claim: confirmed in the same file (Step 4, lines 137–143) that the auto-apply fence ("contained to its Location, high-confidence, and not a call for architectural judgment") sits under the correctness-class subheading specifically, supporting the README.md scoping correction.
  • Eval case 2 premise addition: consistent with the stated premise pattern already used in cases 4 and 5 of evals.json.
  • Version bumps: confirmed against origin/mainai-slop plugin.json is 0.3.2 on main (bump to 0.3.3 is correct, non-colliding), and detector-findings/CHANGELOG.md latest entry on main is 2.4.0 (new 2.4.1 patch entry is correctly incremented and matches the docs-only-clarification = patch rule the changelog itself states).

Verification limitations

This lane's sandbox does not permit running gh or executing the shell scripts/test suite directly (bash detect.test.sh, etc. all required approval that wasn't grantable non-interactively). I verified the logic by static reading of the actual source files rather than by execution. The PR body's own test-run output, shellcheck, markdownlint-cli2, and check-* gate results are author-claimed and unverified by me.

@github-actions

Copy link
Copy Markdown

Last security-reviewed head: f3c02d56203b0caf77b2e6935210db4176d312e0. On the next push, the relevance gate compares only the commits since this SHA; delete this comment to force a full re-review.

@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown

Claude has reviewed this PR 2 times. The lane skips further automatic reviews after 5; deleting this comment resets the count.

The 0.3.3 entry asserted that step 5's "examined tracked files" gate and
persist-findings.md's "nothing scanned" condition are the same, on the grounds
that the audit's default target is the repo's tracked markdown. Step 1 scopes
that default to the empty-target branch, and every eval case passes a path
argument, so the premise does not reach the cases it was offered for. Cases 4
and 5 also word tracked-ness as gating, which an inert precondition would not
need.

The eval gap is settled either way and stays fixed. The wording question is
recorded as open, with the seam named, rather than closed by an argument the
cited text does not support — a published entry is one this repo declines to
edit later, so it should not carry a resolution it has not earned.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@claude

claude Bot commented Aug 21, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 2m 20s —— View job


Code review complete

Lane scope: this repo carries .github/workflows/claude-security-review.yml, so this lane is scoped to correctness/design/conventions/tests/docs; security is left to that lane.

  • Gather context (PR diff via git diff e501521..HEAD, matches the stated +118/-20 across 8 files)
  • Invoke /review:code-review per repo instructions
  • Post inline comments for any findings
  • Summarize results in this comment

Findings

None. No inline comments posted.

What I checked

This PR is four precision corrections (one real emitter bug, three prose-precision fixes). Rather than restate the PR's own claims, I independently re-derived each one against the cited source files:

  • emit-findings.sh date fix (plugins/ai-slop/skills/audit/scripts/emit-findings.sh line 113): confirmed fix-pass-mode.md line 30 — "A value is readable only if it is a full ISO-8601 date-time carrying an explicit UTC designator (Z) or a numeric offset... anything unparsable is UNREADABLE" — and line 34, confirming an unreadable date: fails open (candidate stays, cost is one extra pass). %H-%M-%SZ%H:%M:%SZ is the correct fix; the colon-free rule elsewhere in the same file (line 176) is scoped to the file NAME, not this field, so no collision.
  • detect.test.sh assertion: now pins the colon-bearing extended form, consistent with the emitter.
  • Two-branch cleanup route claim: verified fix-pass-mode.md line 157 reads exactly "Invoke the /simplify skill when available in the session; otherwise apply the cleanup findings directly, one file at a time." — confirms the SKILL.md/README.md/CHANGELOG.md corrections describe real behavior, and confirms plugins/review/CHANGELOG.md:100 and detector-findings/CHANGELOG.md:79 still carry the old one-branch description, exactly as the PR says was deliberately left alone.
  • Correctness-class scoping claim: verified fix-pass-mode.md line 143 (the "contained to Location, high-confidence, not architectural judgment" fence) sits under the ### Correctness-class heading at line 137 — supports the README.md scoping correction.
  • Eval case 2 premise: the added prompt clause ("Treat the audited file as tracked in the repo under audit") and expectation wording ("on the stated premise that the audited file is tracked") match cases 4 and 5's phrasing verbatim (evals.json lines 47, 55, 61, 68), and SKILL.md:62 confirms the gate this premise satisfies ("whenever the audit examined tracked files"). persist-findings.md lines 69-72 confirm tracked-ness is genuinely absent from the file-is-written enumeration, supporting the PR's decision to leave the fix-flow re-emit wording alone.
  • Version bumps: ai-slop 0.3.2 → 0.3.3 in plugin.json matches the new plugins/ai-slop/CHANGELOG.md [0.3.3] entry; detector-findings 2.4.0 → 2.4.1 is consistent with the contract's own patch/minor/major rule stated at the top of its CHANGELOG (docs-only clarification = patch, no producer-owned field or enforceability verdict changed).
  • evals.json diff is structurally valid JSON (checked by reading the full array — braces/commas balanced, no truncation).

No correctness, convention, or test-coverage issues found. The diff does exactly what the PR body describes, and every cross-file claim in the body checks out against the actual current text of the referenced files.

@kyle-sexton
kyle-sexton merged commit c5ad0c6 into main Aug 21, 2026
52 checks passed
@kyle-sexton
kyle-sexton deleted the claude/ai-slop-followup-corrections branch August 21, 2026 14:00
kyle-sexton added a commit that referenced this pull request Aug 21, 2026
…3100)

## Summary

Compress the session-flow handoff instruction walk (`save-point.md`,
`structure.md`, `skills/handoff/SKILL.md`) under docs-hygiene
flavor-only discipline. Re-review the Stop-hook escalation from #3018;
no defect found, hook not shipped.

## Fix

Author-time compression of the three named files: drop filler and
verbose verbs that do not carry contract meaning. Preserve find-handoff
detection contract (rails, copy instruction, `Read @…-handoff-…`
directive, `Re-arm <i> of <n> — <L> lines:`), redaction rules,
rooted-path / `Handoff origin:` rationale, and STOP / output-order
contract. Bump session-flow 0.32.2 → 0.32.3. Stop-hook re-review: 0.26.1
already shipped the STOP/output-order contract; one observed occurrence;
find-handoff rung 1 still recovers file-mode; the 0.22% cut does not
change occupancy. No hook change.

## Test plan

- [x] `markdownlint-cli2` on the three compressed files + CHANGELOG: 0
issues
- [x] `scripts/changelog-parity.sh --check --check-bump origin/main
--check-order --check-preserved origin/main`
- [x] Contract tokens remain: rails, copy instruction, Read
@…-handoff-…, Re-arm header, redaction markers, STOP / output-order
- [x] Byte delta vs author-time snapshots: 188 B / 0.22% (save-point 152
B, structure 27 B, SKILL 9 B)

## Verification

- `markdownlint-cli2` on the three files + CHANGELOG: 0 issues.
- Changelog-parity `--check`, `--check-bump origin/main`,
`--check-order`, `--check-preserved origin/main`: all pass.
- Contract-token grep: rails, copy instruction, `Read @…-handoff-…`,
`Re-arm <i> of <n> — <L> lines:`, redaction markers, STOP / output-order
all still present.
- Byte savings vs `/tmp/wt-3018-snap`: save-point 40831→40679 (152 B),
structure 23296→23269 (27 B), SKILL 19641→19632 (9 B); total 188 B /
0.22%.

## Related

- Closes #3018
- Follows #3097 / #3098 / #3099
- Stop-hook re-review; no defect — hook not shipped

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
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.

2 participants