From rtl-agent-team
Auto-loop wrapper that repeats rtl-ppa-optimize-dc until PPA convergence or plateau. Drives DC-based PPA optimization loop with termination tiers.
How this skill is triggered — by the user, by Claude, or both
Slash command
/rtl-agent-team:rat-ultraloop-ppa [top-module-name][top-module-name]This skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
<Purpose>
<Use_When>
<Do_Not_Use_When>
/rtl-agent-team:rat-ultraloop-ppa [top_module]
import json, time, shutil, subprocess, pathlib
TOP = ARGUMENTS or json.load(open("requirements.json"))["top_module"]
# Hard preconditions
assert shutil.which("dc_shell") or shutil.which("genus"), \
"rat-ultraloop-ppa requires dc_shell or genus in PATH"
req = json.load(open("requirements.json"))
assert "ppa_targets" in req, \
"requirements.json missing ppa_targets — run rtl-ppa-optimize-dc once to scaffold"
max_cycles = int(req["ppa_targets"].get("convergence", {}).get("max_cycles", 4))
# Initialize state
state_path = pathlib.Path(".rat/state/ppa-loop-state.json")
if not state_path.exists():
state = {
"mode": "ppa-loop",
"cycle": 0,
"max_cycles": max_cycles,
"weights": req["ppa_targets"].get("weights", {"timing":0.7, "power":0.2, "area":0.1}),
"convergence": {
"delta_pct": req["ppa_targets"].get("convergence", {}).get("delta_pct", 2.0),
"streak_required": req["ppa_targets"].get("convergence", {}).get("streak", 3),
"early_plateau_pct": req["ppa_targets"].get("convergence", {}).get("early_plateau_pct", 1.0),
"history": [],
},
"allowed_edit_scope": [f"rtl/{TOP}/**/*.sv"],
"frozen_scope": ["rtl/common/**", "rtl/pkg/**", "rtl/intf/**"],
"last_cycle_timestamp": int(time.time()),
"auto_continue_minutes": 30,
}
state_path.parent.mkdir(parents=True, exist_ok=True)
state_path.write_text(json.dumps(state, indent=2))
# The LLM executes the following iterative protocol. The block below is
# CONCEPTUAL pseudo-code (Skill() is not a callable Python function) —
# the real mechanism is a slash-command invocation followed by reading
# the verdict file that the orchestrator writes.
For each cycle in 1..max_cycles:
/rtl-agent-team:rtl-ppa-optimize-dc <TOP>.
This runs exactly one PPA iteration via the orchestrator, which writes
docs/ppa-opt/iter-{cycle}/verdict.txt on completion.1a. Refresh auto-continue timestamp — update last_cycle_timestamp in
.rat/state/ppa-loop-state.json to the current epoch seconds BEFORE
invoking rtl-ppa-optimize-dc. This ensures the 30-minute
stop-gate.sh window restarts each cycle, not only at loop start.
```python
import json, time, pathlib, os, tempfile, fcntl
STATE_PATH = pathlib.Path(".rat/state/ppa-loop-state.json")
LOCK_PATH = str(STATE_PATH) + ".lock"
with open(LOCK_PATH, "a") as lock_f: # long-lived lock file; never replaced
fcntl.flock(lock_f.fileno(), fcntl.LOCK_EX)
try:
s = json.loads(STATE_PATH.read_text())
s["last_cycle_timestamp"] = int(time.time())
dir_ = STATE_PATH.parent
fd, tmp = tempfile.mkstemp(prefix=".ppa-state-", dir=str(dir_))
try:
with os.fdopen(fd, "w") as tmp_f:
json.dump(s, tmp_f, indent=2)
os.replace(tmp, str(STATE_PATH)) # atomic swap
except BaseException:
try:
os.unlink(tmp)
except OSError:
pass
raise
finally:
fcntl.flock(lock_f.fileno(), fcntl.LOCK_UN)
```
Uses the same atomic lock-file + `os.replace()` pattern as `compute_delta.py`:
a `.lock` file is held via `fcntl.flock` during the read-modify-write cycle,
and the updated state is written to a temp file then atomically renamed
onto the canonical path. This prevents `stop-gate.sh` from observing a
truncated state file between steps.
2. Read verdict — read docs/ppa-opt/iter-{cycle}/verdict.txt. Expected
values: CONTINUE, CONVERGED_STREAK, CONVERGED_TARGETS, EARLY_PLATEAU,
MAX_CYCLES, TIMING_REGRESSION. If verdict.txt is ABSENT, the
orchestrator hard-halted on an equivalence or smoke-regression FAIL before
writing a verdict — handle via the "Missing verdict.txt" branch in step 3.
Dispatch by verdict:
CONVERGED_STREAK or CONVERGED_TARGETS:
/rtl-agent-team:rtl-p5-verify for a full final regression
confirmation. Pass the run intent as the free-text argument, e.g.
final regression (source: ppa-opt) — rtl-p5-verify forwards its
argument to the P5 orchestrator verbatim (it does NOT parse
--mode/--source flags)..rat/state/rtl-verify-done with ppa-opt-converge cycle {cycle}\n..rat/state/ppa-opt-done with converge cycle {cycle}\n (triggers
P6 cascade re-review if the design-note was written prior).docs/ppa-opt/final-report.md (see template below)..rat/state/ppa-loop-state.json.EARLY_PLATEAU:
reviews/ppa-opt/early-plateau-escalation.md..rat/state/ppa-loop-state.json.MAX_CYCLES:
docs/ppa-opt/final-report.md with exit_reason MAX_CYCLES
(best-so-far iteration recorded)..rat/state/ppa-loop-state.json.TIMING_REGRESSION:
git checkout -- rtl/<top>,
wrote TIMING_REGRESSION to verdict.txt, and removed
.rat/state/ppa-loop-state.json (its Rollback Cleanup Protocol).reviews/ppa-opt/timing-regression-escalation.md..rat/state/ppa-loop-state.json (idempotent — orchestrator
already removed it).Missing verdict.txt (orchestrator hard-halted on an equivalence or
smoke-regression FAIL — see reviews/ppa-opt/{equiv,smoke}-fail-iter-{cycle}.md):
.rat/state/ppa-loop-state.json (Rollback Cleanup Protocol); the
one-shot skill's terminal cleanup does the same.reviews/ppa-opt/rollback-halt-escalation.md summarizing the
failing check and the rolled-back iteration.rm -f .rat/state/ppa-loop-state.json.CONTINUE:
Safety net — if the loop falls through max_cycles without a terminal
verdict (should not happen), generate final-report with exit_reason
LOOP_EXIT_UNEXPECTED and remove the state file.
Note: The per-cycle refresh of
last_cycle_timestamp(step 1a) is critical:stop-gate.shuses it to decide whether the 30-min auto-continue window is still active. Without it, long DC iterations would be interrupted 30 minutes after loop start even when the loop is making progress.
docs/ppa-opt/final-report.md)# PPA Optimization Final Report
- Target module: {TOP}
- Cycles executed: {N} / {max_cycles}
- Exit reason: CONVERGED | EARLY_PLATEAU | MAX_CYCLES
## Iteration history
| iter | wns_ns | power_mw | area_um2 | weighted_Δ |
## Best-so-far iteration
- iter: {best_iter}
- wns_ns: {} power_mw: {} area_um2: {}
## Next steps
- If CONVERGED: full Phase 5 regression passed → proceed to Phase 6 design note
- If EARLY_PLATEAU: see reviews/ppa-opt/early-plateau-escalation.md
- If MAX_CYCLES: consider raising max_cycles in requirements.json["ppa_targets"]["convergence"]
Reuses the stop-gate.sh escalation pattern: when
.rat/state/ppa-loop-state.json is present with mode == "ppa-loop" and
last_cycle_timestamp + auto_continue_minutes*60 > now, the hook auto-continues
instead of stopping.
npx claudepluginhub babyworm/rtl-agent-team --plugin rtl-agent-teamExecutes one iteration of DC synthesis PPA optimization loop with equivalence and smoke validation. Requires dc_shell/genus and Phase 5 PASS.
Guides iterative development loops with recurring verification gates, completion evidence, and pause/abort markers. Ensures code changes pass a user-defined verify command before acceptance.
Executes tasks in a loop with defined goals, max iterations, and success criteria. Useful for iterative refinement, polling, or convergence workflows.