autotrain(continuous-openui-local): L01 unblock doc self-heal version-stamp gate + first two cycles - #1503
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reached
Next review available in: 42 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (13)
📝 WalkthroughWalkthroughThe change adds a staged version-history commit utility and documents two fixture-only ChangesContinuous autotrain evidence
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant self_heal_doc_commit.py
participant GitIndex
participant verify_version_stamps
participant GitCommit
self_heal_doc_commit.py->>GitIndex: Stage version-history entry
self_heal_doc_commit.py->>GitIndex: Read staged paths
self_heal_doc_commit.py->>verify_version_stamps: Validate staged version stamps
verify_version_stamps-->>self_heal_doc_commit.py: Return validation result
self_heal_doc_commit.py->>GitCommit: Commit staged changes
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
docs/MODEL_CARD.md (2)
1-1: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winDuplicate
## Continuous autotrain note (2026-08-08)heading indocs/MODEL_CARD.mdandREADME.md. Both files add two headings with identical text for cycles c1 and c2 on the same day. markdownlint (MD024) flags this in both files, and it also causes anchor-link ambiguity for readers or tools navigating by heading id.
docs/MODEL_CARD.md#L1452-1463: append the cycle id to each heading, e.g.## Continuous autotrain note (2026-08-08, cycle c1)and## Continuous autotrain note (2026-08-08, cycle c2).README.md#L796-807: apply the same cycle-id suffix to its two matching headings.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/MODEL_CARD.md` at line 1, Update the duplicate “Continuous autotrain note (2026-08-08)” headings in both MODEL_CARD.md and README.md to include their cycle identifiers, using “cycle c1” and “cycle c2” respectively. Preserve the existing heading levels and note content while ensuring each heading text is unique.Source: Linters/SAST tools
1452-1463: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winDistinguish the two same-day headings (see consolidated comment).
Lines 1452 and 1458 use the identical heading text
## Continuous autotrain note (2026-08-08)for cycles c1 and c2. This is flagged by markdownlint (MD024) and mirrors the same issue inREADME.md. See the consolidated comment for the proposed fix.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/MODEL_CARD.md` around lines 1452 - 1463, The two continuous autotrain note headings in MODEL_CARD.md must be unique to satisfy MD024. Update each heading to include its cycle identifier, distinguishing c1 from c2 while preserving the existing date and note context.Source: Linters/SAST tools
README.md (1)
796-807: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winDistinguish the two same-day headings (see consolidated comment).
Lines 796 and 802 use the identical heading text
## Continuous autotrain note (2026-08-08)for two different cycles (c1 and c2). This is flagged by markdownlint (MD024) and causes anchor-link ambiguity between the two sections. See the consolidated comment covering this file anddocs/MODEL_CARD.mdfor the proposed fix.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@README.md` around lines 796 - 807, Distinguish the two same-day README headings by making each `## Continuous autotrain note (2026-08-08)` title unique, while preserving the c1 and c2 cycle details under their respective sections and avoiding duplicate Markdown anchors.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.agents/skills/autotrain/scripts/self_heal_doc_commit.py:
- Around line 31-48: Update _bump_component so the inserted JSON entry uses
json.dumps() for the date and note values before f-string interpolation,
producing valid escaped JSON string literals for quotes, backslashes, and other
special characters while preserving the existing text-splicing approach.
- Around line 36-38: Update the history insertion logic around hist_idx and
insert_at to detect when the targeted component’s history array is empty. For an
empty array, set the insertion position immediately after the `"history": [`
marker; otherwise preserve the existing search for the next history-entry `{`,
ensuring the new entry remains within the selected component’s history.
---
Outside diff comments:
In `@docs/MODEL_CARD.md`:
- Line 1: Update the duplicate “Continuous autotrain note (2026-08-08)” headings
in both MODEL_CARD.md and README.md to include their cycle identifiers, using
“cycle c1” and “cycle c2” respectively. Preserve the existing heading levels and
note content while ensuring each heading text is unique.
- Around line 1452-1463: The two continuous autotrain note headings in
MODEL_CARD.md must be unique to satisfy MD024. Update each heading to include
its cycle identifier, distinguishing c1 from c2 while preserving the existing
date and note context.
In `@README.md`:
- Around line 796-807: Distinguish the two same-day README headings by making
each `## Continuous autotrain note (2026-08-08)` title unique, while preserving
the c1 and c2 cycle details under their respective sections and avoiding
duplicate Markdown anchors.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 5031d1aa-d2e1-42e3-b85d-0efcda51bbed
📒 Files selected for processing (8)
.agents/skills/autotrain/scripts/self_heal_doc_commit.pyREADME.mddocs/MODEL_CARD.mddocs/design/continuous-loop-20260808-continuous-openui-local-8c0b60dd-c1-results.jsondocs/design/continuous-loop-20260808-continuous-openui-local-8c0b60dd-c1-results.mddocs/design/continuous-loop-20260808-continuous-openui-local-8c0b60dd-c2-results.jsondocs/design/continuous-loop-20260808-continuous-openui-local-8c0b60dd-c2-results.mdsrc/slm_training/resources/versions.json
| def _bump_component(component_id: str, date: str, note: str) -> bool: | ||
| data = json.loads(VERSIONS.read_text(encoding="utf-8")) | ||
| comp = data["components"][component_id] | ||
| version = comp["version"] | ||
| text = VERSIONS.read_text(encoding="utf-8") | ||
| idx = text.index(f'"{component_id}"') | ||
| hist_idx = text.index('"history": [', idx) | ||
| insert_at = text.index("{", hist_idx) | ||
| entry = ( | ||
| "{\n" | ||
| f' "version": "{version}",\n' | ||
| f' "date": "{date}",\n' | ||
| f' "note": "{note}"\n' | ||
| " },\n " | ||
| ) | ||
| new_text = text[:insert_at] + entry + text[insert_at:] | ||
| VERSIONS.write_text(new_text, encoding="utf-8") | ||
| return True |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🔴 Critical | ⚡ Quick win
Escape note and date before splicing them into the JSON text.
The entry template inserts note and date into a hand-written JSON fragment with plain f-string interpolation. If note or date contains a " or a \, the resulting versions.json becomes invalid JSON. This breaks verify_version_stamps, every test that parses versions.json, and any other tool that reads the registry, for every component, not only the one this script touches. The docstring states this script exists specifically "to avoid reformatting/escaping the whole registry," but the escaping is required for the inserted fragment regardless of whether the rest of the file is rewritten.
Use json.dumps() to produce the escaped string literals for these two fields.
🛡️ Proposed fix to escape inserted string values
entry = (
"{\n"
- f' "version": "{version}",\n'
- f' "date": "{date}",\n'
- f' "note": "{note}"\n'
+ f' "version": {json.dumps(version)},\n'
+ f' "date": {json.dumps(date)},\n'
+ f' "note": {json.dumps(note)}\n'
" },\n "
)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def _bump_component(component_id: str, date: str, note: str) -> bool: | |
| data = json.loads(VERSIONS.read_text(encoding="utf-8")) | |
| comp = data["components"][component_id] | |
| version = comp["version"] | |
| text = VERSIONS.read_text(encoding="utf-8") | |
| idx = text.index(f'"{component_id}"') | |
| hist_idx = text.index('"history": [', idx) | |
| insert_at = text.index("{", hist_idx) | |
| entry = ( | |
| "{\n" | |
| f' "version": "{version}",\n' | |
| f' "date": "{date}",\n' | |
| f' "note": "{note}"\n' | |
| " },\n " | |
| ) | |
| new_text = text[:insert_at] + entry + text[insert_at:] | |
| VERSIONS.write_text(new_text, encoding="utf-8") | |
| return True | |
| def _bump_component(component_id: str, date: str, note: str) -> bool: | |
| data = json.loads(VERSIONS.read_text(encoding="utf-8")) | |
| comp = data["components"][component_id] | |
| version = comp["version"] | |
| text = VERSIONS.read_text(encoding="utf-8") | |
| idx = text.index(f'"{component_id}"') | |
| hist_idx = text.index('"history": [', idx) | |
| insert_at = text.index("{", hist_idx) | |
| entry = ( | |
| "{\n" | |
| f' "version": {json.dumps(version)},\n' | |
| f' "date": {json.dumps(date)},\n' | |
| f' "note": {json.dumps(note)}\n' | |
| " },\n " | |
| ) | |
| new_text = text[:insert_at] + entry + text[insert_at:] | |
| VERSIONS.write_text(new_text, encoding="utf-8") | |
| return True |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.agents/skills/autotrain/scripts/self_heal_doc_commit.py around lines 31 -
48, Update _bump_component so the inserted JSON entry uses json.dumps() for the
date and note values before f-string interpolation, producing valid escaped JSON
string literals for quotes, backslashes, and other special characters while
preserving the existing text-splicing approach.
| idx = text.index(f'"{component_id}"') | ||
| hist_idx = text.index('"history": [', idx) | ||
| insert_at = text.index("{", hist_idx) |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Handle an empty history array before searching for the next {.
insert_at = text.index("{", hist_idx) assumes comp["history"] already has at least one entry. If a component's history is [] (the empty-array case, e.g., a freshly registered component or a future --component target other than the current default), this search skips past the array's own ] and matches an unrelated { belonging to a later component or object in the file. The new entry then gets spliced into the wrong place, corrupting that other component's data and its own semantics, not just formatting.
Check whether history is empty and branch to insert right after "history": [ in that case, instead of unconditionally searching for the next {.
🛡️ Proposed fix to handle an empty history array
comp = data["components"][component_id]
version = comp["version"]
+ history = comp.get("history") or []
text = VERSIONS.read_text(encoding="utf-8")
idx = text.index(f'"{component_id}"')
hist_idx = text.index('"history": [', idx)
- insert_at = text.index("{", hist_idx)
- entry = (
- "{\n"
- f' "version": {json.dumps(version)},\n'
- f' "date": {json.dumps(date)},\n'
- f' "note": {json.dumps(note)}\n'
- " },\n "
- )
+ if history:
+ insert_at = text.index("{", hist_idx)
+ entry = (
+ "{\n"
+ f' "version": {json.dumps(version)},\n'
+ f' "date": {json.dumps(date)},\n'
+ f' "note": {json.dumps(note)}\n'
+ " },\n "
+ )
+ else:
+ insert_at = text.index("]", hist_idx)
+ entry = (
+ "{\n"
+ f' "version": {json.dumps(version)},\n'
+ f' "date": {json.dumps(date)},\n'
+ f' "note": {json.dumps(note)}\n'
+ " }\n "
+ )📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| idx = text.index(f'"{component_id}"') | |
| hist_idx = text.index('"history": [', idx) | |
| insert_at = text.index("{", hist_idx) | |
| comp = data["components"][component_id] | |
| version = comp["version"] | |
| history = comp.get("history") or [] | |
| text = VERSIONS.read_text(encoding="utf-8") | |
| idx = text.index(f'"{component_id}"') | |
| hist_idx = text.index('"history": [', idx) | |
| if history: | |
| insert_at = text.index("{", hist_idx) | |
| entry = ( | |
| "{\n" | |
| f' "version": {json.dumps(version)},\n' | |
| f' "date": {json.dumps(date)},\n' | |
| f' "note": {json.dumps(note)}\n' | |
| " },\n " | |
| ) | |
| else: | |
| insert_at = text.index("]", hist_idx) | |
| entry = ( | |
| "{\n" | |
| f' "version": {json.dumps(version)},\n' | |
| f' "date": {json.dumps(date)},\n' | |
| f' "note": {json.dumps(note)}\n' | |
| " }\n " | |
| ) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.agents/skills/autotrain/scripts/self_heal_doc_commit.py around lines 36 -
38, Update the history insertion logic around hist_idx and insert_at to detect
when the targeted component’s history array is empty. For an empty array, set
the insertion position immediately after the `"history": [` marker; otherwise
preserve the existing search for the next history-entry `{`, ensuring the new
entry remains within the selected component’s history.
…oseouts Continuous loop cycles that touch README.md/MODEL_CARD.md need a matching no-bump version-stamp history entry before the driver's document self-heal commit can land; without it every cycle hard-blocks on the pre-commit hook. This helper inserts the entry via a targeted text splice (not a json.dump rewrite, which reformats/escapes the whole 8k-line registry) and commits.
…t c3 (non-positive)
…t c4 (non-positive)
…t c5 (non-positive)
…t c6 (non-positive)
…t c7 (non-positive)
c9cfae3 to
d97df9e
Compare
Summary
continuous-openui-localsmoke.structural_similarity0.3267 → 0.3828, +0.0561)scripts.verify_version_stamps --checkbecause README.md/MODEL_CARD.md changes require a matching no-bump history entry forharness.experiments.slm228_spectral_disposition. Added.agents/skills/autotrain/scripts/self_heal_doc_commit.py, a small helper that inserts the required history entry via a targeted text splice (not ajson.dumprewrite, which would reformat/escape the entire 8k-line registry) and lands the commit. Replayed identical cycles c1 and c2 afterward — both completed cleanly.docs/design/continuous-loop-20260808-continuous-openui-local-8c0b60dd-c1-results.{md,json},docs/design/continuous-loop-20260808-continuous-openui-local-8c0b60dd-c2-results.{md,json}Why this is positive
Per
autotrain-iteration-delivery.md, this qualifies as executable unblocking: a harness fix removed a hard, reproducing blocker (pre-commit version-stamp gate failure on every continuous document closeout), and the identical arm then completed with a usable scoreboard on replay (c1, then c2 with a primary-metric win).Test plan
scripts.verify_version_stamps --check --stagedpasses for both cycle closeout commitsruff checkon the new helper script passesscripts.run_autotrain_supervisor --loop-id continuous-openui-local --train-version wf_smoke_v2 --steps 20) advances past cycle c1 and c2 without a human re-promptGenerated by Claude Code
Summary by CodeRabbit
New Features
Documentation
Chores