simplicio-loop 3.15.0__tar.gz → 3.18.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {simplicio_loop-3.15.0/simplicio_loop.egg-info → simplicio_loop-3.18.1}/PKG-INFO +1 -1
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/pyproject.toml +1 -1
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/hooks/loop_stop.py +129 -21
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/skills/simplicio-loop/SKILL.md +1 -1
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/skills/simplicio-review/SKILL.md +5 -5
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/skills/simplicio-tasks/SKILL.md +13 -4
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/skills/simplicio-tasks/references/orchestration.md +38 -13
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/skills/simplicio-tasks/references/quality-safety-delivery.md +8 -6
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1/simplicio_loop.egg-info}/PKG-INFO +1 -1
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/LICENSE +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/MANIFEST.in +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/PYPI.md +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/README.md +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/setup.cfg +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/__init__.py +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/hooks/README.md +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/hooks/action_gate.py +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/hooks/hooks.claude.json +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/hooks/hooks.json +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/hooks/learn_stop.py +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/hooks/loop_capture.py +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/hooks/orient_clamp.py +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/hooks/orient_rewrite.py +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/hooks/simplicio_dashboard.py +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/hooks/simplicio_watch.py +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/skills/simplicio-compress/SKILL.md +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/skills/simplicio-learn/SKILL.md +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/skills/simplicio-orient/SKILL.md +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/skills/simplicio-tasks/references/agentsview-adapter.md +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/skills/simplicio-tasks/references/azure-devops-adapter.md +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/skills/simplicio-tasks/references/extension-points.md +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/skills/simplicio-tasks/references/lmcache-adapter.md +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/skills/simplicio-tasks/references/standing-loop-247.md +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/skills/simplicio-tasks/references/token-capture.md +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/skills/simplicio-tasks/references/token-economy.md +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/skills/simplicio-tasks/references/understand-anything-adapter.md +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/skills/simplicio-tasks/references/video-evidence.md +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/skills/simplicio-tasks/references/web-evidence.md +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/cli.py +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop.egg-info/SOURCES.txt +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop.egg-info/dependency_links.txt +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop.egg-info/entry_points.txt +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop.egg-info/requires.txt +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop.egg-info/top_level.txt +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/tests/test_action_gate.py +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/tests/test_flow_audit.py +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/tests/test_impact_audit.py +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/tests/test_loop_e2e.py +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/tests/test_worker_selftests.py +0 -0
- {simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/tests/test_worker_smoke.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: simplicio-loop
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.18.1
|
|
4
4
|
Summary: The Universal Looping AI Orchestrator — a runtime-agnostic super-plugin (6 skills) that drains any queue of work end-to-end on any LLM/runtime.
|
|
5
5
|
Author-email: Wesley Simplicio <wesleybob4@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "simplicio-loop"
|
|
7
|
-
version = "3.
|
|
7
|
+
version = "3.18.1"
|
|
8
8
|
description = "The Universal Looping AI Orchestrator — a runtime-agnostic super-plugin (6 skills) that drains any queue of work end-to-end on any LLM/runtime."
|
|
9
9
|
readme = "PYPI.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -11,17 +11,26 @@ hook must never trap the agent in an endless loop. The real guards are the
|
|
|
11
11
|
|
|
12
12
|
State (single source of truth): .orchestrator/loop/scratchpad.md (+ sibling `done` flag)
|
|
13
13
|
Reads stdin JSON from the host (Claude: {transcript_path,...}; Cursor: {text,...}).
|
|
14
|
+
|
|
15
|
+
Cross-agent handoff: an INCOMPLETE stop (budget halted, iteration cap, manual STOP
|
|
16
|
+
signal) writes `.orchestrator/loop/HANDOFF.md` before clearing the scratchpad, so a
|
|
17
|
+
different agent/runtime picking up this repo cold — because the first one ran out of
|
|
18
|
+
budget — can resume without re-deriving the goal, the verified acceptance criteria, or
|
|
19
|
+
the dead-end attempts. A successful (promise-fulfilled) stop needs no handoff.
|
|
14
20
|
"""
|
|
15
21
|
import json
|
|
16
22
|
import os
|
|
17
23
|
import re
|
|
18
24
|
import sys
|
|
25
|
+
import time
|
|
19
26
|
|
|
20
27
|
LOOP_DIR = os.path.join(".orchestrator", "loop")
|
|
21
28
|
SCRATCHPAD = os.path.join(LOOP_DIR, "scratchpad.md")
|
|
22
29
|
DONE_FLAG = os.path.join(LOOP_DIR, "done")
|
|
23
30
|
LAST_RESP = os.path.join(LOOP_DIR, "last_response.txt")
|
|
24
31
|
ANCHOR = os.path.join(LOOP_DIR, "anchor.json")
|
|
32
|
+
JOURNAL = os.path.join(LOOP_DIR, "journal.jsonl")
|
|
33
|
+
HANDOFF = os.path.join(LOOP_DIR, "HANDOFF.md")
|
|
25
34
|
STOP_SIGNAL = os.path.join(".orchestrator", "STOP")
|
|
26
35
|
BUDGET = os.path.join(".orchestrator", "loop-budget.json")
|
|
27
36
|
GATE_LOCK = os.path.join(LOOP_DIR, "gate.lock")
|
|
@@ -122,31 +131,118 @@ def gate_running():
|
|
|
122
131
|
try:
|
|
123
132
|
if not os.path.exists(GATE_LOCK):
|
|
124
133
|
return False
|
|
125
|
-
import time
|
|
126
134
|
return (time.time() - os.path.getmtime(GATE_LOCK)) < GATE_TTL_SEC
|
|
127
135
|
except Exception:
|
|
128
136
|
return False
|
|
129
137
|
|
|
130
138
|
|
|
139
|
+
def read_anchor():
|
|
140
|
+
"""Return the parsed task anchor dict, or None if absent/corrupt. Fail-open."""
|
|
141
|
+
try:
|
|
142
|
+
with open(ANCHOR, encoding="utf-8") as f:
|
|
143
|
+
return json.load(f)
|
|
144
|
+
except Exception:
|
|
145
|
+
return None
|
|
146
|
+
|
|
147
|
+
|
|
131
148
|
def anchor_pending():
|
|
132
149
|
"""Return the unverified acceptance-criteria ids from the task anchor, or [].
|
|
133
150
|
|
|
134
151
|
The mechanical anti-drift gate: a `<promise>` must not end the loop while the frozen task anchor
|
|
135
|
-
still has criteria that are not `done`.
|
|
136
|
-
|
|
137
|
-
self-contained). FAIL-OPEN: a missing / unreadable / empty anchor, or one with no criteria,
|
|
138
|
-
returns [] so the gate never blocks — a buggy anchor must never trap the loop, and the rejection
|
|
139
|
-
it does cause is still bounded by `max_iterations` + the budget. Only a cleanly-parsed anchor
|
|
140
|
-
with ≥1 criterion that is not `done` reports pending.
|
|
152
|
+
still has criteria that are not `done`. FAIL-OPEN: a missing / unreadable / empty anchor, or one
|
|
153
|
+
with no criteria, returns [] so the gate never blocks — a buggy anchor must never trap the loop.
|
|
141
154
|
"""
|
|
155
|
+
data = read_anchor()
|
|
156
|
+
if not data:
|
|
157
|
+
return []
|
|
158
|
+
crit = data.get("criteria") or []
|
|
159
|
+
return [c.get("id") for c in crit
|
|
160
|
+
if isinstance(c, dict) and c.get("status") != "done"]
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def tail_journal(n=8):
|
|
164
|
+
"""Last N attempt records from the journal, oldest first. [] on any read error."""
|
|
142
165
|
try:
|
|
143
|
-
with open(
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
166
|
+
with open(JOURNAL, encoding="utf-8") as f:
|
|
167
|
+
lines = [ln for ln in f if ln.strip()]
|
|
168
|
+
out = []
|
|
169
|
+
for ln in lines[-n:]:
|
|
170
|
+
try:
|
|
171
|
+
out.append(json.loads(ln))
|
|
172
|
+
except Exception:
|
|
173
|
+
continue
|
|
174
|
+
return out
|
|
148
175
|
except Exception:
|
|
149
|
-
return []
|
|
176
|
+
return []
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def write_handoff(reason, meta=None, body=None):
|
|
180
|
+
"""Write the cross-agent continuation artifact before an INCOMPLETE stop.
|
|
181
|
+
|
|
182
|
+
Aggregates the frozen task anchor (goal + acceptance criteria + evidence), the last journal
|
|
183
|
+
attempts (what was already tried, to avoid re-running a dead end), and the live scratchpad
|
|
184
|
+
iteration/promise — everything a fresh agent needs to resume cold, without this conversation.
|
|
185
|
+
Fail-open: any error here must never block the stop itself.
|
|
186
|
+
"""
|
|
187
|
+
try:
|
|
188
|
+
anchor = read_anchor() or {}
|
|
189
|
+
criteria = anchor.get("criteria") or []
|
|
190
|
+
attempts = tail_journal()
|
|
191
|
+
lines = [
|
|
192
|
+
"# simplicio-loop handoff",
|
|
193
|
+
"",
|
|
194
|
+
"Stop reason: %s" % reason,
|
|
195
|
+
"Stopped at: %s" % time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
|
|
196
|
+
]
|
|
197
|
+
if meta:
|
|
198
|
+
lines += [
|
|
199
|
+
"Iteration: %s / %s" % (meta.get("iteration", "?"), meta.get("max_iterations", "?")),
|
|
200
|
+
"Completion promise: %s" % (meta.get("completion_promise") or "(none set)"),
|
|
201
|
+
]
|
|
202
|
+
if anchor.get("goal"):
|
|
203
|
+
lines += ["", "## Frozen goal", "", anchor["goal"]]
|
|
204
|
+
elif body:
|
|
205
|
+
lines += ["", "## Goal (from scratchpad, no anchor set)", "", body]
|
|
206
|
+
if criteria:
|
|
207
|
+
lines += ["", "## Acceptance criteria"]
|
|
208
|
+
for c in criteria:
|
|
209
|
+
if not isinstance(c, dict):
|
|
210
|
+
continue
|
|
211
|
+
mark = "x" if c.get("status") == "done" else " "
|
|
212
|
+
ev = (" — %s" % c["evidence"]) if c.get("evidence") else ""
|
|
213
|
+
lines.append(
|
|
214
|
+
"- [%s] %s (%s)%s"
|
|
215
|
+
% (mark, c.get("text", c.get("id", "?")), c.get("status", "pending"), ev)
|
|
216
|
+
)
|
|
217
|
+
if attempts:
|
|
218
|
+
lines += ["", "## Last attempts (`scripts/loop_journal.py resume` for the full read)"]
|
|
219
|
+
for a in attempts:
|
|
220
|
+
lines.append(
|
|
221
|
+
"- iter %s: %s -> %s (fp %s)%s"
|
|
222
|
+
% (
|
|
223
|
+
a.get("iteration", "?"),
|
|
224
|
+
a.get("action", "?"),
|
|
225
|
+
a.get("gate", "?"),
|
|
226
|
+
(a.get("fingerprint") or "")[:12],
|
|
227
|
+
(" — %s" % a["note"]) if a.get("note") else "",
|
|
228
|
+
)
|
|
229
|
+
)
|
|
230
|
+
lines += [
|
|
231
|
+
"",
|
|
232
|
+
"## Resume",
|
|
233
|
+
"",
|
|
234
|
+
"1. `python3 scripts/task_anchor.py status` (or `gate --exit-code`) — verified vs open.",
|
|
235
|
+
"2. `python3 scripts/loop_journal.py resume` — dead-end actions to avoid.",
|
|
236
|
+
"3. `git log --oneline -10` / `git diff` — what already landed.",
|
|
237
|
+
"4. Re-arm the loop once the stop cause (budget/cap/manual) is resolved.",
|
|
238
|
+
"",
|
|
239
|
+
]
|
|
240
|
+
tmp = HANDOFF + ".tmp"
|
|
241
|
+
with open(tmp, "w", encoding="utf-8") as f:
|
|
242
|
+
f.write("\n".join(lines))
|
|
243
|
+
os.replace(tmp, HANDOFF)
|
|
244
|
+
except Exception:
|
|
245
|
+
pass # fail-open: a broken handoff write must never block the stop
|
|
150
246
|
|
|
151
247
|
|
|
152
248
|
def budget_halted():
|
|
@@ -177,8 +273,18 @@ def emit_refeed(followup):
|
|
|
177
273
|
|
|
178
274
|
def main():
|
|
179
275
|
try:
|
|
180
|
-
|
|
276
|
+
meta, body = None, None
|
|
277
|
+
if os.path.exists(SCRATCHPAD):
|
|
278
|
+
try:
|
|
279
|
+
with open(SCRATCHPAD, encoding="utf-8") as f:
|
|
280
|
+
meta, body = parse_frontmatter(f.read())
|
|
281
|
+
except OSError:
|
|
282
|
+
meta, body = None, None
|
|
283
|
+
|
|
284
|
+
# Explicit STOP signal beats everything — but still hand off if there was live state.
|
|
181
285
|
if os.path.exists(STOP_SIGNAL):
|
|
286
|
+
if meta is not None:
|
|
287
|
+
write_handoff("manual STOP signal", meta, body)
|
|
182
288
|
cleanup_and_stop()
|
|
183
289
|
# Waiting on a background gate (workflow / CI / long task)? Let the turn end WITHOUT
|
|
184
290
|
# consuming an iteration or re-feeding — we are blocked on that gate, not idle. The gate's
|
|
@@ -188,9 +294,6 @@ def main():
|
|
|
188
294
|
# (1) No active loop.
|
|
189
295
|
if not os.path.exists(SCRATCHPAD):
|
|
190
296
|
allow_stop()
|
|
191
|
-
with open(SCRATCHPAD, encoding="utf-8") as f:
|
|
192
|
-
content = f.read()
|
|
193
|
-
meta, body = parse_frontmatter(content)
|
|
194
297
|
# (2) Corrupt state.
|
|
195
298
|
if meta is None:
|
|
196
299
|
cleanup_and_stop()
|
|
@@ -215,21 +318,26 @@ def main():
|
|
|
215
318
|
# in the task anchor — the mechanical anti-drift gate. Pending ACs ⇒ ignore the
|
|
216
319
|
# promise and keep looping (still bounded by max_iter), never a false "done".
|
|
217
320
|
if ((not evidence_required) or has_evidence) and not anchor_pending():
|
|
218
|
-
cleanup_and_stop() # (3) promise fulfilled → stop
|
|
321
|
+
cleanup_and_stop() # (3) promise fulfilled → stop, no handoff needed
|
|
219
322
|
# promise without evidence, or anchor still has open ACs → ignore, keep looping
|
|
220
323
|
# (3') Cursor capture may have raised the flag.
|
|
221
324
|
if os.path.exists(DONE_FLAG):
|
|
222
325
|
cleanup_and_stop()
|
|
223
|
-
# (4) Iteration cap.
|
|
326
|
+
# (4) Iteration cap — incomplete stop, hand off.
|
|
224
327
|
if max_iter > 0 and iteration >= max_iter:
|
|
328
|
+
write_handoff("max_iterations cap reached", meta, body)
|
|
225
329
|
cleanup_and_stop()
|
|
226
|
-
# (5) Budget halted.
|
|
330
|
+
# (5) Budget halted — incomplete stop, hand off. This is the exact "ran out of tokens/$"
|
|
331
|
+
# case: a different agent must be able to pick this up cold.
|
|
227
332
|
if budget_halted():
|
|
333
|
+
write_handoff("budget halted", meta, body)
|
|
228
334
|
cleanup_and_stop()
|
|
229
335
|
# (6) Continue: bump iteration in place, re-feed the goal body.
|
|
230
336
|
nxt = iteration + 1
|
|
337
|
+
with open(SCRATCHPAD, encoding="utf-8") as f:
|
|
338
|
+
raw = f.read()
|
|
231
339
|
new_content = re.sub(
|
|
232
|
-
r"^iteration:\s*\d+", "iteration: %d" % nxt,
|
|
340
|
+
r"^iteration:\s*\d+", "iteration: %d" % nxt, raw, count=1, flags=re.M
|
|
233
341
|
)
|
|
234
342
|
try:
|
|
235
343
|
tmp = SCRATCHPAD + ".tmp"
|
|
@@ -312,7 +312,7 @@ Where the host runtime supports lifecycle hooks, bind the two cross-platform hoo
|
|
|
312
312
|
| Hook | Fires | Job |
|
|
313
313
|
|---|---|---|
|
|
314
314
|
| `afterAgentResponse` → `loop_capture.py` | after every turn | extract `<promise>…</promise>`; if it exactly equals `completion_promise` AND in-turn evidence exists → `touch .orchestrator/loop/done`. Fire-and-forget, `exit 0`. Never stops the loop itself. |
|
|
315
|
-
| `stop` → `loop_stop.py` | when the turn ends | guard clauses, each ends the loop cleanly (remove state, `exit 0`): (1) no scratchpad → stop; (2) corrupt frontmatter → stop; (3) `done` flag present → stop (promise fulfilled); (4) `iteration >= max_iterations > 0` → stop (cap); (5) budget halted → stop; else increment `iteration` in place and emit `{"followup_message": "<header>\n\n<goal body>"}` to re-feed. |
|
|
315
|
+
| `stop` → `loop_stop.py` | when the turn ends | guard clauses, each ends the loop cleanly (remove state, `exit 0`): (1) no scratchpad → stop; (2) corrupt frontmatter → stop; (3) `done` flag present → stop (promise fulfilled); (4) `iteration >= max_iterations > 0` → write `HANDOFF.md`, then stop (cap); (5) budget halted → write `HANDOFF.md` (frozen goal + AC status + last attempts) for a different agent to resume, then stop; else increment `iteration` in place and emit `{"followup_message": "<header>\n\n<goal body>"}` to re-feed. |
|
|
316
316
|
|
|
317
317
|
Detection (`capture`) and termination (`stop`) are split on purpose — neither parses the
|
|
318
318
|
other's inline state. Iteration carries forward through git history + the working tree, not
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: simplicio-review
|
|
3
|
-
description: Deep, adversarial branch review — parallel subagents on separate rubrics (security/correctness
|
|
3
|
+
description: Deep, adversarial branch review — parallel subagents on separate rubrics (security/correctness, code-quality, and does-it-reproduce), spawned in one message, then deduped into one verdict. Runs for EVERY item, no TRIVIAL/SMALL shortcut — it is 3 of the 6 roles in simplicio-tasks' minimum-agent floor. Use before merging any work, when the user says "review this branch/PR hard", "thermo-nuclear review", "is this safe to merge", or when simplicio-tasks needs the Step 4c adversarial verify gate. Scopes strictly to the diff; refutes rather than rubber-stamps.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# simplicio-review — thermo-nuclear adversarial review
|
|
@@ -15,9 +15,9 @@ security vs code-quality rubrics, dedup-on-synthesis) wired into the simplicio e
|
|
|
15
15
|
|
|
16
16
|
## When to use
|
|
17
17
|
|
|
18
|
-
- Before merging
|
|
18
|
+
- Before merging ANY item, TRIVIAL through CRITICAL (the Step 4c gate) — `simplicio-tasks`' 6-agent
|
|
19
|
+
floor (Step 3) has no solo/self-review path left; this fan-out is 3 of those 6 roles, always.
|
|
19
20
|
- "review this branch hard", "thermo-nuclear", "find what's wrong before I merge".
|
|
20
|
-
- NOT for TRIVIAL/SMALL items — those keep a single self-review (don't pay the latency).
|
|
21
21
|
|
|
22
22
|
## Step 1 — Gather context ONCE (parent)
|
|
23
23
|
|
|
@@ -36,7 +36,7 @@ unless the change makes them reachable.
|
|
|
36
36
|
|
|
37
37
|
## Step 2 — Fan out parallel reviewers (one message, background)
|
|
38
38
|
|
|
39
|
-
Spawn
|
|
39
|
+
Spawn 3 INDEPENDENT subagents IN A SINGLE MESSAGE (so they run concurrently — wall-clock
|
|
40
40
|
down, no proportional token blow-up). Each gets the SAME context bundle and a DISTINCT rubric:
|
|
41
41
|
|
|
42
42
|
### Rubric A — security & correctness
|
|
@@ -53,7 +53,7 @@ down, no proportional token blow-up). Each gets the SAME context bundle and a DI
|
|
|
53
53
|
- Boundary cleanliness: leaky abstractions, duplicated logic that ignores an adjacent module.
|
|
54
54
|
- Naming, dead code, comments that lie, tests that assert nothing.
|
|
55
55
|
|
|
56
|
-
### Rubric C
|
|
56
|
+
### Rubric C — does-it-reproduce / runtime (always spawned; its evidence requirements below stay scoped to what the diff touches)
|
|
57
57
|
- Actually run the changed path; confirm the AC behavior end-to-end (not just "compiles").
|
|
58
58
|
- **Front-end change → require web evidence.** If the diff touches front-end files
|
|
59
59
|
(`*.tsx/jsx/vue/svelte/css/html`, `components/**`, `pages/**`, `app/**`), REQUIRE a `web_verify`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: simplicio-tasks
|
|
3
|
-
description: Autonomously complete a body of work (tasks, issues, cards, CI failures) on ANY LLM/runtime. Use when the user types /simplicio-tasks or asks to clear/finish/close/implement a queue of work — e.g. "finish all open issues", "close the bugs in milestone X", "implement epic #235", "clear the CI queue", "clean up the Jira board". Runtime-agnostic: discovers work-items from any source, dedups, auto-scales to machine capacity,
|
|
3
|
+
description: Autonomously complete a body of work (tasks, issues, cards, CI failures) on ANY LLM/runtime. Use when the user types /simplicio-tasks or asks to clear/finish/close/implement a queue of work — e.g. "finish all open issues", "close the bugs in milestone X", "implement epic #235", "clear the CI queue", "clean up the Jira board". Runtime-agnostic: discovers work-items from any source, dedups, auto-scales to machine capacity, a minimum 6-agent floor (plan, implement, 4 parallel reviewers) for every item / a scaled fleet beyond 6 for large queues, then merges and closes with evidence. If a host runtime is present it binds native capabilities to this skill's extension points; otherwise the LLM performs every step directly. For a body of work it runs as a loop (auto-arms, no separate /loop or /simplicio-loop command, re-feeding the goal until the queue is drained and verified, or a cap/budget/STOP fires); a single interactive item still runs the 6-agent floor and stops after one pass.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# /simplicio-tasks — Universal Looping Orchestrator
|
|
@@ -9,7 +9,10 @@ A runtime-agnostic autonomous orchestrator. It works on ANY strong LLM/runtime (
|
|
|
9
9
|
Copilot, Gemini, Cursor, local models, CI agents) with NO mandatory external dependency. Every
|
|
10
10
|
step is something the LLM can do directly with standard tools (shell, git, gh, file edit, web).
|
|
11
11
|
Where a host runtime exposes a faster native capability, it BINDS to the extension points
|
|
12
|
-
(Step 1b) — near-zero token cost
|
|
12
|
+
(Step 1b) — near-zero token cost. The skill itself never requires it (the abstraction works on
|
|
13
|
+
any strong LLM) — but on Claude Code, Codex, Cursor, VS Code, Antigravity, Kiro, OpenCode, and
|
|
14
|
+
Hermes, binding to `simplicio-runtime` (MCP or CLI) IS a project-policy requirement, enforced at
|
|
15
|
+
the host/installer level, not by the skill (see `adapters/MATRIX.md` `FORCED_BIND_RUNTIMES`).
|
|
13
16
|
|
|
14
17
|
The target is in the skill arguments (e.g. `/simplicio-tasks finish all open issues`). If no
|
|
15
18
|
argument, default to "all open work-items in the default source"; confirm scope in ONE line only
|
|
@@ -122,6 +125,11 @@ ABSTRACTION, never a runtime — the INVERTED DEPENDENCY (the skill names no run
|
|
|
122
125
|
detects the skill). Full table + fallbacks: `references/extension-points.md`. Core rule: any
|
|
123
126
|
DECIDED change goes through `deterministic_edit` — never hand-write or regenerate it with a model.
|
|
124
127
|
|
|
128
|
+
On the 8 `FORCED_BIND_RUNTIMES` (Claude, Codex, Cursor, VS Code, Antigravity, Kiro, OpenCode,
|
|
129
|
+
Hermes), the LLM fallback for an extension point is allowed only until the native bind is
|
|
130
|
+
verified reachable (`simplicio doctor --json`); a run that starts unbound on one of these hosts
|
|
131
|
+
must report the gap as a blocker, not proceed silently on the fallback indefinitely.
|
|
132
|
+
|
|
125
133
|
When the run is driven by `simplicio-loop` (Step 0, the armed body-of-work path), two points are bound to REQUIRED
|
|
126
134
|
operators instead of LLM fallbacks: `simplicio-mapper` surveys the repo (`orient`) and
|
|
127
135
|
`simplicio-dev-cli task` applies+verifies each decided change (`execute`/`deterministic_edit`) — the AI
|
|
@@ -352,5 +360,6 @@ on the STOP signal, budget exhaustion, or a safety halt. Full ten axes + arming
|
|
|
352
360
|
and load the compact form thereafter.
|
|
353
361
|
- **Portability:** any strong LLM/runtime runs this end-to-end with standard tools. A host runtime
|
|
354
362
|
that binds the extension points makes steps deterministic + near-zero-token; without it the LLM
|
|
355
|
-
fallbacks cover 100%. Same skill, any runtime
|
|
356
|
-
|
|
363
|
+
fallbacks cover 100%. Same skill, any runtime — EXCEPT that on the 8 `FORCED_BIND_RUNTIMES`
|
|
364
|
+
the native bind is a policy requirement, not a speed-only nicety (see Step 1b). Runtimes
|
|
365
|
+
without real multi-agent degrade the heavy-path to internal multi-pass — no swarm, same gates.
|
|
@@ -61,13 +61,33 @@ changes, or refactors inside widely imported modules, tighten the gate to `--fai
|
|
|
61
61
|
uncovered local dependencies and related tests also block the plan. The point is to know the blast
|
|
62
62
|
radius before editing, not after the regression.
|
|
63
63
|
|
|
64
|
-
## Step 3 — Route:
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
64
|
+
## Step 3 — Route: minimum fleet vs scaled fleet
|
|
65
|
+
|
|
66
|
+
**Hard floor: every run keeps ≥6 orchestrated agents in flight — no solo/inline path.** A single
|
|
67
|
+
TRIVIAL item is decomposed by ROLE, not by work-item count, so the floor holds without inventing
|
|
68
|
+
parallel work that doesn't exist:
|
|
69
|
+
|
|
70
|
+
| # | Role | Cardinality |
|
|
71
|
+
|---|---|---|
|
|
72
|
+
| 1 | Orient + plan (Step 2b) | 1 agent |
|
|
73
|
+
| 2 | Implement (Step 4) | 1 agent (2 on MEDIUM+: a fast-follow pair) |
|
|
74
|
+
| 3 | Review — Rubric A: security & correctness (`simplicio-review`) | 1 agent |
|
|
75
|
+
| 4 | Review — Rubric B: quality & maintainability (`simplicio-review`) | 1 agent |
|
|
76
|
+
| 5 | Review — Rubric C: does-it-reproduce / runtime (`simplicio-review`) | 1 agent |
|
|
77
|
+
| 6 | Independent blast-radius reviewer — re-checks Step 4a' `impact_audit.json` (and `flow_audit.json` when applicable) as a second set of eyes, not the implementer self-grading its own scope claim | 1 agent |
|
|
78
|
+
|
|
79
|
+
Roles 1–2 are sequential (plan before implementing); roles 3–6 spawn in ONE message so they run
|
|
80
|
+
concurrently — wall-clock down, no proportional token blow-up (`simplicio-review` Step 2 pattern).
|
|
81
|
+
Rubric C's heaviest sub-checks (`web_verify`, `flow_audit`) stay conditional on the diff actually
|
|
82
|
+
touching that surface — the rubric runs always, its expensive evidence requirements stay scoped.
|
|
83
|
+
|
|
84
|
+
- **Minimum fleet** (queue small AND every item complexity ≤ 3): the 6-role floor above runs on
|
|
85
|
+
the single item. There is no solo/self-review shortcut left to fall back to — the floor IS the
|
|
86
|
+
minimum, never undercut it. Finish → Step 6.
|
|
87
|
+
- **Scaled fleet** (large queue OR any medium+ item): fan out beyond 6. Compute the fleet, keep a
|
|
88
|
+
CONTINUOUS WORKER POOL fed by a LIVE queue (not frozen waves) — a freed worker pulls the next
|
|
89
|
+
item, even one that appeared seconds ago. Serialize same-file items (conflict detection).
|
|
90
|
+
Quarantine items that fail K times to a dead-letter list.
|
|
71
91
|
|
|
72
92
|
**Worker report contract (every worker MUST follow).** A worker result is re-injected into the
|
|
73
93
|
orchestrator context verbatim and costs budget on EVERY delegation. Forbid narration; mandate the
|
|
@@ -92,10 +112,12 @@ Step 4 loop). Feed the top corrections into the shared digest so agents pre-empt
|
|
|
92
112
|
cap_cpu = max(1, floor((cores - 2) / 2))
|
|
93
113
|
cap_mem = floor(free_gb / 2)
|
|
94
114
|
cap_disk = (free_disk_gb < 10) ? 0 : (free_disk_gb < 25 ? 1 : 99)
|
|
95
|
-
fleet = min(cap_cpu, cap_mem, cap_disk, independent_items, 16) #
|
|
115
|
+
fleet = max(6, min(cap_cpu, cap_mem, cap_disk, independent_items, 16)) # 6-agent floor, 16/wave cap
|
|
96
116
|
waves = ceil(queue_size / fleet)
|
|
97
117
|
```
|
|
98
|
-
If resources unknown or disk < 10 GB
|
|
118
|
+
If resources unknown or disk < 10 GB, the 6-role floor still runs — switch isolation to
|
|
119
|
+
`isolation=shared` (one checkout, sequential commits on overlapping files) instead of
|
|
120
|
+
worktree-per-item, so the floor is met without the disk cost of 6 separate worktrees.
|
|
99
121
|
|
|
100
122
|
**Worktree-per-item isolation (DEFAULT) + a cost opt-out.** Each item gets its OWN
|
|
101
123
|
`git worktree add` checkout by default, so parallel workers never touch the same tree and there is
|
|
@@ -133,10 +155,13 @@ conflict-serialization for newly-arrived same-file items.
|
|
|
133
155
|
## Step 3c — Speed model (velocity without sacrificing quality)
|
|
134
156
|
1. Pipeline, not barrier (item A merges while B builds). 2. Shared compile cache (e.g. `sccache`).
|
|
135
157
|
3. Verify once: each agent runs a scoped incremental check; the full suite runs EXACTLY ONCE on
|
|
136
|
-
the merged result. 4. Front-load shared context (orient once, share the digest). 5. Tier
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
158
|
+
the merged result. 4. Front-load shared context (orient once, share the digest). 5. Tier scope,
|
|
159
|
+
not tier skip: the Step 3 6-role review fan-out (roles 3-6) runs on EVERY item regardless of
|
|
160
|
+
tier — only Rubric C's heaviest sub-checks (web/flow evidence) stay scoped to MEDIUM+ or
|
|
161
|
+
surface-touching diffs; a TRIVIAL item still gets the full review, just lighter individual
|
|
162
|
+
checks within it. 6. Pre-warm the build on clean main. 7. Time-box + quarantine stuck agents.
|
|
163
|
+
8. Prefetch re-discovery during the prior wave's review. Speed comes from removing redundant
|
|
164
|
+
work, not skipping gates.
|
|
140
165
|
|
|
141
166
|
## Step 3d — Model routing (spend reasoning only where it pays)
|
|
142
167
|
- **L0** Deterministic, ZERO LLM tokens: decided edits via `deterministic_edit`, repo view via
|
|
@@ -108,12 +108,14 @@ python3 scripts/flow_audit.py audit <root> --fail-on medium
|
|
|
108
108
|
The final evidence must include either `.orchestrator/flow-audit.json` or the human summary. A green
|
|
109
109
|
unit test is not enough when the flow graph still has an unclassified loose end.
|
|
110
110
|
|
|
111
|
-
### 4c — Adversarial verify for
|
|
112
|
-
Spawn
|
|
113
|
-
Majority-refute → back to fix. TRIVIAL/SMALL
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
111
|
+
### 4c — Adversarial verify for EVERY item (multi-vote, no tier shortcut)
|
|
112
|
+
Spawn 3 INDEPENDENT verifiers — Rubrics A/B/C of the Step 3 6-role floor — each prompted to REFUTE
|
|
113
|
+
the implementation AND check each AC. Majority-refute → back to fix. There is no TRIVIAL/SMALL
|
|
114
|
+
single-self-review shortcut left: the 6-agent floor applies to every item, so this fan-out is
|
|
115
|
+
already paid for by the floor, not an extra cost layered on top of a cheaper default. When
|
|
116
|
+
`simplicio-review` is loaded, delegate this gate to it (parallel rubrics → deduped verdict). Each
|
|
117
|
+
verifier gets the full body + ACs, the diff, the run evidence; task: "Find any AC NOT met, any
|
|
118
|
+
fake/placeholder return. Refute or confirm with specific `file:line`."
|
|
117
119
|
|
|
118
120
|
## Step 5 — Safety gates (NON-NEGOTIABLE)
|
|
119
121
|
Before any commit/push: secret-scan the diff (block on hit). Before any IRREVERSIBLE op
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: simplicio-loop
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.18.1
|
|
4
4
|
Summary: The Universal Looping AI Orchestrator — a runtime-agnostic super-plugin (6 skills) that drains any queue of work end-to-end on any LLM/runtime.
|
|
5
5
|
Author-email: Wesley Simplicio <wesleybob4@gmail.com>
|
|
6
6
|
License: MIT
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/hooks/hooks.claude.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/hooks/loop_capture.py
RENAMED
|
File without changes
|
{simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/hooks/orient_clamp.py
RENAMED
|
File without changes
|
{simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/hooks/orient_rewrite.py
RENAMED
|
File without changes
|
{simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/hooks/simplicio_dashboard.py
RENAMED
|
File without changes
|
{simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop/_bundle/hooks/simplicio_watch.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simplicio_loop-3.15.0 → simplicio_loop-3.18.1}/simplicio_loop.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|