diff --git a/.codex/agents/franky.toml b/.codex/agents/fronk.toml similarity index 95% rename from .codex/agents/franky.toml rename to .codex/agents/fronk.toml index f78b5d7..127ac87 100644 --- a/.codex/agents/franky.toml +++ b/.codex/agents/fronk.toml @@ -1,10 +1,10 @@ -name = "franky" +name = "fronk" description = "Implementation worker for one Superloopy criterion or one non-overlapping slice." model = "gpt-5.5" model_reasoning_effort = "high" service_tier = "priority" developer_instructions = """ -You are franky, a focused implementation worker for Superloopy. +You are fronk, a focused implementation worker for Superloopy. Operate on exactly one handoff card. The parent should give you the goal, criterion or slice, scope, allowed files, active evidence root, validation command, and artifact target. If essential context is missing and repo state cannot answer it, return STATUS: NEEDS_CONTEXT. diff --git a/.codex/agents/jinbe.toml b/.codex/agents/jumbo.toml similarity index 96% rename from .codex/agents/jinbe.toml rename to .codex/agents/jumbo.toml index 879bf2f..91b0453 100644 --- a/.codex/agents/jinbe.toml +++ b/.codex/agents/jumbo.toml @@ -1,10 +1,10 @@ -name = "jinbe" +name = "jumbo" description = "Final Superloopy gate reviewer that integrates implementation, QA, review, and audit evidence." model = "gpt-5.5" model_reasoning_effort = "xhigh" service_tier = "priority" developer_instructions = """ -You are jinbe, the final evidence integrator for a Superloopy task. +You are jumbo, the final evidence integrator for a Superloopy task. Do not edit product files or Superloopy plan state. Read the original brief, current Superloopy guide/check/report output, code-review report, QA report, audit verdicts when present, and the artifacts cited by each claim. You may write one final gate report under the active evidence root. diff --git a/.codex/agents/nami.toml b/.codex/agents/nomi.toml similarity index 97% rename from .codex/agents/nami.toml rename to .codex/agents/nomi.toml index 0b5c72e..17d3890 100644 --- a/.codex/agents/nami.toml +++ b/.codex/agents/nomi.toml @@ -1,10 +1,10 @@ -name = "nami" +name = "nomi" description = "Read-only codebase navigator for Superloopy subagent-driven work. Finds files and code in the working tree and returns absolute paths with a direct answer. Never edits, never writes evidence." model = "gpt-5.4-mini" model_reasoning_effort = "low" service_tier = "fast" developer_instructions = """ -You are nami, a read-only codebase navigator for Superloopy. You locate files and code so the parent can act without a follow-up search. You are strictly read-only: you never edit, never run product builds, and never write evidence artifacts. +You are nomi, a read-only codebase navigator for Superloopy. You locate files and code so the parent can act without a follow-up search. You are strictly read-only: you never edit, never run product builds, and never write evidence artifacts. You answer one of: "Where is X?", "Which files do Y?", "Find the code that does Z." Answer the parent's actual need, not just the literal request. diff --git a/.codex/agents/robin.toml b/.codex/agents/rovyn.toml similarity index 96% rename from .codex/agents/robin.toml rename to .codex/agents/rovyn.toml index 839e5a5..c5ca6ef 100644 --- a/.codex/agents/robin.toml +++ b/.codex/agents/rovyn.toml @@ -1,10 +1,10 @@ -name = "robin" +name = "rovyn" description = "Read-only, skeptical evidence auditor for Superloopy criteria." model = "gpt-5.5" model_reasoning_effort = "high" service_tier = "priority" developer_instructions = """ -You are robin, an independent, read-only Superloopy evidence auditor. Assume the implementation is NOT done. +You are rovyn, an independent, read-only Superloopy evidence auditor. Assume the implementation is NOT done. You are given one criterion's scenario and Superloopy's deterministic re-run artifact: Superloopy already re-ran the proof in-process and recorded the result. Judge whether that re-run actually satisfies the scenario, then write a verdict. diff --git a/.codex/agents/usopp.toml b/.codex/agents/usk.toml similarity index 96% rename from .codex/agents/usopp.toml rename to .codex/agents/usk.toml index e143558..25828c2 100644 --- a/.codex/agents/usopp.toml +++ b/.codex/agents/usk.toml @@ -1,10 +1,10 @@ -name = "usopp" +name = "usk" description = "QA worker that exercises Superloopy criteria and writes artifact-backed QA evidence." model = "gpt-5.5" model_reasoning_effort = "high" service_tier = "priority" developer_instructions = """ -You are usopp, a QA worker for Superloopy evidence. +You are usk, a QA worker for Superloopy evidence. Exercise the user-facing and regression surface named in the handoff card. Do not edit product files or Superloopy plan state. You may create fixtures, command transcripts, screenshots, or one QA report under the active evidence root. diff --git a/.codex/agents/zoro.toml b/.codex/agents/zyro.toml similarity index 95% rename from .codex/agents/zoro.toml rename to .codex/agents/zyro.toml index 0005286..ec11839 100644 --- a/.codex/agents/zoro.toml +++ b/.codex/agents/zyro.toml @@ -1,10 +1,10 @@ -name = "zoro" +name = "zyro" description = "Independent code reviewer for Superloopy subagent-driven development." model = "gpt-5.5" model_reasoning_effort = "xhigh" service_tier = "priority" developer_instructions = """ -You are zoro, an independent reviewer for a bounded Superloopy change. +You are zyro, an independent reviewer for a bounded Superloopy change. Review only the assignment in the handoff card. Read the original goal, relevant criteria, changed files, evidence artifacts, and local instructions. Do not edit product files or Superloopy plan state. You may write one review report under the active evidence root. diff --git a/.github/assets/franky.png b/.github/assets/franky.png deleted file mode 100644 index 3217932..0000000 Binary files a/.github/assets/franky.png and /dev/null differ diff --git a/.github/assets/fronk.png b/.github/assets/fronk.png new file mode 100644 index 0000000..ce9bceb Binary files /dev/null and b/.github/assets/fronk.png differ diff --git a/.github/assets/jinbe.png b/.github/assets/jinbe.png deleted file mode 100644 index 8260849..0000000 Binary files a/.github/assets/jinbe.png and /dev/null differ diff --git a/.github/assets/jumbo.png b/.github/assets/jumbo.png new file mode 100644 index 0000000..3344ff5 Binary files /dev/null and b/.github/assets/jumbo.png differ diff --git a/.github/assets/nami.png b/.github/assets/nami.png deleted file mode 100644 index 4f57b8e..0000000 Binary files a/.github/assets/nami.png and /dev/null differ diff --git a/.github/assets/nomi.png b/.github/assets/nomi.png new file mode 100644 index 0000000..e6c8b56 Binary files /dev/null and b/.github/assets/nomi.png differ diff --git a/.github/assets/robin.png b/.github/assets/robin.png deleted file mode 100644 index e842a07..0000000 Binary files a/.github/assets/robin.png and /dev/null differ diff --git a/.github/assets/rovyn.png b/.github/assets/rovyn.png new file mode 100644 index 0000000..d58058c Binary files /dev/null and b/.github/assets/rovyn.png differ diff --git a/.github/assets/usk.png b/.github/assets/usk.png new file mode 100644 index 0000000..beb4938 Binary files /dev/null and b/.github/assets/usk.png differ diff --git a/.github/assets/usopp.png b/.github/assets/usopp.png deleted file mode 100644 index 4e8d215..0000000 Binary files a/.github/assets/usopp.png and /dev/null differ diff --git a/.github/assets/zoro.png b/.github/assets/zoro.png deleted file mode 100644 index 925746a..0000000 Binary files a/.github/assets/zoro.png and /dev/null differ diff --git a/.github/assets/zyro.png b/.github/assets/zyro.png new file mode 100644 index 0000000..fd738e2 Binary files /dev/null and b/.github/assets/zyro.png differ diff --git a/README.es.md b/README.es.md index b2b78b2..45ccd39 100644 --- a/README.es.md +++ b/README.es.md @@ -12,7 +12,7 @@ Español

-franky zoro usopp jinbe robin nami +fronk zyro usk jumbo rovyn nomi the crew — subagentes opcionales, un trabajo cada uno @@ -52,14 +52,14 @@ Para trabajos grandes, Superloopy incluye seis subagentes opcionales en `.codex/ - - - + + + - - - + + +
franky
franky
construye
zoro
zoro
revisa
usopp
usopp
prueba
fronk
fronk
construye
zyro
zyro
revisa
usk
usk
prueba
jinbe
jinbe
valida el gate
robin
robin
audita
nami
nami
encuentra
jumbo
jumbo
valida el gate
rovyn
rovyn
audita
nomi
nomi
encuentra
@@ -134,7 +134,7 @@ Reinicia Codex después de desinstalar. Optional local bootstrap cleanup: elimin ``` rm -f ~/.local/bin/superloopy -rm -f ~/.codex/agents/franky.toml ~/.codex/agents/zoro.toml ~/.codex/agents/usopp.toml ~/.codex/agents/jinbe.toml ~/.codex/agents/robin.toml ~/.codex/agents/nami.toml +rm -f ~/.codex/agents/fronk.toml ~/.codex/agents/zyro.toml ~/.codex/agents/usk.toml ~/.codex/agents/jumbo.toml ~/.codex/agents/rovyn.toml ~/.codex/agents/nomi.toml ``` Si instalaste con `CODEX_HOME`, `SUPERLOOPY_BIN_DIR` o `CODEX_LOCAL_BIN_DIR`, limpia esas rutas configuradas. diff --git a/README.ja.md b/README.ja.md index e1a76d9..3474e7c 100644 --- a/README.ja.md +++ b/README.ja.md @@ -12,7 +12,7 @@ Español

-franky zoro usopp jinbe robin nami +fronk zyro usk jumbo rovyn nomi the crew — 任意のサブエージェント、それぞれ 1 つの役割 @@ -52,14 +52,14 @@ Loop skill が標準のガードレールです。`loopy` は evidence loop を - - - + + + - - - + + +
franky
franky
実装
zoro
zoro
レビュー
usopp
usopp
テスト
fronk
fronk
実装
zyro
zyro
レビュー
usk
usk
テスト
jinbe
jinbe
ゲート確認
robin
robin
監査
nami
nami
探索
jumbo
jumbo
ゲート確認
rovyn
rovyn
監査
nomi
nomi
探索
@@ -134,7 +134,7 @@ codex plugin marketplace remove beefiker ``` rm -f ~/.local/bin/superloopy -rm -f ~/.codex/agents/franky.toml ~/.codex/agents/zoro.toml ~/.codex/agents/usopp.toml ~/.codex/agents/jinbe.toml ~/.codex/agents/robin.toml ~/.codex/agents/nami.toml +rm -f ~/.codex/agents/fronk.toml ~/.codex/agents/zyro.toml ~/.codex/agents/usk.toml ~/.codex/agents/jumbo.toml ~/.codex/agents/rovyn.toml ~/.codex/agents/nomi.toml ``` `CODEX_HOME`、`SUPERLOOPY_BIN_DIR`、`CODEX_LOCAL_BIN_DIR` を使ってインストール先を変えた場合は、その設定先を削除してください。 diff --git a/README.ko.md b/README.ko.md index bc1c0aa..8223c85 100644 --- a/README.ko.md +++ b/README.ko.md @@ -12,7 +12,7 @@ Español

-franky zoro usopp jinbe robin nami +fronk zyro usk jumbo rovyn nomi the crew — 필요할 때 부르는 서브에이전트들 @@ -52,14 +52,14 @@ Superloopy는 명령을 작게 둡니다. 대신 스킬이 작업 방식을 잡 - - - + + + - - - + + +
franky
franky
구현
zoro
zoro
리뷰
usopp
usopp
테스트
fronk
fronk
구현
zyro
zyro
리뷰
usk
usk
테스트
jinbe
jinbe
게이트 검토
robin
robin
감사
nami
nami
탐색
jumbo
jumbo
게이트 검토
rovyn
rovyn
감사
nomi
nomi
탐색
@@ -134,7 +134,7 @@ codex plugin marketplace remove beefiker ``` rm -f ~/.local/bin/superloopy -rm -f ~/.codex/agents/franky.toml ~/.codex/agents/zoro.toml ~/.codex/agents/usopp.toml ~/.codex/agents/jinbe.toml ~/.codex/agents/robin.toml ~/.codex/agents/nami.toml +rm -f ~/.codex/agents/fronk.toml ~/.codex/agents/zyro.toml ~/.codex/agents/usk.toml ~/.codex/agents/jumbo.toml ~/.codex/agents/rovyn.toml ~/.codex/agents/nomi.toml ``` `CODEX_HOME`, `SUPERLOOPY_BIN_DIR`, `CODEX_LOCAL_BIN_DIR`로 설치 위치를 바꿨다면 그 경로를 정리하세요. diff --git a/README.md b/README.md index f35b87a..638518b 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Español

-franky zoro usopp jinbe robin nami +fronk zyro usk jumbo rovyn nomi the crew — optional subagents, one job each @@ -60,14 +60,14 @@ For bigger work, Superloopy ships six optional subagents under `.codex/agents/` - - - + + + - - - + + +
franky
franky
builds it
zoro
zoro
reviews it
usopp
usopp
tests it
fronk
fronk
builds it
zyro
zyro
reviews it
usk
usk
tests it
jinbe
jinbe
gates it
robin
robin
audits it
nami
nami
finds it
jumbo
jumbo
gates it
rovyn
rovyn
audits it
nomi
nomi
finds it
@@ -142,7 +142,7 @@ Restart Codex after uninstalling. Optional local bootstrap cleanup: plugin remov ``` rm -f ~/.local/bin/superloopy -rm -f ~/.codex/agents/franky.toml ~/.codex/agents/zoro.toml ~/.codex/agents/usopp.toml ~/.codex/agents/jinbe.toml ~/.codex/agents/robin.toml ~/.codex/agents/nami.toml +rm -f ~/.codex/agents/fronk.toml ~/.codex/agents/zyro.toml ~/.codex/agents/usk.toml ~/.codex/agents/jumbo.toml ~/.codex/agents/rovyn.toml ~/.codex/agents/nomi.toml ``` If you installed with `CODEX_HOME`, `SUPERLOOPY_BIN_DIR`, or `CODEX_LOCAL_BIN_DIR`, clean up those configured paths instead. diff --git a/README.zh-CN.md b/README.zh-CN.md index 399a3e8..83c304e 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -12,7 +12,7 @@ Español

-franky zoro usopp jinbe robin nami +fronk zyro usk jumbo rovyn nomi the crew — 可选子代理,每个代理负责一个岗位 @@ -52,14 +52,14 @@ Loop skill 是默认护栏。`loopy` 会启动或继续 evidence loop;`loopy t - - - + + + - - - + + +
franky
franky
实现
zoro
zoro
评审
usopp
usopp
测试
fronk
fronk
实现
zyro
zyro
评审
usk
usk
测试
jinbe
jinbe
把关
robin
robin
审计
nami
nami
定位
jumbo
jumbo
把关
rovyn
rovyn
审计
nomi
nomi
定位
@@ -134,7 +134,7 @@ codex plugin marketplace remove beefiker ``` rm -f ~/.local/bin/superloopy -rm -f ~/.codex/agents/franky.toml ~/.codex/agents/zoro.toml ~/.codex/agents/usopp.toml ~/.codex/agents/jinbe.toml ~/.codex/agents/robin.toml ~/.codex/agents/nami.toml +rm -f ~/.codex/agents/fronk.toml ~/.codex/agents/zyro.toml ~/.codex/agents/usk.toml ~/.codex/agents/jumbo.toml ~/.codex/agents/rovyn.toml ~/.codex/agents/nomi.toml ``` 如果安装时使用了 `CODEX_HOME`、`SUPERLOOPY_BIN_DIR` 或 `CODEX_LOCAL_BIN_DIR`,请清理对应路径。 diff --git a/docs/superloopy-design-audit.md b/docs/superloopy-design-audit.md index 92d4d4d..096ccd2 100644 --- a/docs/superloopy-design-audit.md +++ b/docs/superloopy-design-audit.md @@ -10,7 +10,7 @@ This doctor-verified audit records Superloopy's own design decisions. It exists | `actor-field-policy` | Exact external role literals made compatibility too specific. | Actor fields now require non-empty identity text instead of a hard-coded role name. | `src/review-gate.js` and review-gate golden tests. | | `native-naming` | Public code, docs, and tests should describe Superloopy behavior directly. | Modules, tests, docs, CLI flags, and metadata use Superloopy-owned terms. | `test/docs.test.js` and `docs/superloopy-gate-notes.md`. | | `recorded-thresholds` | Later analysis should compare against earlier judgments. | `docs/superloopy-loop-golden-set.md` stores score history and command evidence in one tracked place. | `docs/superloopy-loop-golden-set.md` and `test/docs.test.js`. | -| `model-policy` | Crew lanes need explicit cost/depth defaults without treating model choice as correctness. | Bundled agent TOML files carry advisory model, effort, and tier defaults, with Nami optimized for navigation and review/gate lanes using deeper effort. | `docs/superloopy-model-policy.md`, `src/model-policy.js`, and `test/doctor.test.js`. | +| `model-policy` | Crew lanes need explicit cost/depth defaults without treating model choice as correctness. | Bundled agent TOML files carry advisory model, effort, and tier defaults, with Nomi optimized for navigation and review/gate lanes using deeper effort. | `docs/superloopy-model-policy.md`, `src/model-policy.js`, and `test/doctor.test.js`. | | `crew-lines` | Crew handoffs should feel alive without weakening evidence discipline. | Known crew lanes can emit original terminal-state lines in presentation output only; persisted state and gate authority stay mechanical. | `docs/superloopy-crew-lines.md`, `src/crew-lines.js`, `test/crew-lines.test.js`, and `test/fleet.test.js`. | ## Compatibility Boundary diff --git a/docs/superloopy-file-audit.md b/docs/superloopy-file-audit.md index 491d2b5..9c24aee 100644 --- a/docs/superloopy-file-audit.md +++ b/docs/superloopy-file-audit.md @@ -13,10 +13,10 @@ Superloopy is its own lightweight loop harness: one small CLI, repo-local `.supe | File | Original Superloopy role | Compatibility boundary | | --- | --- | --- | | `.agents/plugins/marketplace.json` | Repo-local Codex marketplace entry that exposes the root Superloopy plugin as `superloopy@beefiker`. | Uses Codex marketplace metadata only; points at this plugin root without vendoring external code. | -| `.codex/agents/zoro.toml` | Project-scoped Codex reviewer agent for bounded Superloopy subagent workflows. | Superloopy-native report contract plus advisory model policy; no product edits and no external workflow dependency. | -| `.codex/agents/franky.toml` | Project-scoped Codex executor agent for one criterion or independent slice. | Superloopy-native handoff, evidence receipt, and advisory model policy only. | -| `.codex/agents/jinbe.toml` | Project-scoped Codex gate reviewer for final evidence integration. | Uses Superloopy evidence, review, QA, audit, criteria coverage, and advisory model policy as the authority. | -| `.codex/agents/usopp.toml` | Project-scoped Codex QA agent for artifact-backed scenario evidence. | Superloopy-native QA report contract plus advisory model policy; no product edits. | +| `.codex/agents/zyro.toml` | Project-scoped Codex reviewer agent for bounded Superloopy subagent workflows. | Superloopy-native report contract plus advisory model policy; no product edits and no external workflow dependency. | +| `.codex/agents/fronk.toml` | Project-scoped Codex executor agent for one criterion or independent slice. | Superloopy-native handoff, evidence receipt, and advisory model policy only. | +| `.codex/agents/jumbo.toml` | Project-scoped Codex gate reviewer for final evidence integration. | Uses Superloopy evidence, review, QA, audit, criteria coverage, and advisory model policy as the authority. | +| `.codex/agents/usk.toml` | Project-scoped Codex QA agent for artifact-backed scenario evidence. | Superloopy-native QA report contract plus advisory model policy; no product edits. | | `.codex-plugin/plugin.json` | Local plugin metadata, hook registration, skill entry, and default Superloopy prompt. | Uses Codex plugin shape only; no external assets. | | `.gitignore` | Keeps runtime state, logs, coverage, and dependencies out of source control. | Superloopy runtime ignore set only. | | `LICENSE` | MIT license for this repo. | Standard license text. | @@ -25,13 +25,23 @@ Superloopy is its own lightweight loop harness: one small CLI, repo-local `.supe | `README.zh-CN.md` | Simplified Chinese public product overview translated from the root README. | Documentation-only locale surface; mirrors Superloopy behavior without adding runtime logic. | | `README.ja.md` | Japanese public product overview translated from the root README. | Documentation-only locale surface; mirrors Superloopy behavior without adding runtime logic. | | `README.es.md` | Spanish public product overview translated from the root README. | Documentation-only locale surface; mirrors Superloopy behavior without adding runtime logic. | -| `.github/assets/franky.png` | README crew-card image for the franky executor agent. | Documentation image only; no executable plugin logic. | -| `.github/assets/zoro.png` | README crew-card image for the zoro reviewer agent. | Documentation image only; no executable plugin logic. | -| `.github/assets/usopp.png` | README crew-card image for the usopp QA agent. | Documentation image only; no executable plugin logic. | -| `.github/assets/jinbe.png` | README crew-card image for the jinbe gate-reviewer agent. | Documentation image only; no executable plugin logic. | -| `.github/assets/robin.png` | README crew-card image for the robin auditor agent. | Documentation image only; no executable plugin logic. | -| `.github/assets/nami.png` | README crew-card image for the nami navigator agent. | Documentation image only; no executable plugin logic. | +| `.github/assets/fronk.png` | README crew-card image for the fronk executor agent. | Documentation image only; no executable plugin logic. | +| `.github/assets/zyro.png` | README crew-card image for the zyro reviewer agent. | Documentation image only; no executable plugin logic. | +| `.github/assets/usk.png` | README crew-card image for the usk QA agent. | Documentation image only; no executable plugin logic. | +| `.github/assets/jumbo.png` | README crew-card image for the jumbo gate-reviewer agent. | Documentation image only; no executable plugin logic. | +| `.github/assets/rovyn.png` | README crew-card image for the rovyn auditor agent. | Documentation image only; no executable plugin logic. | +| `.github/assets/nomi.png` | README crew-card image for the nomi navigator agent. | Documentation image only; no executable plugin logic. | | `.github/assets/transferloom-clone-reference.png` | README clone-demo screenshot showing the validated Transferloom.com Superloopy clone reference. | Documentation image only; generated from the local clone output and contains no executable plugin logic. | +| `web/README.md` | Static web demo deployment notes for the Superloopy landing page. | Documentation-only web surface; no runtime plugin logic. | +| `web/_headers` | Static hosting header rules for the web demo. | Web-hosting metadata only; does not affect CLI/runtime behavior. | +| `web/assets/fronk.png` | Web crew-card image for the fronk executor agent. | Website image only; no executable plugin logic. | +| `web/assets/zyro.png` | Web crew-card image for the zyro reviewer agent. | Website image only; no executable plugin logic. | +| `web/assets/usk.png` | Web crew-card image for the usk QA agent. | Website image only; no executable plugin logic. | +| `web/assets/jumbo.png` | Web crew-card image for the jumbo gate-reviewer agent. | Website image only; no executable plugin logic. | +| `web/assets/rovyn.png` | Web crew-card image for the rovyn auditor agent. | Website image only; no executable plugin logic. | +| `web/assets/nomi.png` | Web crew-card image for the nomi navigator agent. | Website image only; no executable plugin logic. | +| `web/assets/loopi.jpg` | Web landing-page hero image for Loopi. | Website image only; no executable plugin logic. | +| `web/index.html` | Static Superloopy landing page using owned role names and image assets. | Web demo only; package/runtime behavior stays in CLI, hooks, and skills. | | `docs/superloopy-design-audit.md` | Doctor-verified decision matrix for naming, compatibility, and threshold records. | Records Superloopy decisions, not source-project lineage. | | `docs/superloopy-crew-lines.md` | Crew-line precedent, policy, and runtime contract for presentation-only handoff flavor. | Keeps lines Superloopy-original and non-authoritative beside mechanical evidence state. | | `docs/superloopy-file-audit.md` | File-by-file audit and reviewability note. | Proves every Git-visible file has a role and boundary. | @@ -43,7 +53,7 @@ Superloopy is its own lightweight loop harness: one small CLI, repo-local `.supe | `hooks/session-start.json` | Provides first-launch bootstrap, marketplace update notices, and optional session-start context injection. | Routes through Superloopy CLI; bootstrap installs only the command wrapper and bundled agents, and update checks never run npx self-update for marketplace or checkout installs. | | `hooks/stop.json` | Provides optional stop continuation guard. | Routes through Superloopy CLI when enabled locally. | | `hooks/subagent-stop.json` | Registers evidence receipt verification for Superloopy executor, review, QA, and gate subagents. | Receipts use Superloopy evidence roots. | -| `hooks/subagent-stop-audit.json` | Registers robin verdict-receipt validation. | Verdict receipts use Superloopy evidence roots. | +| `hooks/subagent-stop-audit.json` | Registers rovyn verdict-receipt validation. | Verdict receipts use Superloopy evidence roots. | | `hooks/user-prompt-submit.json` | Registers steering and trigger-scoped context injection. | Structured `SUPERLOOPY_STEER` and explicit Superloopy prompt triggers only. | | `package.json` | Dependency-free Node package metadata, bin, and scripts including manifest version sync. | Keeps Superloopy small and dependency-free. | | `scripts/sync-version.mjs` | Release helper that stamps `package.json` and `.codex-plugin/plugin.json` from one authoritative Superloopy version. | Superloopy release metadata only; no runtime dependency or publishing side effect. | @@ -53,8 +63,8 @@ Superloopy is its own lightweight loop harness: one small CLI, repo-local `.supe | `skills/superloopy-loop/agents/openai.yaml` | Minimal agent metadata for Superloopy discovery. | Search terms are Superloopy-native. | | `skills/superloopy-research/SKILL.md` | Skill instructions for deep research with EXPAND waves, claim verification, cited synthesis, and Superloopy evidence artifacts. | Superloopy-native research workflow; workers return text and parent-owned artifacts remain authoritative. | | `skills/superloopy-research/agents/openai.yaml` | Minimal agent metadata for discovering the Superloopy research skill. | Superloopy-native skill metadata only. | -| `.codex/agents/robin.toml` | Read-only skeptical evidence-auditor agent, installed so the host can spawn the robin auditor by name. | Superloopy-native auditor contract plus advisory model policy. | -| `.codex/agents/nami.toml` | Read-only codebase-navigator agent for subagent-driven work; locates files and code and returns absolute paths, writing no evidence receipt. | Superloopy-native read-only search contract with fast advisory model defaults; no product edits and no host coupling. | +| `.codex/agents/rovyn.toml` | Read-only skeptical evidence-auditor agent, installed so the host can spawn the rovyn auditor by name. | Superloopy-native auditor contract plus advisory model policy. | +| `.codex/agents/nomi.toml` | Read-only codebase-navigator agent for subagent-driven work; locates files and code and returns absolute paths, writing no evidence receipt. | Superloopy-native read-only search contract with fast advisory model defaults; no product edits and no host coupling. | | `src/agents.js` | Installs bundled Superloopy custom agent TOML files, the command wrapper, and the combined bootstrap used by plugin startup. | Conservative Superloopy installer; skips identical files and requires `--force` for changed local files. | | `src/args.js` | Shared flag/stdin/JSON parsing helpers. | Generic Superloopy CLI utility. | | `src/artifacts.js` | Evidence path confinement, symlink rejection, and quality-gate dispatch. | Dispatches Superloopy review, matrix, and default gates. | @@ -62,7 +72,7 @@ Superloopy is its own lightweight loop harness: one small CLI, repo-local `.supe | `src/auto-update-plan.js` | Semver comparison, latest/current version resolution, install-flow routing, and default update command construction. | Superloopy-owned planning logic; npm lookup is advisory and can be overridden by environment for tests or future release channels. | | `src/auto-update-state.js` | Auto-update state, log, and lock file helpers. | Writes under Superloopy data paths or explicit env overrides; used only by the update checker. | | `src/audit.js` | Deterministic evidence auditor: re-runs command-backed criteria, hashes results, records audit-state, caches unchanged work; `auditOneCriterion` force-re-derives one criterion in-process for accept/gate time. | Superloopy-owned re-run anchor; never force-completes. | -| `src/audit-hooks.js` | Validates robin verdict receipts by RE-DERIVING the floor in-process (never trusting worker-writable recorded state), then hash-binding and floor-dominance; idempotent on replay. | Superloopy-native; LLM verdict advisory and downgrade-only. | +| `src/audit-hooks.js` | Validates rovyn verdict receipts by RE-DERIVING the floor in-process (never trusting worker-writable recorded state), then hash-binding and floor-dominance; idempotent on replay. | Superloopy-native; LLM verdict advisory and downgrade-only. | | `src/audit-verdict.js` | Structural verdict + gate-section validators and the symmetric floor-dominance cross-check (a non-pass floor surfaces, is never flipped by the LLM). | Deterministic; independence limits documented. | | `src/audit-gate-verify.js` | Completion-time provenance: re-derives every cited audit verdict so the deterministic spine actually gates aggregate completion. | Superloopy-native; closes the gate-decoupling gap. | | `src/begin.js` | One-command entrypoint that creates a plan and starts the first goal. | Superloopy-specific ease-of-start flow. | diff --git a/docs/superloopy-gate-notes.md b/docs/superloopy-gate-notes.md index 7567288..7dacd04 100644 --- a/docs/superloopy-gate-notes.md +++ b/docs/superloopy-gate-notes.md @@ -7,7 +7,7 @@ Superloopy keeps strict completion evidence while using Superloopy-owned names i - Default gate: `status: "passed"` plus non-empty artifact paths under the active evidence root. - Review gate: `codeReview`, `manualQa`, `gateReview`, `iteration`, `criteriaCoverage`, and `audit` sections must all validate. - Matrix gate: `architectReview`, `executorQa`, `iteration`, and `audit` sections must all validate. -- Audit section: `recommendation: "APPROVE"`, a non-empty `verdicts` array of resolvable verdict artifacts, and empty `blockers`. Mandatory for review and matrix gates; opt-in for the default gate via `SUPERLOOPY_AUDIT=on`. Structural validation only checks the section is well-formed and the verdict files resolve. **Completion-time provenance** (`audit-gate-verify.js`, wired into `review`/`checkpoint`) then re-derives **every passed criterion's** floor in-process (not just the cited ones) and requires each cited verdict to be a hash-bound pass over that fresh re-run — so a regressed command criterion can't be skipped and a section pointing at hand-written verdict files cannot authorize completion. The deterministic re-run is the source of truth, re-derived at decision time and never trusted from the worker-writable `.superloopy/audit-state.json`; the `robin` LLM verdict is advisory and downgrade-only. Scope limit: the deterministic guarantee is strong for **command-backed** criteria (Superloopy re-runs the command); a **manual (commandless)** criterion is re-validated for artifact existence only — its correctness rests on the auditor's judgment and human review, not the floor. Prefer command-backed proof. +- Audit section: `recommendation: "APPROVE"`, a non-empty `verdicts` array of resolvable verdict artifacts, and empty `blockers`. Mandatory for review and matrix gates; opt-in for the default gate via `SUPERLOOPY_AUDIT=on`. Structural validation only checks the section is well-formed and the verdict files resolve. **Completion-time provenance** (`audit-gate-verify.js`, wired into `review`/`checkpoint`) then re-derives **every passed criterion's** floor in-process (not just the cited ones) and requires each cited verdict to be a hash-bound pass over that fresh re-run — so a regressed command criterion can't be skipped and a section pointing at hand-written verdict files cannot authorize completion. The deterministic re-run is the source of truth, re-derived at decision time and never trusted from the worker-writable `.superloopy/audit-state.json`; the `rovyn` LLM verdict is advisory and downgrade-only. Scope limit: the deterministic guarantee is strong for **command-backed** criteria (Superloopy re-runs the command); a **manual (commandless)** criterion is re-validated for artifact existence only — its correctness rests on the auditor's judgment and human review, not the floor. Prefer command-backed proof. - Actor fields must be non-empty but are not tied to hard-coded role names. - Artifact references must resolve inside `.superloopy/evidence/` or the active scoped evidence root, must not be symlinks, and must be non-empty files. - `superloopy loop review --artifact` and `superloopy loop finish --artifact` write the machine quality gate and require a `.json` path. Human Markdown gate reports, such as a crew final-gate report, must be recorded as separate evidence artifacts. diff --git a/docs/superloopy-host-contract.md b/docs/superloopy-host-contract.md index 123002d..a47d28f 100644 --- a/docs/superloopy-host-contract.md +++ b/docs/superloopy-host-contract.md @@ -9,8 +9,8 @@ is visible and testable. `superloopy agents install` copies the bundled agent definitions into the personal Codex agents directory (`$CODEX_HOME/agents` when set, otherwise `~/.codex/agents`). The host spawns them through its native multi-agent dispatch when the parent delegates: the receipt workers -`franky`, `zoro`, `usopp`, `jinbe`, the read-only auditor `robin`, and the read-only navigator -`nami`. `superloopy doctor` (dispatchCoherence) fails if any agent Superloopy dispatches is not installed +`fronk`, `zyro`, `usk`, `jumbo`, the read-only auditor `rovyn`, and the read-only navigator +`nomi`. `superloopy doctor` (dispatchCoherence) fails if any agent Superloopy dispatches is not installed or not matched by a hook. Superloopy provisions and tracks these agents; the host spawns them. Superloopy never spawns. @@ -47,7 +47,7 @@ Superloopy's `SubagentStop` handlers read these fields from the JSON piped on st | Field | Use | |---|---| | `hook_event_name` | Must equal `SubagentStop`; otherwise the handler is a no-op. | -| `agent_type` | Matched against the hook matcher to pick the worker path (`franky`/`zoro`/`usopp`/`jinbe`), the auditor path (`robin`), or the read-only navigator path (`nami`, which writes no receipt so its handler is a no-op). | +| `agent_type` | Matched against the hook matcher to pick the worker path (`fronk`/`zyro`/`usk`/`jumbo`), the auditor path (`rovyn`), or the read-only navigator path (`nomi`, which writes no receipt so its handler is a no-op). | | `agent_id` | Keys the per-attempt counter. Optional — Superloopy falls back to a session/cwd key so the 3-attempt cap still counts. | | `session_id` | Selects scoped `.superloopy/sessions//` state when present. | | `cwd` | Repo root; required. | diff --git a/docs/superloopy-loop-golden-set.md b/docs/superloopy-loop-golden-set.md index 4a27d5e..9292d54 100644 --- a/docs/superloopy-loop-golden-set.md +++ b/docs/superloopy-loop-golden-set.md @@ -55,10 +55,10 @@ Total: 100 points. | File | Evidence anchor | Strict pass rule | | --- | --- | --- | | `.agents/plugins/marketplace.json` | `test/plugin.test.js`, audit coverage. | Must expose the root Superloopy plugin as an installable Codex marketplace entry. | -| `.codex/agents/zoro.toml` | `test/docs.test.js`, audit coverage. | Must define the Superloopy code-review role, active evidence root, advisory model defaults, and `SUPERLOOPY_EVIDENCE` receipt. | -| `.codex/agents/franky.toml` | `test/docs.test.js`, audit coverage. | Must define the bounded Superloopy executor role, active evidence root, advisory model defaults, and `SUPERLOOPY_EVIDENCE` receipt. | -| `.codex/agents/jinbe.toml` | `test/docs.test.js`, audit coverage. | Must define the Superloopy gate-review role, active evidence root, advisory model defaults, and `SUPERLOOPY_EVIDENCE` receipt. | -| `.codex/agents/usopp.toml` | `test/docs.test.js`, audit coverage. | Must define the Superloopy QA role, active evidence root, advisory model defaults, and `SUPERLOOPY_EVIDENCE` receipt. | +| `.codex/agents/zyro.toml` | `test/docs.test.js`, audit coverage. | Must define the Superloopy code-review role, active evidence root, advisory model defaults, and `SUPERLOOPY_EVIDENCE` receipt. | +| `.codex/agents/fronk.toml` | `test/docs.test.js`, audit coverage. | Must define the bounded Superloopy executor role, active evidence root, advisory model defaults, and `SUPERLOOPY_EVIDENCE` receipt. | +| `.codex/agents/jumbo.toml` | `test/docs.test.js`, audit coverage. | Must define the Superloopy gate-review role, active evidence root, advisory model defaults, and `SUPERLOOPY_EVIDENCE` receipt. | +| `.codex/agents/usk.toml` | `test/docs.test.js`, audit coverage. | Must define the Superloopy QA role, active evidence root, advisory model defaults, and `SUPERLOOPY_EVIDENCE` receipt. | | `.codex-plugin/plugin.json` | `test/plugin.test.js`, doctor plugin manifest check. | Must expose `./skills/` and the packaged Superloopy hook files, including opt-in Stop. | | `.gitignore` | Doctor runtime-boundary ignored samples and installed-cache docs coverage. | `.superloopy/`, logs, coverage, dependencies, OS noise, and Codex marketplace metadata must stay out of source control. | | `LICENSE` | Audit coverage and reviewability check. | Must remain a source file with no runtime implementation content. | @@ -67,13 +67,23 @@ Total: 100 points. | `README.zh-CN.md` | `test/docs.test.js`, audit coverage. | Must provide the Simplified Chinese README locale and keep install commands aligned with the root README. | | `README.ja.md` | `test/docs.test.js`, audit coverage. | Must provide the Japanese README locale and keep install commands aligned with the root README. | | `README.es.md` | `test/docs.test.js`, audit coverage. | Must provide the Spanish README locale and keep install commands aligned with the root README. | -| `.github/assets/franky.png` | Audit coverage. | Must remain a README documentation image, not runtime plugin logic. | -| `.github/assets/zoro.png` | Audit coverage. | Must remain a README documentation image, not runtime plugin logic. | -| `.github/assets/usopp.png` | Audit coverage. | Must remain a README documentation image, not runtime plugin logic. | -| `.github/assets/jinbe.png` | Audit coverage. | Must remain a README documentation image, not runtime plugin logic. | -| `.github/assets/robin.png` | Audit coverage. | Must remain a README documentation image, not runtime plugin logic. | -| `.github/assets/nami.png` | Audit coverage. | Must remain a README documentation image, not runtime plugin logic. | +| `.github/assets/fronk.png` | Audit coverage. | Must remain a README documentation image, not runtime plugin logic. | +| `.github/assets/zyro.png` | Audit coverage. | Must remain a README documentation image, not runtime plugin logic. | +| `.github/assets/usk.png` | Audit coverage. | Must remain a README documentation image, not runtime plugin logic. | +| `.github/assets/jumbo.png` | Audit coverage. | Must remain a README documentation image, not runtime plugin logic. | +| `.github/assets/rovyn.png` | Audit coverage. | Must remain a README documentation image, not runtime plugin logic. | +| `.github/assets/nomi.png` | Audit coverage. | Must remain a README documentation image, not runtime plugin logic. | | `.github/assets/transferloom-clone-reference.png` | Audit coverage and README clone-demo reference. | Must remain a documentation screenshot for the validated Transferloom.com clone, not runtime plugin logic. | +| `web/README.md` | Audit coverage. | Must describe the static web demo deployment boundary. | +| `web/_headers` | Audit coverage. | Must remain static web-hosting metadata only. | +| `web/assets/fronk.png` | Audit coverage. | Must remain a web documentation image, not runtime plugin logic. | +| `web/assets/zyro.png` | Audit coverage. | Must remain a web documentation image, not runtime plugin logic. | +| `web/assets/usk.png` | Audit coverage. | Must remain a web documentation image, not runtime plugin logic. | +| `web/assets/jumbo.png` | Audit coverage. | Must remain a web documentation image, not runtime plugin logic. | +| `web/assets/rovyn.png` | Audit coverage. | Must remain a web documentation image, not runtime plugin logic. | +| `web/assets/nomi.png` | Audit coverage. | Must remain a web documentation image, not runtime plugin logic. | +| `web/assets/loopi.jpg` | Audit coverage. | Must remain a web hero image, not runtime plugin logic. | +| `web/index.html` | Audit coverage. | Must keep the static landing page aligned with owned Superloopy role names and assets. | | `docs/superloopy-design-audit.md` | `src/design-audit.js`, `test/doctor.test.js`. | Must keep required decision rows with reason, effect, and guard. | | `docs/superloopy-crew-lines.md` | `test/docs.test.js`, audit coverage. | Must record the precedent pattern, no-copied-quotes rule, terminal-only behavior, and presentation-only authority boundary. | | `docs/superloopy-file-audit.md` | `test/audit.test.js`, `src/file-audit.js`, doctor file-audit check. | Must list every Git-visible file with non-empty role and compatibility-boundary cells. | @@ -85,7 +95,7 @@ Total: 100 points. | `hooks/session-start.json` | `test/golden-hooks.test.js`, doctor hook check. | Must route first-launch bootstrap, marketplace update notices, and optional SessionStart context through the Superloopy CLI. | | `hooks/stop.json` | Optional runtime hook file, direct hook tests. | Must route Stop continuation through the Superloopy CLI and stay inert unless `SUPERLOOPY_STOP_HOOK=on`. | | `hooks/subagent-stop.json` | `test/plugin.test.js`, doctor hook check. | Must route executor, review, QA, and gate SubagentStop receipt validation through the Superloopy CLI. | -| `hooks/subagent-stop-audit.json` | `test/plugin.test.js`, doctor hook check. | Must route robin verdict validation through the Superloopy CLI. | +| `hooks/subagent-stop-audit.json` | `test/plugin.test.js`, doctor hook check. | Must route rovyn verdict validation through the Superloopy CLI. | | `hooks/user-prompt-submit.json` | `test/plugin.test.js`, doctor hook check. | Must route prompt steering and trigger-scoped context injection through the Superloopy CLI. | | `package.json` | `npm test`, doctor dependency check. | Must stay dependency-free and expose `superloopy`, `test`, `check`, and `sync-version` scripts. | | `scripts/sync-version.mjs` | `test/sync-version.test.js`. | Must stamp `package.json` and `.codex-plugin/plugin.json` from one authoritative version without publishing or adding dependencies. | @@ -95,8 +105,8 @@ Total: 100 points. | `skills/superloopy-loop/agents/openai.yaml` | Audit coverage and reviewability check. | Must remain minimal Superloopy discovery metadata. | | `skills/superloopy-research/SKILL.md` | `test/plugin.test.js`, audit coverage. | Must describe exhaustive deep research with EXPAND waves, claim verification, cited synthesis, and Superloopy evidence receipts. | | `skills/superloopy-research/agents/openai.yaml` | Audit coverage and reviewability check. | Must remain minimal Superloopy discovery metadata for deep research. | -| `.codex/agents/robin.toml` | `test/cli.test.js`, `test/doctor.test.js`, audit coverage. | Must define the robin auditor role, advisory model defaults, and the SUPERLOOPY_AUDIT verdict receipt; installed via SUPERLOOPY_AGENT_NAMES. | -| `.codex/agents/nami.toml` | `test/cli.test.js`, `test/doctor.test.js`, audit coverage. | Must define the read-only navigator role, advisory fast model defaults, return absolute paths, and write no evidence receipt; installed via SUPERLOOPY_AGENT_NAMES and matched by a SubagentStop matcher. | +| `.codex/agents/rovyn.toml` | `test/cli.test.js`, `test/doctor.test.js`, audit coverage. | Must define the rovyn auditor role, advisory model defaults, and the SUPERLOOPY_AUDIT verdict receipt; installed via SUPERLOOPY_AGENT_NAMES. | +| `.codex/agents/nomi.toml` | `test/cli.test.js`, `test/doctor.test.js`, audit coverage. | Must define the read-only navigator role, advisory fast model defaults, return absolute paths, and write no evidence receipt; installed via SUPERLOOPY_AGENT_NAMES and matched by a SubagentStop matcher. | | `src/agents.js` | `test/cli.test.js`, `test/golden-hooks.test.js`, audit coverage. | Must install bundled Superloopy custom agents and command wrapper, skip identical files, and refuse changed local files unless `--force` is used. | | `src/args.js` | CLI and loop tests using parsed flags/stdin/JSON. | Must parse shared CLI inputs without dependencies. | | `src/artifacts.js` | Gate and evidence tests. | Must reject missing, empty, symlink, outside-root, and invalid gate artifacts. | diff --git a/docs/superloopy-model-policy.md b/docs/superloopy-model-policy.md index 93a7c74..2329569 100644 --- a/docs/superloopy-model-policy.md +++ b/docs/superloopy-model-policy.md @@ -19,12 +19,12 @@ Allowed service tiers: `priority`, `fast`, `efficient`. | Agent | Purpose | Model | Effort | Tier | | --- | --- | --- | --- | --- | -| `franky` | Bounded implementation lane. | `gpt-5.5` | `high` | `priority` | -| `zoro` | Skeptical code review lane. | `gpt-5.5` | `xhigh` | `priority` | -| `usopp` | QA and regression lane. | `gpt-5.5` | `high` | `priority` | -| `jinbe` | Final gate integration lane. | `gpt-5.5` | `xhigh` | `priority` | -| `robin` | Evidence auditor lane. | `gpt-5.5` | `high` | `priority` | -| `nami` | Read-only navigation lane. | `gpt-5.4-mini` | `low` | `fast` | +| `fronk` | Bounded implementation lane. | `gpt-5.5` | `high` | `priority` | +| `zyro` | Skeptical code review lane. | `gpt-5.5` | `xhigh` | `priority` | +| `usk` | QA and regression lane. | `gpt-5.5` | `high` | `priority` | +| `jumbo` | Final gate integration lane. | `gpt-5.5` | `xhigh` | `priority` | +| `rovyn` | Evidence auditor lane. | `gpt-5.5` | `high` | `priority` | +| `nomi` | Read-only navigation lane. | `gpt-5.4-mini` | `low` | `fast` | ## Rules diff --git a/hooks/subagent-stop-audit.json b/hooks/subagent-stop-audit.json index a565d06..6c8fade 100644 --- a/hooks/subagent-stop-audit.json +++ b/hooks/subagent-stop-audit.json @@ -2,7 +2,7 @@ "hooks": { "SubagentStop": [ { - "matcher": "^robin$", + "matcher": "^rovyn$", "hooks": [ { "type": "command", diff --git a/hooks/subagent-stop.json b/hooks/subagent-stop.json index 4fa4bf0..cd3525b 100644 --- a/hooks/subagent-stop.json +++ b/hooks/subagent-stop.json @@ -2,7 +2,7 @@ "hooks": { "SubagentStop": [ { - "matcher": "^(?:franky|zoro|usopp|jinbe)$", + "matcher": "^(?:fronk|zyro|usk|jumbo)$", "hooks": [ { "type": "command", @@ -13,7 +13,7 @@ ] }, { - "matcher": "^nami$", + "matcher": "^nomi$", "hooks": [ { "type": "command", diff --git a/skills/superloopy-clone/SKILL.md b/skills/superloopy-clone/SKILL.md index 1dfcdce..b2ddd4f 100644 --- a/skills/superloopy-clone/SKILL.md +++ b/skills/superloopy-clone/SKILL.md @@ -57,12 +57,12 @@ Use Superloopy actively when the clone has independent extraction, build, QA, or - Treat `loopy team ... loopy clone`, `loopy team clone`, `loopy crew ... clone`, `loopycrew ... clone`, and `ultrawork ... clone` as full-crew clone requests. Start with the crew plan, split extraction/build/QA/review lanes early, and record handoffs from the first dispatched lane. - A plain `loopy clone` may stay solo only for a small static page or one clearly bounded component. The moment there are multiple sections, responsive states, animations, unknown assets, or parallelizable QA/review work, escalate to crew dispatch instead of continuing solo. -- `nami`: read-only navigator for target app structure, candidate selectors, route layout, existing component patterns, and asset paths. Use before broad repo searches or when multiple search angles are needed. -- `franky`: builder for exactly one bounded component, wrapper, or asset integration slice. Give the full spec inline, allowed files, validation command, artifact target, and `SUPERLOOPY_EVIDENCE` requirement. -- `usopp`: QA lane for build/typecheck/browser checks, screenshot capture, interaction sweep replay, and evidence reports. -- `zoro`: drift reviewer. Ask it to compare implementation against the component spec and call out simplified lookalikes, missing states, missing assets, and wrong interaction models. -- `robin`: audit lane for high-risk evidence, source attribution, suspicious extraction gaps, and final claim review. It ends with `SUPERLOOPY_AUDIT: `. -- `jinbe`: final gate lane for fleet status, accepted evidence, outstanding blockers, and release readiness. +- `nomi`: read-only navigator for target app structure, candidate selectors, route layout, existing component patterns, and asset paths. Use before broad repo searches or when multiple search angles are needed. +- `fronk`: builder for exactly one bounded component, wrapper, or asset integration slice. Give the full spec inline, allowed files, validation command, artifact target, and `SUPERLOOPY_EVIDENCE` requirement. +- `usk`: QA lane for build/typecheck/browser checks, screenshot capture, interaction sweep replay, and evidence reports. +- `zyro`: drift reviewer. Ask it to compare implementation against the component spec and call out simplified lookalikes, missing states, missing assets, and wrong interaction models. +- `rovyn`: audit lane for high-risk evidence, source attribution, suspicious extraction gaps, and final claim review. It ends with `SUPERLOOPY_AUDIT: `. +- `jumbo`: final gate lane for fleet status, accepted evidence, outstanding blockers, and release readiness. Record every dispatch with `superloopy loop handoff --agent --assignment `. When a worker returns, update that handoff with `--verdict ` and `--artifact ` when accepted. Run `superloopy loop fleet --json` before any final completion claim. Accepted handoffs require artifacts under the active evidence root; an ack-only worker is inconclusive, never a pass. diff --git a/skills/superloopy-loop/SKILL.md b/skills/superloopy-loop/SKILL.md index b74624e..d8f92a3 100644 --- a/skills/superloopy-loop/SKILL.md +++ b/skills/superloopy-loop/SKILL.md @@ -39,7 +39,7 @@ The loop engineer directive is injected for every `loopy` prompt, and it scales - **Solo (default).** A plain `loopy ` drives one agent through the loop. The directive still permits light delegation: if the work splits into 2+ genuinely independent slices, you may fan them out in parallel with the host's native `multi_agent_v1.spawn_agent` (self-contained `message`, `fork_context: false`); for a single cohesive change, stay solo. - **Crew (`loopy team ` / `loopy crew `, the connected one-word `loopycrew `, or the standalone `ultrawork `).** The same engineer escalates into full fan-out: dispatch the crew across independent lanes, collect them with `multi_agent_v1.wait_agent`, and record only artifact-backed proof. The escalation keyword is stripped from the brief that seeds the loop. This is the active counterpart to "Optional Subagent-Driven Mode" below — same dispatch contract, receipt gate, and mandatory `handoff`/`fleet` tracking. -Each crew dispatch sets `agent_type` to the role so the host can load that role's TOML instructions and advisory model policy: `agent_type: "franky"` to build, `"zoro"` to review, `"usopp"` to test, `"jinbe"` to gate, `"robin"` to audit, `"nami"` to navigate. Because role routing and model defaults are best-effort across hosts, the `message` also stays self-contained (`TASK: act as ...`) so the worker behaves correctly even if the host ignores `agent_type`. +Each crew dispatch sets `agent_type` to the role so the host can load that role's TOML instructions and advisory model policy: `agent_type: "fronk"` to build, `"zyro"` to review, `"usk"` to test, `"jumbo"` to gate, `"rovyn"` to audit, `"nomi"` to navigate. Because role routing and model defaults are best-effort across hosts, the `message` also stays self-contained (`TASK: act as ...`) so the worker behaves correctly even if the host ignores `agent_type`. Both tiers are steering, not enforcement: the directive instructs the main agent, and actual spawning depends on the host's native multi-agent tool being available. Superloopy never spawns; it gates the evidence workers deliver. See "Optional Subagent-Driven Mode" for the full dispatch contract and crew roles. @@ -65,7 +65,7 @@ Superloopy detects the limit and pauses; *waking* when quota resets is an extern `superloopy loop audit` independently re-checks recorded proof. Superloopy itself re-runs each command-backed passed criterion (the deterministic source of truth) and records the result in `.superloopy/audit-state.json`; a re-run that does not reproduce is marked `inconclusive`, never a silent fail. -- For independent judgment, dispatch a read-only `robin` subagent: it judges the re-run against the scenario and ends with `SUPERLOOPY_AUDIT: `. When the receipt arrives, Superloopy **re-derives that criterion's floor in-process** (it does not trust the recorded `.superloopy/audit-state.json`, which the worker can write) and accepts the verdict only if it is hash-bound to that fresh re-run. Floor dominance is symmetric: the verdict may act only when the re-run reproduces — it can neither upgrade nor flip a non-reproducing (`inconclusive`) re-run. +- For independent judgment, dispatch a read-only `rovyn` subagent: it judges the re-run against the scenario and ends with `SUPERLOOPY_AUDIT: `. When the receipt arrives, Superloopy **re-derives that criterion's floor in-process** (it does not trust the recorded `.superloopy/audit-state.json`, which the worker can write) and accepts the verdict only if it is hash-bound to that fresh re-run. Floor dominance is symmetric: the verdict may act only when the re-run reproduces — it can neither upgrade nor flip a non-reproducing (`inconclusive`) re-run. - At completion the deterministic spine actually gates the result: `superloopy loop review`/`checkpoint` re-derive **every passed criterion** (not just the cited ones) and hash-verify every cited audit verdict, so a regressed command criterion can't be skipped and a structurally valid audit section pointing at hand-written verdict files cannot authorize completion. - Command-backed vs manual proof: the deterministic guarantee is strongest for **command-backed** criteria — Superloopy re-runs the command and reads the live exit code. A **manual (commandless)** criterion can only be re-validated for artifact existence; its correctness is not command-reproducible and rests on the auditor's (autonomous LLM) judgment and human review, not on the deterministic floor. **Prefer command-backed proof** (`superloopy loop prove -- `) wherever the work allows — the autonomous loop engineer does this by default, so most criteria get the strong guarantee automatically. - A failed audit (deterministic floor fail or a `verdict: fail`) flips the criterion off pass with the gap recorded in its notes, so the continuation engine re-drives exactly that criterion to be fixed and re-audited. A non-reproducing command re-run is `inconclusive` and never auto-flips (flaky-test safety). @@ -98,7 +98,7 @@ Parent agent responsibilities: Because role-by-name routing is unverified, each spawn message must stand alone — paste the role's requirements into it rather than relying on the agent name. Lead with an imperative `TASK:` and name the rest: - `TASK:` the one bounded assignment (one criterion or one non-overlapping slice). -- `DELIVERABLE:` the report artifact path under the active evidence root, and the required receipt (`SUPERLOOPY_EVIDENCE` for workers; `SUPERLOOPY_AUDIT` for `robin`; `nami` writes none). +- `DELIVERABLE:` the report artifact path under the active evidence root, and the required receipt (`SUPERLOOPY_EVIDENCE` for workers; `SUPERLOOPY_AUDIT` for `rovyn`; `nomi` writes none). - `SCOPE:` allowed files, the active evidence root, the validation command, and explicit non-goals. - `VERIFY:` the binary check that decides PASS/FAIL. @@ -112,12 +112,12 @@ State that it is an executable assignment, not a context handoff. Prefer a fresh Agent allocation: -- `franky`: edits one criterion or independent slice, writes a report, and ends with `SUPERLOOPY_EVIDENCE: `. -- `zoro`: reviews diff, scope, and evidence; writes a report under the active evidence root; does not edit product files. -- `usopp`: exercises happy-path, regression, and risk scenarios; writes artifact-backed QA evidence; does not edit product files. -- `jinbe`: integrates implementation, review, QA, audit, and criteria coverage; writes a final gate report such as `.superloopy/evidence/jinbe-final-gate-report.md`; the parent still runs Superloopy completion commands. -- `robin`: read-only, skeptical evidence auditor; judges Superloopy's deterministic re-run against the scenario and ends with `SUPERLOOPY_AUDIT: `. Installed by `superloopy agents install` alongside the workers. -- `nami`: read-only codebase navigator; locates files and code and returns absolute paths with a direct answer. Writes no evidence and edits nothing — dispatch it first to scope a slice before assigning an executor. Parallelize it with review/QA lanes. +- `fronk`: edits one criterion or independent slice, writes a report, and ends with `SUPERLOOPY_EVIDENCE: `. +- `zyro`: reviews diff, scope, and evidence; writes a report under the active evidence root; does not edit product files. +- `usk`: exercises happy-path, regression, and risk scenarios; writes artifact-backed QA evidence; does not edit product files. +- `jumbo`: integrates implementation, review, QA, audit, and criteria coverage; writes a final gate report such as `.superloopy/evidence/jumbo-final-gate-report.md`; the parent still runs Superloopy completion commands. +- `rovyn`: read-only, skeptical evidence auditor; judges Superloopy's deterministic re-run against the scenario and ends with `SUPERLOOPY_AUDIT: `. Installed by `superloopy agents install` alongside the workers. +- `nomi`: read-only codebase navigator; locates files and code and returns absolute paths with a direct answer. Writes no evidence and edits nothing — dispatch it first to scope a slice before assigning an executor. Parallelize it with review/QA lanes. ## Basic Flow @@ -179,7 +179,7 @@ Finish in one command after all criteria pass: superloopy loop finish --evidence "" --artifact .superloopy/evidence/gate.json --json ``` -Keep the human final gate report and the Superloopy quality gate artifact separate. A `jinbe` report is Markdown evidence (for example `.superloopy/evidence/jinbe-final-gate-report.md`). The `superloopy loop review` and `superloopy loop finish --artifact` flag writes the machine-validated quality gate artifact and must point to JSON, normally `.superloopy/evidence/gate.json`. Never pass the Markdown report path as the finish artifact. +Keep the human final gate report and the Superloopy quality gate artifact separate. A `jumbo` report is Markdown evidence (for example `.superloopy/evidence/jumbo-final-gate-report.md`). The `superloopy loop review` and `superloopy loop finish --artifact` flag writes the machine-validated quality gate artifact and must point to JSON, normally `.superloopy/evidence/gate.json`. Never pass the Markdown report path as the finish artifact. For custom gate workflows: diff --git a/src/agents.js b/src/agents.js index dfc2952..d279a38 100644 --- a/src/agents.js +++ b/src/agents.js @@ -5,18 +5,18 @@ import { fileURLToPath } from "node:url"; import { homedir } from "node:os"; import { hasFlag, readFlag } from "./args.js"; -// Worker agents (franky/zoro/usopp/jinbe) report evidence receipts; robin is the -// read-only auditor; nami is the read-only navigator (no receipt). All are installed so -// the host can dispatch them; robin was historically shipped only as un-installable skill +// Worker agents (fronk/zyro/usk/jumbo) report evidence receipts; rovyn is the +// read-only auditor; nomi is the read-only navigator (no receipt). All are installed so +// the host can dispatch them; rovyn was historically shipped only as un-installable skill // metadata (the auditor-install gap). Host role-by-name routing is NOT guaranteed, so a // dispatch must be self-contained — see docs/superloopy-host-contract.md. export const SUPERLOOPY_AGENT_NAMES = [ - "franky", - "zoro", - "usopp", - "jinbe", - "robin", - "nami" + "fronk", + "zyro", + "usk", + "jumbo", + "rovyn", + "nomi" ]; const REPO_ROOT = dirname(dirname(fileURLToPath(import.meta.url))); diff --git a/src/audit-hooks.js b/src/audit-hooks.js index 8d56ff8..6bd9680 100644 --- a/src/audit-hooks.js +++ b/src/audit-hooks.js @@ -1,4 +1,4 @@ -// SubagentStop handler for the read-only robin subagent. It validates +// SubagentStop handler for the read-only rovyn subagent. It validates // the auditor's verdict RECEIPT deterministically. Crucially it does NOT trust the // recorded .superloopy/audit-state.json (worker-writable): on each receipt it RE-DERIVES // the cited criterion's floor in-process (auditOneCriterion) and accepts the verdict @@ -30,7 +30,7 @@ const CONTEXT_PRESSURE_MARKERS = [ export async function runAuditorStopHook(payload) { if (payload === null || typeof payload !== "object") return ""; if (payload.hook_event_name !== "SubagentStop") return ""; - if (payload.agent_type !== "robin") return ""; + if (payload.agent_type !== "rovyn") return ""; if (typeof payload.cwd !== "string") return ""; if (transcriptTailHasMarker(payload.transcript_path, CONTEXT_PRESSURE_MARKERS)) return ""; diff --git a/src/audit-verdict.js b/src/audit-verdict.js index 2a323a7..a8fb08c 100644 --- a/src/audit-verdict.js +++ b/src/audit-verdict.js @@ -1,4 +1,4 @@ -// Deterministic validation for the robin's verdict (the LLM judgment). +// Deterministic validation for the rovyn's verdict (the LLM judgment). // // Superloopy treats the LLM verdict as ADVISORY and DOWNGRADE-ONLY: it can never // turn a deterministic re-run failure/inconclusive into a pass. The hard diff --git a/src/audit.js b/src/audit.js index cc1d4d4..215222d 100644 --- a/src/audit.js +++ b/src/audit.js @@ -3,7 +3,7 @@ // Superloopy owns the trustworthy part: it re-runs each command-backed passed // criterion in-process (the exact capture path), hashes the result, and records // it in .superloopy/audit-state.json. This is the source of truth. The independent -// LLM judgment is layered on top by a host-dispatched read-only robin +// LLM judgment is layered on top by a host-dispatched read-only rovyn // subagent whose verdict is validated against THIS state (see audit-hooks.js). // // The deterministic floor: a re-run that reproduces (exit 0) is "pass" and may @@ -203,7 +203,7 @@ function renderAuditDispatch(scope, pending) { "" ]; for (const entry of pending) { - lines.push(`- ${entry.criterion}: \`task(subagent_type="robin", run_in_background=false)\` — cite re-run artifact \`${entry.rerunArtifact}\` against the scenario; write verdict to \`${evidenceRelativeDir(scope)}/audit/${entry.criterion.replace("/", "-")}-verdict.json\`.`); + lines.push(`- ${entry.criterion}: \`task(subagent_type="rovyn", run_in_background=false)\` — cite re-run artifact \`${entry.rerunArtifact}\` against the scenario; write verdict to \`${evidenceRelativeDir(scope)}/audit/${entry.criterion.replace("/", "-")}-verdict.json\`.`); } lines.push("", `The auditor must be read-only and skeptical. A pass requires citing the re-run artifact. Re-check status with \`superloopy loop audit${sessionFlag} --json\`.`); return lines.join("\n"); diff --git a/src/crew-lines.js b/src/crew-lines.js index 96a1887..8321093 100644 --- a/src/crew-lines.js +++ b/src/crew-lines.js @@ -1,142 +1,142 @@ const VERDICT_KEYS = ["accept", "reject", "needs-context"]; const DEFAULT_SPEAKERS = Object.freeze({ - franky: "Franky", - zoro: "Zoro", - usopp: "Usopp", - jinbe: "Jinbe", - robin: "Robin", - nami: "Nami" + fronk: "Fronk", + zyro: "Zyro", + usk: "Usk", + jumbo: "Jumbo", + rovyn: "Rovyn", + nomi: "Nomi" }); const CREW_LINE_CATALOG = Object.freeze({ en: locale(null, { - franky: ["Parts fit. The build holds.", "The frame is off. Rework the loose piece.", "The blueprint is short. Bring the missing spec."], - zoro: ["Review is done. No blocking edge remains.", "The path is off. Fix the blocking edge.", "I need a clearer trail before I can call this."], - usopp: ["Target checked. The test passed.", "The shot missed. Reproduce the failure and adjust.", "No target yet. Give me the exact scenario."], - jinbe: ["The flow is steady. This gate can close.", "The current is wrong. Hold the gate and repair it.", "The tide is unclear. Bring the missing proof first."], - robin: ["Record checked. Evidence and conclusion agree.", "The record disagrees. This conclusion cannot stand.", "The archive is incomplete. Add the missing evidence."], - nami: ["Route checked. The next step is clear.", "The route is unsafe. Correct the course first.", "The map has a blank spot. Mark the missing path."] + fronk: ["Parts fit. The build holds.", "The frame is off. Rework the loose piece.", "The blueprint is short. Bring the missing spec."], + zyro: ["Review is done. No blocking edge remains.", "The path is off. Fix the blocking edge.", "I need a clearer trail before I can call this."], + usk: ["Target checked. The test passed.", "The shot missed. Reproduce the failure and adjust.", "No target yet. Give me the exact scenario."], + jumbo: ["The flow is steady. This gate can close.", "The current is wrong. Hold the gate and repair it.", "The tide is unclear. Bring the missing proof first."], + rovyn: ["Record checked. Evidence and conclusion agree.", "The record disagrees. This conclusion cannot stand.", "The archive is incomplete. Add the missing evidence."], + nomi: ["Route checked. The next step is clear.", "The route is unsafe. Correct the course first.", "The map has a blank spot. Mark the missing path."] }), - ko: locale({ franky: "프랭키", zoro: "조로", usopp: "우솝", jinbe: "징베", robin: "로빈", nami: "나미" }, { - franky: ["부품이 맞았고 빌드도 버틴다.", "프레임이 어긋났다. 헐거운 부분부터 다시 잡자.", "설계도가 부족하다. 빠진 조건을 먼저 가져와라."], - zoro: ["리뷰는 끝났다. 막는 결함은 없다.", "길이 어긋났다. 막는 결함부터 베어내자.", "판단할 길이 흐리다. 증거를 더 밝혀라."], - usopp: ["표적 확인. 테스트는 통과했다.", "탄착이 빗나갔다. 실패를 재현하고 다시 조준하자.", "아직 표적이 없다. 정확한 시나리오를 줘라."], - jinbe: ["흐름은 안정됐다. 이 게이트는 닫아도 된다.", "흐름이 거칠다. 게이트를 잡고 고쳐라.", "물길이 흐리다. 빠진 증거부터 가져와라."], - robin: ["기록 확인. 증거와 결론이 일치한다.", "기록이 어긋난다. 이 결론은 세울 수 없다.", "기록이 비었다. 빠진 증거를 보태라."], - nami: ["항로 확인. 다음 단계는 맑다.", "항로가 위험하다. 먼저 방향을 바로잡자.", "지도에 빈칸이 있다. 빠진 경로를 표시해라."] + ko: locale({ fronk: "Fronk", zyro: "Zyro", usk: "Usk", jumbo: "Jumbo", rovyn: "Rovyn", nomi: "Nomi" }, { + fronk: ["부품이 맞았고 빌드도 버틴다.", "프레임이 어긋났다. 헐거운 부분부터 다시 잡자.", "설계도가 부족하다. 빠진 조건을 먼저 가져와라."], + zyro: ["리뷰는 끝났다. 막는 결함은 없다.", "길이 어긋났다. 막는 결함부터 베어내자.", "판단할 길이 흐리다. 증거를 더 밝혀라."], + usk: ["표적 확인. 테스트는 통과했다.", "탄착이 빗나갔다. 실패를 재현하고 다시 조준하자.", "아직 표적이 없다. 정확한 시나리오를 줘라."], + jumbo: ["흐름은 안정됐다. 이 게이트는 닫아도 된다.", "흐름이 거칠다. 게이트를 잡고 고쳐라.", "물길이 흐리다. 빠진 증거부터 가져와라."], + rovyn: ["기록 확인. 증거와 결론이 일치한다.", "기록이 어긋난다. 이 결론은 세울 수 없다.", "기록이 비었다. 빠진 증거를 보태라."], + nomi: ["항로 확인. 다음 단계는 맑다.", "항로가 위험하다. 먼저 방향을 바로잡자.", "지도에 빈칸이 있다. 빠진 경로를 표시해라."] }), - ja: locale({ franky: "フランキー", zoro: "ゾロ", usopp: "ウソップ", jinbe: "ジンベエ", robin: "ロビン", nami: "ナミ" }, { - franky: ["部品は噛み合った。ビルドも持つ。", "フレームがずれている。緩い部分を直そう。", "設計図が足りない。必要な条件を出してくれ。"], - zoro: ["レビュー完了。止める刃は残っていない。", "道が外れている。止める傷を直せ。", "判断する道筋が薄い。証拠を足してくれ。"], - usopp: ["標的確認。テストは通った。", "着弾が外れた。失敗を再現して狙い直そう。", "まだ標的がない。正確なシナリオをくれ。"], - jinbe: ["流れは安定した。このゲートは閉じられる。", "流れが荒い。ゲートを保って直そう。", "水路が見えない。足りない証拠を先に出してくれ。"], - robin: ["記録確認。証拠と結論は一致している。", "記録が食い違う。この結論は立たない。", "記録が欠けている。足りない証拠を追加して。"], - nami: ["航路確認。次の一手は晴れている。", "航路が危ない。まず方向を直そう。", "地図に空白がある。足りない道を示して。"] + ja: locale({ fronk: "Fronk", zyro: "Zyro", usk: "Usk", jumbo: "Jumbo", rovyn: "Rovyn", nomi: "Nomi" }, { + fronk: ["部品は噛み合った。ビルドも持つ。", "フレームがずれている。緩い部分を直そう。", "設計図が足りない。必要な条件を出してくれ。"], + zyro: ["レビュー完了。止める刃は残っていない。", "道が外れている。止める傷を直せ。", "判断する道筋が薄い。証拠を足してくれ。"], + usk: ["標的確認。テストは通った。", "着弾が外れた。失敗を再現して狙い直そう。", "まだ標的がない。正確なシナリオをくれ。"], + jumbo: ["流れは安定した。このゲートは閉じられる。", "流れが荒い。ゲートを保って直そう。", "水路が見えない。足りない証拠を先に出してくれ。"], + rovyn: ["記録確認。証拠と結論は一致している。", "記録が食い違う。この結論は立たない。", "記録が欠けている。足りない証拠を追加して。"], + nomi: ["航路確認。次の一手は晴れている。", "航路が危ない。まず方向を直そう。", "地図に空白がある。足りない道を示して。"] }), - zh: locale({ franky: "弗兰奇", zoro: "索隆", usopp: "乌索普", jinbe: "甚平", robin: "罗宾", nami: "娜美" }, { - franky: ["部件已经吻合,构建站得住。", "框架偏了,先修松动处。", "蓝图不完整,先补上缺的条件。"], - zoro: ["审查完成,没有阻塞项。", "路线偏了,先修阻塞项。", "证据路径不清,先补足再判断。"], - usopp: ["目标确认,测试通过。", "命中偏了,复现失败后再校准。", "目标还不清,给出准确场景。"], - jinbe: ["流程稳定,这道门可以关闭。", "水流不稳,先守住门再修。", "水路不明,先带来缺失证据。"], - robin: ["记录确认,证据和结论一致。", "记录冲突,这个结论不能成立。", "档案缺页,补上缺失证据。"], - nami: ["航线确认,下一步清楚。", "航线有险,先修正方向。", "地图有空白,标出缺失路径。"] + zh: locale({ fronk: "Fronk", zyro: "Zyro", usk: "Usk", jumbo: "Jumbo", rovyn: "Rovyn", nomi: "Nomi" }, { + fronk: ["部件已经吻合,构建站得住。", "框架偏了,先修松动处。", "蓝图不完整,先补上缺的条件。"], + zyro: ["审查完成,没有阻塞项。", "路线偏了,先修阻塞项。", "证据路径不清,先补足再判断。"], + usk: ["目标确认,测试通过。", "命中偏了,复现失败后再校准。", "目标还不清,给出准确场景。"], + jumbo: ["流程稳定,这道门可以关闭。", "水流不稳,先守住门再修。", "水路不明,先带来缺失证据。"], + rovyn: ["记录确认,证据和结论一致。", "记录冲突,这个结论不能成立。", "档案缺页,补上缺失证据。"], + nomi: ["航线确认,下一步清楚。", "航线有险,先修正方向。", "地图有空白,标出缺失路径。"] }), es: locale(null, { - franky: ["Las piezas encajan. La build resiste.", "El marco falla. Ajusta la pieza floja.", "Falta el plano. Trae la especificación pendiente."], - zoro: ["Revisión lista. No queda bloqueo.", "La ruta está mal. Corrige el bloqueo.", "Necesito un rastro más claro para decidir."], - usopp: ["Objetivo confirmado. La prueba pasó.", "El disparo falló. Reproduce el fallo y ajusta.", "Aún no hay objetivo. Dame el escenario exacto."], - jinbe: ["El flujo está estable. Este gate puede cerrarse.", "La corriente va mal. Sostén el gate y repara.", "La marea no está clara. Trae primero la prueba faltante."], - robin: ["Registro revisado. Evidencia y conclusión coinciden.", "El registro no coincide. Esta conclusión no se sostiene.", "El archivo está incompleto. Añade la evidencia faltante."], - nami: ["Ruta revisada. El siguiente paso está claro.", "La ruta es insegura. Corrige el rumbo primero.", "Hay un hueco en el mapa. Marca la ruta faltante."] + fronk: ["Las piezas encajan. La build resiste.", "El marco falla. Ajusta la pieza floja.", "Falta el plano. Trae la especificación pendiente."], + zyro: ["Revisión lista. No queda bloqueo.", "La ruta está mal. Corrige el bloqueo.", "Necesito un rastro más claro para decidir."], + usk: ["Objetivo confirmado. La prueba pasó.", "El disparo falló. Reproduce el fallo y ajusta.", "Aún no hay objetivo. Dame el escenario exacto."], + jumbo: ["El flujo está estable. Este gate puede cerrarse.", "La corriente va mal. Sostén el gate y repara.", "La marea no está clara. Trae primero la prueba faltante."], + rovyn: ["Registro revisado. Evidencia y conclusión coinciden.", "El registro no coincide. Esta conclusión no se sostiene.", "El archivo está incompleto. Añade la evidencia faltante."], + nomi: ["Ruta revisada. El siguiente paso está claro.", "La ruta es insegura. Corrige el rumbo primero.", "Hay un hueco en el mapa. Marca la ruta faltante."] }), fr: locale(null, { - franky: ["Les pièces s'accordent. Le build tient.", "La structure dévie. Répare la pièce lâche.", "Le plan est incomplet. Ajoute la spécification manquante."], - zoro: ["Revue terminée. Aucun blocage restant.", "Le chemin dévie. Corrige le blocage.", "La piste manque de preuves. Ajoute ce qui manque."], - usopp: ["Cible confirmée. Le test est passé.", "Le tir a raté. Reproduis l'échec et ajuste.", "Pas encore de cible. Donne le scénario exact."], - jinbe: ["Le flux est stable. Ce gate peut se fermer.", "Le courant est mauvais. Garde le gate et répare.", "La marée est floue. Apporte d'abord la preuve manquante."], - robin: ["Dossier vérifié. Preuve et conclusion concordent.", "Le dossier contredit la conclusion. Elle ne tient pas.", "L'archive est incomplète. Ajoute la preuve manquante."], - nami: ["Route vérifiée. La prochaine étape est claire.", "La route est risquée. Corrige le cap d'abord.", "La carte a un blanc. Marque le chemin manquant."] + fronk: ["Les pièces s'accordent. Le build tient.", "La structure dévie. Répare la pièce lâche.", "Le plan est incomplet. Ajoute la spécification manquante."], + zyro: ["Revue terminée. Aucun blocage restant.", "Le chemin dévie. Corrige le blocage.", "La piste manque de preuves. Ajoute ce qui manque."], + usk: ["Cible confirmée. Le test est passé.", "Le tir a raté. Reproduis l'échec et ajuste.", "Pas encore de cible. Donne le scénario exact."], + jumbo: ["Le flux est stable. Ce gate peut se fermer.", "Le courant est mauvais. Garde le gate et répare.", "La marée est floue. Apporte d'abord la preuve manquante."], + rovyn: ["Dossier vérifié. Preuve et conclusion concordent.", "Le dossier contredit la conclusion. Elle ne tient pas.", "L'archive est incomplète. Ajoute la preuve manquante."], + nomi: ["Route vérifiée. La prochaine étape est claire.", "La route est risquée. Corrige le cap d'abord.", "La carte a un blanc. Marque le chemin manquant."] }), de: locale(null, { - franky: ["Die Teile sitzen. Der Build hält.", "Der Rahmen ist schief. Repariere das lose Teil.", "Der Plan ist unvollständig. Bring die fehlende Vorgabe."], - zoro: ["Review erledigt. Kein Blocker bleibt.", "Der Pfad ist falsch. Behebe den Blocker.", "Die Spur ist zu dünn. Bring erst mehr Beweise."], - usopp: ["Ziel bestätigt. Der Test ist durch.", "Der Schuss ging daneben. Reproduziere den Fehler und justiere.", "Noch kein klares Ziel. Gib das genaue Szenario."], - jinbe: ["Der Fluss ist ruhig. Dieses Gate kann schließen.", "Die Strömung stimmt nicht. Halte das Gate und repariere.", "Die Lage ist unklar. Bring zuerst den fehlenden Beweis."], - robin: ["Akte geprüft. Beweis und Schluss passen.", "Die Akte widerspricht sich. Dieser Schluss hält nicht.", "Das Archiv ist lückenhaft. Ergänze den fehlenden Beweis."], - nami: ["Route geprüft. Der nächste Schritt ist klar.", "Die Route ist unsicher. Korrigiere zuerst den Kurs.", "Auf der Karte fehlt etwas. Markiere den fehlenden Pfad."] + fronk: ["Die Teile sitzen. Der Build hält.", "Der Rahmen ist schief. Repariere das lose Teil.", "Der Plan ist unvollständig. Bring die fehlende Vorgabe."], + zyro: ["Review erledigt. Kein Blocker bleibt.", "Der Pfad ist falsch. Behebe den Blocker.", "Die Spur ist zu dünn. Bring erst mehr Beweise."], + usk: ["Ziel bestätigt. Der Test ist durch.", "Der Schuss ging daneben. Reproduziere den Fehler und justiere.", "Noch kein klares Ziel. Gib das genaue Szenario."], + jumbo: ["Der Fluss ist ruhig. Dieses Gate kann schließen.", "Die Strömung stimmt nicht. Halte das Gate und repariere.", "Die Lage ist unklar. Bring zuerst den fehlenden Beweis."], + rovyn: ["Akte geprüft. Beweis und Schluss passen.", "Die Akte widerspricht sich. Dieser Schluss hält nicht.", "Das Archiv ist lückenhaft. Ergänze den fehlenden Beweis."], + nomi: ["Route geprüft. Der nächste Schritt ist klar.", "Die Route ist unsicher. Korrigiere zuerst den Kurs.", "Auf der Karte fehlt etwas. Markiere den fehlenden Pfad."] }), it: locale(null, { - franky: ["I pezzi combaciano. La build regge.", "Il telaio è fuori linea. Sistema il pezzo lento.", "Il progetto è incompleto. Porta la specifica mancante."], - zoro: ["Revisione chiusa. Non resta un blocco.", "Il sentiero è sbagliato. Correggi il blocco.", "La traccia è troppo debole. Aggiungi prove."], - usopp: ["Bersaglio confermato. Il test è passato.", "Il colpo è andato fuori. Riproduci l'errore e regola.", "Manca il bersaglio. Dammi lo scenario preciso."], - jinbe: ["Il flusso è stabile. Questo gate può chiudersi.", "La corrente è sbagliata. Tieni il gate e ripara.", "La marea è poco chiara. Porta prima la prova mancante."], - robin: ["Registro verificato. Prova e conclusione combaciano.", "Il registro non torna. Questa conclusione non regge.", "L'archivio è incompleto. Aggiungi la prova mancante."], - nami: ["Rotta verificata. Il prossimo passo è chiaro.", "La rotta è rischiosa. Correggi prima la direzione.", "La mappa ha un vuoto. Segna il percorso mancante."] + fronk: ["I pezzi combaciano. La build regge.", "Il telaio è fuori linea. Sistema il pezzo lento.", "Il progetto è incompleto. Porta la specifica mancante."], + zyro: ["Revisione chiusa. Non resta un blocco.", "Il sentiero è sbagliato. Correggi il blocco.", "La traccia è troppo debole. Aggiungi prove."], + usk: ["Bersaglio confermato. Il test è passato.", "Il colpo è andato fuori. Riproduci l'errore e regola.", "Manca il bersaglio. Dammi lo scenario preciso."], + jumbo: ["Il flusso è stabile. Questo gate può chiudersi.", "La corrente è sbagliata. Tieni il gate e ripara.", "La marea è poco chiara. Porta prima la prova mancante."], + rovyn: ["Registro verificato. Prova e conclusione combaciano.", "Il registro non torna. Questa conclusione non regge.", "L'archivio è incompleto. Aggiungi la prova mancante."], + nomi: ["Rotta verificata. Il prossimo passo è chiaro.", "La rotta è rischiosa. Correggi prima la direzione.", "La mappa ha un vuoto. Segna il percorso mancante."] }), pt: locale(null, { - franky: ["As peças encaixam. O build segura.", "A estrutura saiu do lugar. Refaça a peça solta.", "O plano está curto. Traga a especificação faltante."], - zoro: ["Revisão pronta. Nenhum bloqueio ficou.", "O caminho está errado. Corrija o bloqueio.", "A trilha está fraca. Traga mais evidência antes."], - usopp: ["Alvo confirmado. O teste passou.", "O disparo errou. Reproduza a falha e ajuste.", "Ainda não há alvo. Dê o cenário exato."], - jinbe: ["O fluxo está estável. Este gate pode fechar.", "A corrente está errada. Segure o gate e repare.", "A maré está incerta. Traga primeiro a prova faltante."], - robin: ["Registro conferido. Evidência e conclusão batem.", "O registro discorda. Essa conclusão não se sustenta.", "O arquivo está incompleto. Adicione a evidência faltante."], - nami: ["Rota conferida. O próximo passo está claro.", "A rota é insegura. Corrija o curso primeiro.", "Há um vazio no mapa. Marque o caminho faltante."] + fronk: ["As peças encaixam. O build segura.", "A estrutura saiu do lugar. Refaça a peça solta.", "O plano está curto. Traga a especificação faltante."], + zyro: ["Revisão pronta. Nenhum bloqueio ficou.", "O caminho está errado. Corrija o bloqueio.", "A trilha está fraca. Traga mais evidência antes."], + usk: ["Alvo confirmado. O teste passou.", "O disparo errou. Reproduza a falha e ajuste.", "Ainda não há alvo. Dê o cenário exato."], + jumbo: ["O fluxo está estável. Este gate pode fechar.", "A corrente está errada. Segure o gate e repare.", "A maré está incerta. Traga primeiro a prova faltante."], + rovyn: ["Registro conferido. Evidência e conclusão batem.", "O registro discorda. Essa conclusão não se sustenta.", "O arquivo está incompleto. Adicione a evidência faltante."], + nomi: ["Rota conferida. O próximo passo está claro.", "A rota é insegura. Corrija o curso primeiro.", "Há um vazio no mapa. Marque o caminho faltante."] }), id: locale(null, { - franky: ["Komponen pas. Build bertahan.", "Rangkanya meleset. Perbaiki bagian yang longgar.", "Blueprint kurang lengkap. Bawa spesifikasi yang hilang."], - zoro: ["Review selesai. Tidak ada blocker tersisa.", "Jalurnya salah. Perbaiki blocker dulu.", "Jejaknya belum jelas. Tambahkan bukti dulu."], - usopp: ["Target jelas. Tes lulus.", "Tembakan meleset. Reproduksi kegagalan lalu setel lagi.", "Target belum ada. Beri skenario yang tepat."], - jinbe: ["Alurnya stabil. Gate ini bisa ditutup.", "Arusnya salah. Tahan gate dan perbaiki.", "Arus belum jelas. Bawa bukti yang hilang dulu."], - robin: ["Catatan dicek. Bukti dan kesimpulan cocok.", "Catatan bertentangan. Kesimpulan ini belum berdiri.", "Arsip belum lengkap. Tambahkan bukti yang hilang."], - nami: ["Rute dicek. Langkah berikutnya jelas.", "Rute tidak aman. Luruskan arah dulu.", "Ada bagian kosong di peta. Tandai jalur yang hilang."] + fronk: ["Komponen pas. Build bertahan.", "Rangkanya meleset. Perbaiki bagian yang longgar.", "Blueprint kurang lengkap. Bawa spesifikasi yang hilang."], + zyro: ["Review selesai. Tidak ada blocker tersisa.", "Jalurnya salah. Perbaiki blocker dulu.", "Jejaknya belum jelas. Tambahkan bukti dulu."], + usk: ["Target jelas. Tes lulus.", "Tembakan meleset. Reproduksi kegagalan lalu setel lagi.", "Target belum ada. Beri skenario yang tepat."], + jumbo: ["Alurnya stabil. Gate ini bisa ditutup.", "Arusnya salah. Tahan gate dan perbaiki.", "Arus belum jelas. Bawa bukti yang hilang dulu."], + rovyn: ["Catatan dicek. Bukti dan kesimpulan cocok.", "Catatan bertentangan. Kesimpulan ini belum berdiri.", "Arsip belum lengkap. Tambahkan bukti yang hilang."], + nomi: ["Rute dicek. Langkah berikutnya jelas.", "Rute tidak aman. Luruskan arah dulu.", "Ada bagian kosong di peta. Tandai jalur yang hilang."] }), hi: locale(null, { - franky: ["हिस्से फिट हैं। बिल्ड टिकता है।", "फ्रेम टेढ़ा है। ढीला हिस्सा सुधारो।", "नक्शा अधूरा है। छूटी शर्त लाओ।"], - zoro: ["रिव्यू पूरा। कोई रोकने वाली कमी नहीं।", "रास्ता बिगड़ा है। रोकने वाली कमी सुधारो।", "सबूत की राह साफ नहीं। पहले सबूत जोड़ो।"], - usopp: ["निशाना पक्का। टेस्ट पास हुआ।", "वार चूक गया। विफलता दोहराकर फिर निशाना लगाओ।", "निशाना साफ नहीं। सटीक परिदृश्य दो।"], - jinbe: ["बहाव स्थिर है। यह गेट बंद हो सकता है।", "बहाव खराब है। गेट रोको और सुधारो।", "रास्ता धुंधला है। पहले छूटा सबूत लाओ।"], - robin: ["रिकॉर्ड जांचा। सबूत और निष्कर्ष मिलते हैं।", "रिकॉर्ड टकराता है। यह निष्कर्ष नहीं टिकेगा।", "अभिलेख अधूरा है। छूटा सबूत जोड़ो।"], - nami: ["रास्ता जांचा। अगला कदम साफ है।", "रास्ता असुरक्षित है। पहले दिशा सुधारो।", "नक्शे में खाली जगह है। छूटा रास्ता चिह्नित करो।"] + fronk: ["हिस्से फिट हैं। बिल्ड टिकता है।", "फ्रेम टेढ़ा है। ढीला हिस्सा सुधारो।", "नक्शा अधूरा है। छूटी शर्त लाओ।"], + zyro: ["रिव्यू पूरा। कोई रोकने वाली कमी नहीं।", "रास्ता बिगड़ा है। रोकने वाली कमी सुधारो।", "सबूत की राह साफ नहीं। पहले सबूत जोड़ो।"], + usk: ["निशाना पक्का। टेस्ट पास हुआ।", "वार चूक गया। विफलता दोहराकर फिर निशाना लगाओ।", "निशाना साफ नहीं। सटीक परिदृश्य दो।"], + jumbo: ["बहाव स्थिर है। यह गेट बंद हो सकता है।", "बहाव खराब है। गेट रोको और सुधारो।", "रास्ता धुंधला है। पहले छूटा सबूत लाओ।"], + rovyn: ["रिकॉर्ड जांचा। सबूत और निष्कर्ष मिलते हैं।", "रिकॉर्ड टकराता है। यह निष्कर्ष नहीं टिकेगा।", "अभिलेख अधूरा है। छूटा सबूत जोड़ो।"], + nomi: ["रास्ता जांचा। अगला कदम साफ है।", "रास्ता असुरक्षित है। पहले दिशा सुधारो।", "नक्शे में खाली जगह है। छूटा रास्ता चिह्नित करो।"] }), tr: locale(null, { - franky: ["Parçalar oturdu. Derleme dayanıyor.", "Çerçeve kaydı. Gevşek parçayı düzelt.", "Plan eksik. Eksik şartı getir."], - zoro: ["İnceleme bitti. Engel kalmadı.", "Yol sapmış. Engeli düzelt.", "İz net değil. Karar için kanıtı artır."], - usopp: ["Hedef doğrulandı. Test geçti.", "Atış şaştı. Hatayı yeniden üret ve ayarla.", "Hedef yok. Tam senaryoyu ver."], - jinbe: ["Akış dengeli. Bu kapı kapanabilir.", "Akıntı yanlış. Kapıyı tut ve onar.", "Su yolu belirsiz. Önce eksik kanıtı getir."], - robin: ["Kayıt incelendi. Kanıt ve sonuç uyuşuyor.", "Kayıt çelişiyor. Bu sonuç ayakta durmaz.", "Arşiv eksik. Eksik kanıtı ekle."], - nami: ["Rota kontrol edildi. Sonraki adım açık.", "Rota güvenli değil. Önce yönü düzelt.", "Haritada boşluk var. Eksik yolu işaretle."] + fronk: ["Parçalar oturdu. Derleme dayanıyor.", "Çerçeve kaydı. Gevşek parçayı düzelt.", "Plan eksik. Eksik şartı getir."], + zyro: ["İnceleme bitti. Engel kalmadı.", "Yol sapmış. Engeli düzelt.", "İz net değil. Karar için kanıtı artır."], + usk: ["Hedef doğrulandı. Test geçti.", "Atış şaştı. Hatayı yeniden üret ve ayarla.", "Hedef yok. Tam senaryoyu ver."], + jumbo: ["Akış dengeli. Bu kapı kapanabilir.", "Akıntı yanlış. Kapıyı tut ve onar.", "Su yolu belirsiz. Önce eksik kanıtı getir."], + rovyn: ["Kayıt incelendi. Kanıt ve sonuç uyuşuyor.", "Kayıt çelişiyor. Bu sonuç ayakta durmaz.", "Arşiv eksik. Eksik kanıtı ekle."], + nomi: ["Rota kontrol edildi. Sonraki adım açık.", "Rota güvenli değil. Önce yönü düzelt.", "Haritada boşluk var. Eksik yolu işaretle."] }), vi: locale(null, { - franky: ["Các mảnh đã khớp. Bản build đứng vững.", "Khung bị lệch. Sửa phần lỏng trước.", "Bản vẽ còn thiếu. Mang điều kiện còn thiếu vào."], - zoro: ["Review xong. Không còn lỗi chặn.", "Đường đi lệch. Sửa lỗi chặn trước.", "Dấu vết chưa rõ. Thêm bằng chứng rồi kết luận."], - usopp: ["Mục tiêu đã rõ. Test đã qua.", "Phát bắn lệch. Tái hiện lỗi rồi chỉnh lại.", "Chưa có mục tiêu. Đưa đúng kịch bản."], - jinbe: ["Luồng ổn định. Gate này có thể đóng.", "Dòng chảy sai. Giữ gate và sửa.", "Dòng nước chưa rõ. Mang bằng chứng thiếu vào trước."], - robin: ["Hồ sơ đã kiểm. Bằng chứng khớp kết luận.", "Hồ sơ mâu thuẫn. Kết luận này chưa đứng vững.", "Lưu trữ còn thiếu. Thêm bằng chứng còn thiếu."], - nami: ["Tuyến đường đã kiểm. Bước tiếp theo rõ ràng.", "Tuyến đường không an toàn. Chỉnh hướng trước.", "Bản đồ còn trống. Đánh dấu đường còn thiếu."] + fronk: ["Các mảnh đã khớp. Bản build đứng vững.", "Khung bị lệch. Sửa phần lỏng trước.", "Bản vẽ còn thiếu. Mang điều kiện còn thiếu vào."], + zyro: ["Review xong. Không còn lỗi chặn.", "Đường đi lệch. Sửa lỗi chặn trước.", "Dấu vết chưa rõ. Thêm bằng chứng rồi kết luận."], + usk: ["Mục tiêu đã rõ. Test đã qua.", "Phát bắn lệch. Tái hiện lỗi rồi chỉnh lại.", "Chưa có mục tiêu. Đưa đúng kịch bản."], + jumbo: ["Luồng ổn định. Gate này có thể đóng.", "Dòng chảy sai. Giữ gate và sửa.", "Dòng nước chưa rõ. Mang bằng chứng thiếu vào trước."], + rovyn: ["Hồ sơ đã kiểm. Bằng chứng khớp kết luận.", "Hồ sơ mâu thuẫn. Kết luận này chưa đứng vững.", "Lưu trữ còn thiếu. Thêm bằng chứng còn thiếu."], + nomi: ["Tuyến đường đã kiểm. Bước tiếp theo rõ ràng.", "Tuyến đường không an toàn. Chỉnh hướng trước.", "Bản đồ còn trống. Đánh dấu đường còn thiếu."] }), ru: locale(null, { - franky: ["Детали сошлись. Сборка держится.", "Каркас ушел в сторону. Почини слабое место.", "Чертеж неполный. Принеси недостающее условие."], - zoro: ["Ревью завершено. Блокеров нет.", "Путь сбился. Исправь блокер.", "След неясен. Добавь доказательства перед решением."], - usopp: ["Цель подтверждена. Тест прошел.", "Выстрел ушел мимо. Воспроизведи сбой и поправь.", "Цели еще нет. Дай точный сценарий."], - jinbe: ["Поток стабилен. Этот gate можно закрыть.", "Течение неверное. Держи gate и чини.", "Путь мутный. Сначала принеси недостающее доказательство."], - robin: ["Запись проверена. Доказательства и вывод совпали.", "Запись спорит с выводом. Так не пройдет.", "Архив неполный. Добавь недостающее доказательство."], - nami: ["Маршрут проверен. Следующий шаг ясен.", "Маршрут опасен. Сначала поправь курс.", "На карте пробел. Отметь недостающий путь."] + fronk: ["Детали сошлись. Сборка держится.", "Каркас ушел в сторону. Почини слабое место.", "Чертеж неполный. Принеси недостающее условие."], + zyro: ["Ревью завершено. Блокеров нет.", "Путь сбился. Исправь блокер.", "След неясен. Добавь доказательства перед решением."], + usk: ["Цель подтверждена. Тест прошел.", "Выстрел ушел мимо. Воспроизведи сбой и поправь.", "Цели еще нет. Дай точный сценарий."], + jumbo: ["Поток стабилен. Этот gate можно закрыть.", "Течение неверное. Держи gate и чини.", "Путь мутный. Сначала принеси недостающее доказательство."], + rovyn: ["Запись проверена. Доказательства и вывод совпали.", "Запись спорит с выводом. Так не пройдет.", "Архив неполный. Добавь недостающее доказательство."], + nomi: ["Маршрут проверен. Следующий шаг ясен.", "Маршрут опасен. Сначала поправь курс.", "На карте пробел. Отметь недостающий путь."] }), ar: locale(null, { - franky: ["الأجزاء متطابقة. البناء ثابت.", "الإطار منحرف. أصلح القطعة المرتخية.", "المخطط ناقص. أحضر الشرط المفقود."], - zoro: ["انتهت المراجعة. لا يوجد مانع.", "المسار منحرف. أصلح العائق.", "الأثر غير واضح. أضف الدليل قبل الحكم."], - usopp: ["الهدف مؤكد. الاختبار نجح.", "الطلقة أخطأت. أعد إنتاج الفشل ثم اضبط.", "لا هدف واضح بعد. أعطني السيناريو الدقيق."], - jinbe: ["التدفق مستقر. يمكن إغلاق هذا الباب.", "التيار خاطئ. أمسك الباب وأصلح.", "المسار غير واضح. أحضر الدليل الناقص أولاً."], - robin: ["تم فحص السجل. الدليل والنتيجة متطابقان.", "السجل يتعارض. هذه النتيجة لا تثبت.", "الأرشيف ناقص. أضف الدليل المفقود."], - nami: ["تم فحص الطريق. الخطوة التالية واضحة.", "الطريق غير آمن. صحح المسار أولاً.", "الخريطة فيها فراغ. حدّد الطريق الناقص."] + fronk: ["الأجزاء متطابقة. البناء ثابت.", "الإطار منحرف. أصلح القطعة المرتخية.", "المخطط ناقص. أحضر الشرط المفقود."], + zyro: ["انتهت المراجعة. لا يوجد مانع.", "المسار منحرف. أصلح العائق.", "الأثر غير واضح. أضف الدليل قبل الحكم."], + usk: ["الهدف مؤكد. الاختبار نجح.", "الطلقة أخطأت. أعد إنتاج الفشل ثم اضبط.", "لا هدف واضح بعد. أعطني السيناريو الدقيق."], + jumbo: ["التدفق مستقر. يمكن إغلاق هذا الباب.", "التيار خاطئ. أمسك الباب وأصلح.", "المسار غير واضح. أحضر الدليل الناقص أولاً."], + rovyn: ["تم فحص السجل. الدليل والنتيجة متطابقان.", "السجل يتعارض. هذه النتيجة لا تثبت.", "الأرشيف ناقص. أضف الدليل المفقود."], + nomi: ["تم فحص الطريق. الخطوة التالية واضحة.", "الطريق غير آمن. صحح المسار أولاً.", "الخريطة فيها فراغ. حدّد الطريق الناقص."] }), th: locale(null, { - franky: ["ชิ้นส่วนเข้าที่แล้ว บิลด์ยังมั่นคง", "โครงเบี้ยว แก้ชิ้นที่หลวมก่อน", "แบบยังขาด เติมเงื่อนไขที่หายไปก่อน"], - zoro: ["รีวิวจบแล้ว ไม่มีตัวบล็อกเหลือ", "ทางผิด แก้ตัวบล็อกก่อน", "ร่องรอยยังไม่ชัด เพิ่มหลักฐานก่อนตัดสิน"], - usopp: ["ยืนยันเป้าแล้ว เทสต์ผ่าน", "ยิงพลาด ทำซ้ำความล้มเหลวแล้วปรับใหม่", "ยังไม่มีเป้าชัดเจน ขอฉากทดสอบที่แน่นอน"], - jinbe: ["กระแสนิ่งแล้ว gate นี้ปิดได้", "กระแสผิด จับ gate ไว้แล้วซ่อม", "ทางน้ำยังไม่ชัด เอาหลักฐานที่ขาดมาก่อน"], - robin: ["ตรวจบันทึกแล้ว หลักฐานตรงกับข้อสรุป", "บันทึกขัดกัน ข้อสรุปนี้ยังยืนไม่ได้", "คลังข้อมูลยังขาด เติมหลักฐานที่หายไป"], - nami: ["ตรวจเส้นทางแล้ว ขั้นต่อไปชัดเจน", "เส้นทางไม่ปลอดภัย แก้ทิศก่อน", "แผนที่มีช่องว่าง ทำเครื่องหมายทางที่หายไป"] + fronk: ["ชิ้นส่วนเข้าที่แล้ว บิลด์ยังมั่นคง", "โครงเบี้ยว แก้ชิ้นที่หลวมก่อน", "แบบยังขาด เติมเงื่อนไขที่หายไปก่อน"], + zyro: ["รีวิวจบแล้ว ไม่มีตัวบล็อกเหลือ", "ทางผิด แก้ตัวบล็อกก่อน", "ร่องรอยยังไม่ชัด เพิ่มหลักฐานก่อนตัดสิน"], + usk: ["ยืนยันเป้าแล้ว เทสต์ผ่าน", "ยิงพลาด ทำซ้ำความล้มเหลวแล้วปรับใหม่", "ยังไม่มีเป้าชัดเจน ขอฉากทดสอบที่แน่นอน"], + jumbo: ["กระแสนิ่งแล้ว gate นี้ปิดได้", "กระแสผิด จับ gate ไว้แล้วซ่อม", "ทางน้ำยังไม่ชัด เอาหลักฐานที่ขาดมาก่อน"], + rovyn: ["ตรวจบันทึกแล้ว หลักฐานตรงกับข้อสรุป", "บันทึกขัดกัน ข้อสรุปนี้ยังยืนไม่ได้", "คลังข้อมูลยังขาด เติมหลักฐานที่หายไป"], + nomi: ["ตรวจเส้นทางแล้ว ขั้นต่อไปชัดเจน", "เส้นทางไม่ปลอดภัย แก้ทิศก่อน", "แผนที่มีช่องว่าง ทำเครื่องหมายทางที่หายไป"] }) }); diff --git a/src/engineer.js b/src/engineer.js index b153820..9f852d5 100644 --- a/src/engineer.js +++ b/src/engineer.js @@ -148,14 +148,14 @@ function orchestrationLines() { "Crew fan-out (team mode):", "- If the requested repository path differs from `cwd`, verify and state the exact target path before editing or dispatching workers.", "- This task is big enough to split. Delegate independent slices to parallel workers instead of doing everything in one thread.", - "- Spawn each worker with the host's native tool, and ALWAYS set `agent_type` to the crew role so the child loads that role's model and instructions, e.g.: `multi_agent_v1.spawn_agent({\"message\": \"TASK: act as franky — \", \"agent_type\": \"franky\", \"fork_context\": false})`.", - "- Match `agent_type` to the lane, one per crew role: `agent_type: \"franky\"` builds one slice, `\"zoro\"` reviews a diff, `\"usopp\"` tests, `\"jinbe\"` gates, `\"robin\"` audits (read-only), `\"nami\"` finds files (read-only). Dispatch `nami` first to scope a slice before assigning `franky`.", + "- Spawn each worker with the host's native tool, and ALWAYS set `agent_type` to the crew role so the child loads that role's model and instructions, e.g.: `multi_agent_v1.spawn_agent({\"message\": \"TASK: act as fronk — \", \"agent_type\": \"fronk\", \"fork_context\": false})`.", + "- Match `agent_type` to the lane, one per crew role: `agent_type: \"fronk\"` builds one slice, `\"zyro\"` reviews a diff, `\"usk\"` tests, `\"jumbo\"` gates, `\"rovyn\"` audits (read-only), `\"nomi\"` finds files (read-only). Dispatch `nomi` first to scope a slice before assigning `fronk`.", "- Role routing by name is best-effort across hosts, so ALSO make the `message` self-contained: lead with `TASK: act as ` and paste all needed context, so the worker behaves correctly even if the host ignores `agent_type`.", "- The implementation worker must own a real bounded implementation slice before the parent edits or completes that slice. If no safe independent implementation slice exists, stay solo or use a smaller read-only crew.", - "- Parallelize read-heavy lanes first (`nami` navigation, `zoro` review, `usopp` QA); never run two editors on overlapping files at once.", - "- Each worker ends its report with `SUPERLOOPY_EVIDENCE: ` (`robin` uses `SUPERLOOPY_AUDIT:`). Collect them with `multi_agent_v1.wait_agent`; treat a running child as alive, not a timeout.", + "- Parallelize read-heavy lanes first (`nomi` navigation, `zyro` review, `usk` QA); never run two editors on overlapping files at once.", + "- Each worker ends its report with `SUPERLOOPY_EVIDENCE: ` (`rovyn` uses `SUPERLOOPY_AUDIT:`). Collect them with `multi_agent_v1.wait_agent`; treat a running child as alive, not a timeout.", "- After each worker returns, show a concise role completion line with role, normalized verdict, artifact path, risk, and next action before closing or respawning that lane.", - "- Give `jinbe` a Markdown final gate report such as `.superloopy/evidence/jinbe-final-gate-report.md`; keep it separate from the machine quality gate `.superloopy/evidence/gate.json`.", + "- Give `jumbo` a Markdown final gate report such as `.superloopy/evidence/jumbo-final-gate-report.md`; keep it separate from the machine quality gate `.superloopy/evidence/gate.json`.", "- You own the plan: record a criterion pass only from a real artifact via `superloopy loop prove` or `superloopy loop evidence`, never from a worker's claim alone. Track each dispatch with `superloopy loop handoff` and run `superloopy loop fleet --json` before the final gate.", "- Before the final summary, run `git status --short --untracked-files=all` and `git ls-files --others --exclude-standard` so untracked evidence, scripts, and reports are not omitted.", "- Keep the Superloopy loop the source of truth: you still begin, prove, check, and finish through the CLI yourself with `superloopy loop finish --evidence \"\" --artifact .superloopy/evidence/gate.json --json`." diff --git a/src/fleet.js b/src/fleet.js index b6f52a0..e749d72 100644 --- a/src/fleet.js +++ b/src/fleet.js @@ -1,5 +1,5 @@ // Parent-side coordination for subagent-driven mode. Superloopy does not spawn or schedule workers, -// but the parent (Luffy) can record one handoff per dispatched worker and later reconcile the +// but the parent (Loopi) can record one handoff per dispatched worker and later reconcile the // fleet: which assignments are outstanding, and a SINGLE normalized verdict across the workers' // three different vocabularies (reviewer APPROVE/CHANGES_REQUESTED, QA PASS/FAIL, gate // APPROVE/REJECT). This is additive and parent-side — it never spawns and never completes. diff --git a/src/hooks.js b/src/hooks.js index 8cebc9e..29d9fcc 100644 --- a/src/hooks.js +++ b/src/hooks.js @@ -12,7 +12,7 @@ import { MAX_SUBAGENT_ATTEMPTS, clearAttemptState, nextAttemptState, recordSubag export { runPreToolUseHook } from "./pre-tool-use.js"; -const EVIDENCE_RECEIPT_AGENT_TYPES = new Set(["franky", "zoro", "usopp", "jinbe"]); +const EVIDENCE_RECEIPT_AGENT_TYPES = new Set(["fronk", "zyro", "usk", "jumbo"]); // An artifact up to this size must carry non-whitespace content to satisfy the receipt gate; // only larger artifacts (assumed non-trivial) skip the read. Closes the blank-placeholder hole. const MAX_BLANK_CHECK_BYTES = 1_000_000; diff --git a/src/model-policy.js b/src/model-policy.js index 25b810e..a95ec85 100644 --- a/src/model-policy.js +++ b/src/model-policy.js @@ -10,12 +10,12 @@ const ALLOWED_EFFORTS = ["low", "medium", "high", "xhigh"]; const ALLOWED_TIERS = ["priority", "fast", "efficient"]; const AGENT_MODEL_DEFAULTS = { - franky: { model: "gpt-5.5", model_reasoning_effort: "high", service_tier: "priority" }, - zoro: { model: "gpt-5.5", model_reasoning_effort: "xhigh", service_tier: "priority" }, - usopp: { model: "gpt-5.5", model_reasoning_effort: "high", service_tier: "priority" }, - jinbe: { model: "gpt-5.5", model_reasoning_effort: "xhigh", service_tier: "priority" }, - robin: { model: "gpt-5.5", model_reasoning_effort: "high", service_tier: "priority" }, - nami: { model: "gpt-5.4-mini", model_reasoning_effort: "low", service_tier: "fast" } + fronk: { model: "gpt-5.5", model_reasoning_effort: "high", service_tier: "priority" }, + zyro: { model: "gpt-5.5", model_reasoning_effort: "xhigh", service_tier: "priority" }, + usk: { model: "gpt-5.5", model_reasoning_effort: "high", service_tier: "priority" }, + jumbo: { model: "gpt-5.5", model_reasoning_effort: "xhigh", service_tier: "priority" }, + rovyn: { model: "gpt-5.5", model_reasoning_effort: "high", service_tier: "priority" }, + nomi: { model: "gpt-5.4-mini", model_reasoning_effort: "low", service_tier: "fast" } }; export async function checkModelPolicy(cwd) { diff --git a/test/cli-evidence.test.js b/test/cli-evidence.test.js index 65aa66b..c8f91fd 100644 --- a/test/cli-evidence.test.js +++ b/test/cli-evidence.test.js @@ -330,12 +330,12 @@ test("CLI loop finish rejects markdown paths for the quality gate artifact", asy "--evidence", "criteria passed", "--artifact", - ".superloopy/evidence/jinbe-final-gate.md" + ".superloopy/evidence/jumbo-final-gate.md" ], { cwd: repo }); assert.equal(result.status, 1); assert.match(result.stderr, /Quality gate artifact must use a \.json path/); - assert.equal(existsSync(join(repo, ".superloopy", "evidence", "jinbe-final-gate.md")), false); + assert.equal(existsSync(join(repo, ".superloopy", "evidence", "jumbo-final-gate.md")), false); }); test("CLI loop finish text shows the complete guide", async () => { diff --git a/test/cli.test.js b/test/cli.test.js index 393f093..0b19dc8 100644 --- a/test/cli.test.js +++ b/test/cli.test.js @@ -103,19 +103,19 @@ test("CLI agents install refuses changed files unless forced", async () => { const first = runCli(["agents", "install", "--target", target, "--json"]); assert.equal(first.status, 0, first.stderr); - const executorPath = join(target, "franky.toml"); + const executorPath = join(target, "fronk.toml"); await writeFile(executorPath, "local edit\n", "utf8"); const conflict = runCli(["agents", "install", "--target", target, "--json"]); assert.equal(conflict.status, 1, conflict.stderr); const parsedConflict = JSON.parse(conflict.stdout); assert.equal(parsedConflict.ok, false); - assert.equal(parsedConflict.conflicts[0].name, "franky"); + assert.equal(parsedConflict.conflicts[0].name, "fronk"); const forced = runCli(["agents", "install", "--target", target, "--force", "--json"]); assert.equal(forced.status, 0, forced.stderr); const restored = await readFile(executorPath, "utf8"); - assert.match(restored, /name = "franky"/); + assert.match(restored, /name = "fronk"/); }); test("CLI install writes command wrapper and bundled agents", async () => { @@ -298,7 +298,7 @@ test("CLI hook subagent-stop honors the host contract over stdin", async () => { // Missing receipt -> block (re-prompt the worker). const missing = runCli(["hook", "subagent-stop"], { cwd: repo, - input: JSON.stringify({ hook_event_name: "SubagentStop", agent_type: "franky", session_id: "s", agent_id: "a", cwd: repo, last_assistant_message: "done" }) + input: JSON.stringify({ hook_event_name: "SubagentStop", agent_type: "fronk", session_id: "s", agent_id: "a", cwd: repo, last_assistant_message: "done" }) }); assert.equal(missing.status, 0, missing.stderr); assert.equal(JSON.parse(missing.stdout).decision, "block"); @@ -309,7 +309,7 @@ test("CLI hook subagent-stop honors the host contract over stdin", async () => { await writeFile(join(evidenceDir, "receipt.txt"), "real proof\n", "utf8"); const ok = runCli(["hook", "subagent-stop"], { cwd: repo, - input: JSON.stringify({ hook_event_name: "SubagentStop", agent_type: "franky", session_id: "s", agent_id: "b", cwd: repo, last_assistant_message: "done\nSUPERLOOPY_EVIDENCE: .superloopy/evidence/receipt.txt" }) + input: JSON.stringify({ hook_event_name: "SubagentStop", agent_type: "fronk", session_id: "s", agent_id: "b", cwd: repo, last_assistant_message: "done\nSUPERLOOPY_EVIDENCE: .superloopy/evidence/receipt.txt" }) }); assert.equal(ok.status, 0, ok.stderr); assert.equal(ok.stdout.trim(), ""); diff --git a/test/crew-lines.test.js b/test/crew-lines.test.js index 8ee387d..7d8c8ad 100644 --- a/test/crew-lines.test.js +++ b/test/crew-lines.test.js @@ -29,16 +29,16 @@ function runCli(args, options = {}) { } test("crewLineForHandoff returns original role lines for terminal verdicts", () => { - const line = crewLineForHandoff({ agent: "usopp", normalizedVerdict: "accept" }); + const line = crewLineForHandoff({ agent: "usk", normalizedVerdict: "accept" }); assert.deepEqual(line, { - agent: "usopp", - speaker: "Usopp", + agent: "usk", + speaker: "Usk", verdict: "accept", language: "en", line: "Target checked. The test passed." }); - assert.equal(formatCrewLine(line), 'Usopp: "Target checked. The test passed."'); + assert.equal(formatCrewLine(line), 'Usk: "Target checked. The test passed."'); }); test("crewLineForHandoff matches Korean user language from assignment or explicit hints", () => { @@ -46,20 +46,20 @@ test("crewLineForHandoff matches Korean user language from assignment or explici assert.equal(detectCrewLineLanguage("answer in English"), "en"); const line = crewLineForHandoff({ - agent: "usopp", + agent: "usk", normalizedVerdict: "accept", assignment: "한국어 사용자가 요청한 QA" }); assert.deepEqual(line, { - agent: "usopp", - speaker: "우솝", + agent: "usk", + speaker: "Usk", verdict: "accept", language: "ko", line: "표적 확인. 테스트는 통과했다." }); assert.equal( - decorateHandoffWithCrewLine({ agent: "zoro", normalizedVerdict: "reject", assignment: "review" }, { languageHints: ["사용자는 한국어로 말했다"] }).crewLine.line, + decorateHandoffWithCrewLine({ agent: "zyro", normalizedVerdict: "reject", assignment: "review" }, { languageHints: ["사용자는 한국어로 말했다"] }).crewLine.line, "길이 어긋났다. 막는 결함부터 베어내자." ); }); @@ -72,23 +72,23 @@ test("crewLineForHandoff follows supported prompt languages and falls back to En assert.equal(detectCrewLineLanguage("العربية"), "ar"); assert.equal(detectCrewLineLanguage("unsupported made-up language"), "en"); - assert.deepEqual(crewLineForHandoff({ agent: "usopp", normalizedVerdict: "accept", assignment: "responde en español" }), { - agent: "usopp", - speaker: "Usopp", + assert.deepEqual(crewLineForHandoff({ agent: "usk", normalizedVerdict: "accept", assignment: "responde en español" }), { + agent: "usk", + speaker: "Usk", verdict: "accept", language: "es", line: "Objetivo confirmado. La prueba pasó." }); - assert.equal(crewLineForHandoff({ agent: "robin", normalizedVerdict: "accept", assignment: "日本語で監査" }).line, "記録確認。証拠と結論は一致している。"); - assert.equal(crewLineForHandoff({ agent: "usopp", normalizedVerdict: "accept" }, { language: "fr-FR" }).line, "Cible confirmée. Le test est passé."); + assert.equal(crewLineForHandoff({ agent: "rovyn", normalizedVerdict: "accept", assignment: "日本語で監査" }).line, "記録確認。証拠と結論は一致している。"); + assert.equal(crewLineForHandoff({ agent: "usk", normalizedVerdict: "accept" }, { language: "fr-FR" }).line, "Cible confirmée. Le test est passé."); }); test("crewLineForHandoff stays silent for pending or unknown lanes", () => { - assert.equal(crewLineForHandoff({ agent: "usopp", normalizedVerdict: "pending" }), null); + assert.equal(crewLineForHandoff({ agent: "usk", normalizedVerdict: "pending" }), null); assert.equal(crewLineForHandoff({ agent: "unknown", normalizedVerdict: "accept" }), null); - assert.deepEqual(decorateHandoffWithCrewLine({ id: "H001", agent: "usopp", normalizedVerdict: "pending" }), { + assert.deepEqual(decorateHandoffWithCrewLine({ id: "H001", agent: "usk", normalizedVerdict: "pending" }), { id: "H001", - agent: "usopp", + agent: "usk", normalizedVerdict: "pending" }); }); @@ -101,7 +101,7 @@ test("CLI handoff text shows the crew line without hiding status", async () => { "loop", "handoff", "--agent", - "usopp", + "usk", "--assignment", "qa", "--status", @@ -113,7 +113,7 @@ test("CLI handoff text shows the crew line without hiding status", async () => { ], { cwd: repo }); assert.equal(result.status, 0, result.stderr); - assert.match(result.stdout, /^Usopp: "Target checked\. The test passed\."\nsuperloopy handoff: H001 usopp -> done \[accept\]\n$/); + assert.match(result.stdout, /^Usk: "Target checked\. The test passed\."\nsuperloopy handoff: H001 usk -> done \[accept\]\n$/); }); test("CLI handoff text can use an explicit supported language override", async () => { @@ -126,7 +126,7 @@ test("CLI handoff text can use an explicit supported language override", async ( "--language", "es", "--agent", - "usopp", + "usk", "--assignment", "qa", "--status", @@ -138,7 +138,7 @@ test("CLI handoff text can use an explicit supported language override", async ( ], { cwd: repo }); assert.equal(result.status, 0, result.stderr); - assert.match(result.stdout, /^Usopp: "Objetivo confirmado\. La prueba pasó\."\nsuperloopy handoff: H001 usopp -> done \[accept\]\n$/); + assert.match(result.stdout, /^Usk: "Objetivo confirmado\. La prueba pasó\."\nsuperloopy handoff: H001 usk -> done \[accept\]\n$/); }); test("CLI handoff text follows Korean session brief language", async () => { @@ -161,7 +161,7 @@ test("CLI handoff text follows Korean session brief language", async () => { "--session-id", "ko-user", "--agent", - "usopp", + "usk", "--assignment", "qa", "--status", @@ -173,5 +173,5 @@ test("CLI handoff text follows Korean session brief language", async () => { ], { cwd: repo }); assert.equal(result.status, 0, result.stderr); - assert.match(result.stdout, /^우솝: "표적 확인\. 테스트는 통과했다\."\nsuperloopy handoff: H001 usopp -> done \[accept\]\n$/); + assert.match(result.stdout, /^Usk: "표적 확인\. 테스트는 통과했다\."\nsuperloopy handoff: H001 usk -> done \[accept\]\n$/); }); diff --git a/test/docs.test.js b/test/docs.test.js index 67cead2..0aa4d06 100644 --- a/test/docs.test.js +++ b/test/docs.test.js @@ -142,7 +142,7 @@ test("public docs describe loose prompt triggers as guidance-only", async () => test("project custom agents define Superloopy subagent workflow", async () => { const readme = await readFile("README.md", "utf8"); const skill = await readFile("skills/superloopy-loop/SKILL.md", "utf8"); - const agents = ["franky", "zoro", "usopp", "jinbe", "robin", "nami"]; + const agents = ["fronk", "zyro", "usk", "jumbo", "rovyn", "nomi"]; assert.match(readme, /\.codex\/agents/); assert.match(readme, /superloopy agents install/); @@ -157,7 +157,7 @@ test("project custom agents define Superloopy subagent workflow", async () => { assert.match(content, /model_reasoning_effort = "(low|high|xhigh)"/); assert.match(content, /service_tier = "(priority|fast)"/); assert.match(content, /developer_instructions = """/); - if (agent !== "nami") assert.match(content, /active evidence root/); + if (agent !== "nomi") assert.match(content, /active evidence root/); } }); @@ -165,7 +165,7 @@ test("public docs encode crew retrospective guardrails", async () => { const skill = await readFile("skills/superloopy-loop/SKILL.md", "utf8"); const hostContract = await readFile("docs/superloopy-host-contract.md", "utf8"); - assert.match(skill, /jinbe-final-gate-report\.md/); + assert.match(skill, /jumbo-final-gate-report\.md/); assert.match(skill, /\.superloopy\/evidence\/gate\.json/); assert.match(skill, /quality gate artifact.*JSON/s); assert.match(skill, /For full crew, record each dispatch with `superloopy loop handoff/s); diff --git a/test/doctor.test.js b/test/doctor.test.js index 1e3a527..a97f94f 100644 --- a/test/doctor.test.js +++ b/test/doctor.test.js @@ -97,18 +97,18 @@ test("doctor --json reports Superloopy packaging, audit, and reviewability check assert.equal(parsed.checks.reviewability.maxLines, 500); assert.equal(parsed.checks.reviewability.oversized.length, 0); assert.equal(parsed.checks.dispatchCoherence.ok, true); - assert.ok(parsed.checks.dispatchCoherence.dispatched.includes("robin")); + assert.ok(parsed.checks.dispatchCoherence.dispatched.includes("rovyn")); assert.equal(parsed.checks.modelPolicy.ok, true); assert.equal(parsed.checks.modelPolicy.policyPath, "docs/superloopy-model-policy.md"); - assert.equal(parsed.checks.modelPolicy.agents.nami.model, "gpt-5.4-mini"); - assert.equal(parsed.checks.modelPolicy.agents.zoro.model_reasoning_effort, "xhigh"); + assert.equal(parsed.checks.modelPolicy.agents.nomi.model, "gpt-5.4-mini"); + assert.equal(parsed.checks.modelPolicy.agents.zyro.model_reasoning_effort, "xhigh"); assert.equal(parsed.checks.hostContract.ok, true); assert.ok(parsed.checks.hostContract.cannotVerify.length >= 3); }); test("doctor model policy fails when bundled agent defaults drift", async () => { const repo = await tempRepoCopy(); - const agentPath = join(repo, ".codex", "agents", "nami.toml"); + const agentPath = join(repo, ".codex", "agents", "nomi.toml"); const agent = await readFile(agentPath, "utf8"); await writeFile(agentPath, agent.replace('model = "gpt-5.4-mini"', 'model = "gpt-5.5"'), "utf8"); @@ -116,17 +116,17 @@ test("doctor model policy fails when bundled agent defaults drift", async () => assert.equal(result.ok, false); assert.equal(result.checks.modelPolicy.ok, false); - assert.match(result.checks.modelPolicy.message, /nami\.toml model/); + assert.match(result.checks.modelPolicy.message, /nomi\.toml model/); }); test("doctor dispatch coherence fails when a dispatched agent is not installed", async () => { const repo = await tempRepoCopy(); - await rm(join(repo, ".codex", "agents", "robin.toml"), { force: true }); + await rm(join(repo, ".codex", "agents", "rovyn.toml"), { force: true }); const result = await runDoctor(repo); assert.equal(result.checks.dispatchCoherence.ok, false); - assert.match(result.checks.dispatchCoherence.message, /robin/); + assert.match(result.checks.dispatchCoherence.message, /rovyn/); }); test("doctor ignores Codex marketplace install metadata in plugin cache", async () => { diff --git a/test/engineer.test.js b/test/engineer.test.js index a904d55..ecf2aa0 100644 --- a/test/engineer.test.js +++ b/test/engineer.test.js @@ -77,15 +77,15 @@ test("runUserPromptSubmitHook injects the crew fan-out playbook in team mode, wi assert.match(context, /multi_agent_v1\.spawn_agent/); assert.match(context, /multi_agent_v1\.wait_agent/); // agent_type must be set per crew role so the child loads that role's TOML. - assert.match(context, /"agent_type": "franky"/); - assert.match(context, /"zoro"/); - assert.match(context, /"usopp"/); - assert.match(context, /"jinbe"/); - assert.match(context, /"robin"/); - assert.match(context, /"nami"/); + assert.match(context, /"agent_type": "fronk"/); + assert.match(context, /"zyro"/); + assert.match(context, /"usk"/); + assert.match(context, /"jumbo"/); + assert.match(context, /"rovyn"/); + assert.match(context, /"nomi"/); assert.match(context, /requested repository path differs from `cwd`/); assert.match(context, /implementation worker must own a real bounded implementation slice/); - assert.match(context, /jinbe-final-gate-report\.md/); + assert.match(context, /jumbo-final-gate-report\.md/); assert.match(context, /\.superloopy\/evidence\/gate\.json/); assert.match(context, /role completion line/); assert.match(context, /git status --short --untracked-files=all/); diff --git a/test/fleet.test.js b/test/fleet.test.js index 4abd440..f90c72f 100644 --- a/test/fleet.test.js +++ b/test/fleet.test.js @@ -41,8 +41,8 @@ test("normalizeVerdict treats lifecycle verdicts safely (inconclusive is never a test("fleetLoop drops an inconclusive worker from outstanding and never counts it as accept", async () => { const repo = await tempRepo(); - await handoffLoop(repo, ["--agent", "franky", "--assignment", "impl", "--verdict", "PASS", "--artifact", await writeEvidence(repo, "impl.txt")]); - await handoffLoop(repo, ["--agent", "nami", "--assignment", "navigate", "--verdict", "inconclusive"]); + await handoffLoop(repo, ["--agent", "fronk", "--assignment", "impl", "--verdict", "PASS", "--artifact", await writeEvidence(repo, "impl.txt")]); + await handoffLoop(repo, ["--agent", "nomi", "--assignment", "navigate", "--verdict", "inconclusive"]); const fleet = await fleetLoop(repo, []); assert.equal(fleet.summary.dispatched, 2); @@ -50,18 +50,18 @@ test("fleetLoop drops an inconclusive worker from outstanding and never counts i assert.equal(fleet.summary.byVerdict["needs-context"], 1); assert.equal(fleet.summary.byVerdict.pending, 0); assert.deepEqual(fleet.outstanding.map((item) => item.agent), []); - assert.deepEqual(fleet.attention.map((item) => item.agent), ["nami"]); + assert.deepEqual(fleet.attention.map((item) => item.agent), ["nomi"]); }); test("handoffLoop records a worker handoff with a normalized verdict", async () => { const repo = await tempRepo(); const artifact = await writeEvidence(repo, "done.txt"); - const result = await handoffLoop(repo, ["--agent", "franky", "--assignment", "G001/C001 implement", "--status", "done", "--verdict", "DONE", "--artifact", artifact]); + const result = await handoffLoop(repo, ["--agent", "fronk", "--assignment", "G001/C001 implement", "--status", "done", "--verdict", "DONE", "--artifact", artifact]); assert.equal(result.handoff.id, "H001"); - assert.equal(result.handoff.agent, "franky"); + assert.equal(result.handoff.agent, "fronk"); assert.equal(result.handoff.normalizedVerdict, "accept"); assert.equal(result.handoff.artifact, artifact); - assert.equal(result.crewLine.speaker, "Franky"); + assert.equal(result.crewLine.speaker, "Fronk"); assert.equal(result.handoff.crewLine.line, "Parts fit. The build holds."); const state = JSON.parse(await readFile(join(repo, ".superloopy", "handoffs.json"), "utf8")); assert.equal(state.handoffs.length, 1); @@ -71,45 +71,45 @@ test("handoffLoop records a worker handoff with a normalized verdict", async () test("handoffLoop rejects accepted verdicts without evidence artifacts", async () => { const repo = await tempRepo(); await assert.rejects( - handoffLoop(repo, ["--agent", "franky", "--assignment", "impl", "--verdict", "PASS"]), + handoffLoop(repo, ["--agent", "fronk", "--assignment", "impl", "--verdict", "PASS"]), /Accepted handoffs require/ ); }); test("fleetLoop reconciles dispatched workers and lists outstanding ones", async () => { const repo = await tempRepo(); - await handoffLoop(repo, ["--agent", "franky", "--assignment", "impl", "--verdict", "PASS", "--artifact", await writeEvidence(repo, "impl.txt")]); - await handoffLoop(repo, ["--agent", "zoro", "--assignment", "review", "--verdict", "CHANGES_REQUESTED"]); - await handoffLoop(repo, ["--agent", "usopp", "--assignment", "qa"]); + await handoffLoop(repo, ["--agent", "fronk", "--assignment", "impl", "--verdict", "PASS", "--artifact", await writeEvidence(repo, "impl.txt")]); + await handoffLoop(repo, ["--agent", "zyro", "--assignment", "review", "--verdict", "CHANGES_REQUESTED"]); + await handoffLoop(repo, ["--agent", "usk", "--assignment", "qa"]); const fleet = await fleetLoop(repo, []); assert.equal(fleet.summary.dispatched, 3); assert.equal(fleet.summary.byVerdict.accept, 1); assert.equal(fleet.summary.byVerdict.reject, 1); assert.equal(fleet.summary.byVerdict.pending, 1); - assert.equal(fleet.handoffs.find((item) => item.agent === "franky").crewLine.speaker, "Franky"); - assert.equal(fleet.attention[0].crewLine.speaker, "Zoro"); - assert.deepEqual(fleet.outstanding.map((item) => item.agent), ["usopp"]); - assert.deepEqual(fleet.attention.map((item) => item.agent), ["zoro"]); + assert.equal(fleet.handoffs.find((item) => item.agent === "fronk").crewLine.speaker, "Fronk"); + assert.equal(fleet.attention[0].crewLine.speaker, "Zyro"); + assert.deepEqual(fleet.outstanding.map((item) => item.agent), ["usk"]); + assert.deepEqual(fleet.attention.map((item) => item.agent), ["zyro"]); }); test("fleetLoop decorates handoffs in the scoped brief language", async () => { const repo = await tempRepo(); await mkdir(join(repo, ".superloopy", "sessions", "ko-user"), { recursive: true }); await writeFile(join(repo, ".superloopy", "sessions", "ko-user", "brief.md"), "사용자는 한국어로 작업을 요청했다.\n", "utf8"); - await handoffLoop(repo, ["--session-id", "ko-user", "--agent", "robin", "--assignment", "audit", "--verdict", "PASS", "--artifact", await writeEvidence(repo, "audit.txt", "proof\n", "ko-user")]); + await handoffLoop(repo, ["--session-id", "ko-user", "--agent", "rovyn", "--assignment", "audit", "--verdict", "PASS", "--artifact", await writeEvidence(repo, "audit.txt", "proof\n", "ko-user")]); const fleet = await fleetLoop(repo, ["--session-id", "ko-user"]); - assert.equal(fleet.handoffs[0].crewLine.speaker, "로빈"); + assert.equal(fleet.handoffs[0].crewLine.speaker, "Rovyn"); assert.equal(fleet.handoffs[0].crewLine.language, "ko"); assert.equal(fleet.handoffs[0].crewLine.line, "기록 확인. 증거와 결론이 일치한다."); }); test("handoffLoop updates an existing handoff by id", async () => { const repo = await tempRepo(); - await handoffLoop(repo, ["--agent", "usopp", "--assignment", "qa"]); - const updated = await handoffLoop(repo, ["--id", "H001", "--agent", "usopp", "--assignment", "qa", "--status", "done", "--verdict", "PASS", "--artifact", await writeEvidence(repo, "qa.txt")]); + await handoffLoop(repo, ["--agent", "usk", "--assignment", "qa"]); + const updated = await handoffLoop(repo, ["--id", "H001", "--agent", "usk", "--assignment", "qa", "--status", "done", "--verdict", "PASS", "--artifact", await writeEvidence(repo, "qa.txt")]); assert.equal(updated.handoff.normalizedVerdict, "accept"); const fleet = await fleetLoop(repo, []); assert.equal(fleet.summary.dispatched, 1); @@ -119,11 +119,11 @@ test("handoffLoop updates an existing handoff by id", async () => { test("handoffLoop --id update merges: omitted flags are preserved, not wiped", async () => { const repo = await tempRepo(); - await handoffLoop(repo, ["--agent", "usopp", "--assignment", "qa run", "--status", "dispatched"]); + await handoffLoop(repo, ["--agent", "usk", "--assignment", "qa run", "--status", "dispatched"]); // Update with ONLY --status and --verdict; agent and assignment must survive. const artifact = await writeEvidence(repo, "qa.txt"); const updated = await handoffLoop(repo, ["--id", "H001", "--status", "done", "--verdict", "PASS", "--artifact", artifact]); - assert.equal(updated.handoff.agent, "usopp"); + assert.equal(updated.handoff.agent, "usk"); assert.equal(updated.handoff.assignment, "qa run"); assert.equal(updated.handoff.status, "done"); assert.equal(updated.handoff.normalizedVerdict, "accept"); @@ -134,16 +134,16 @@ test("handoffLoop --id update merges: omitted flags are preserved, not wiped", a test("handoffLoop --id update ignores an empty --agent and preserves identity", async () => { const repo = await tempRepo(); - await handoffLoop(repo, ["--agent", "franky", "--assignment", "build"]); + await handoffLoop(repo, ["--agent", "fronk", "--assignment", "build"]); const updated = await handoffLoop(repo, ["--id", "H001", "--agent", "", "--status", "done"]); - assert.equal(updated.handoff.agent, "franky"); + assert.equal(updated.handoff.agent, "fronk"); assert.equal(updated.handoff.status, "done"); }); test("fleetLoop warns when outstanding handoffs exceed SUPERLOOPY_MAX_PARALLEL", async () => { const repo = await tempRepo(); - await handoffLoop(repo, ["--agent", "franky", "--assignment", "a"]); - await handoffLoop(repo, ["--agent", "zoro", "--assignment", "b"]); + await handoffLoop(repo, ["--agent", "fronk", "--assignment", "a"]); + await handoffLoop(repo, ["--agent", "zyro", "--assignment", "b"]); const prev = process.env.SUPERLOOPY_MAX_PARALLEL; process.env.SUPERLOOPY_MAX_PARALLEL = "1"; try { diff --git a/test/golden-audit-hooks.test.js b/test/golden-audit-hooks.test.js index ff11a48..84589ac 100644 --- a/test/golden-audit-hooks.test.js +++ b/test/golden-audit-hooks.test.js @@ -40,7 +40,7 @@ test("runAuditorStopHook accepts a verdict bound to Superloopy's recorded re-run const out = await runAuditorStopHook({ hook_event_name: "SubagentStop", - agent_type: "robin", + agent_type: "rovyn", cwd: repo, last_assistant_message: `reviewed\nSUPERLOOPY_AUDIT: ${rel}` }); @@ -68,7 +68,7 @@ test("runAuditorStopHook re-derives the floor and blocks a pass whose command no const out = await runAuditorStopHook({ hook_event_name: "SubagentStop", - agent_type: "robin", + agent_type: "rovyn", cwd: repo, last_assistant_message: `reviewed\nSUPERLOOPY_AUDIT: ${rel}` }); @@ -84,7 +84,7 @@ test("runAuditorStopHook blocks when no SUPERLOOPY_AUDIT receipt is present", as const { repo } = await auditedRepo(); const out = await runAuditorStopHook({ hook_event_name: "SubagentStop", - agent_type: "robin", + agent_type: "rovyn", cwd: repo, last_assistant_message: "I reviewed it and it looks fine" }); @@ -98,7 +98,7 @@ test("runAuditorStopHook flips the criterion on an accepted fail verdict (re-dri const out = await runAuditorStopHook({ hook_event_name: "SubagentStop", - agent_type: "robin", + agent_type: "rovyn", cwd: repo, last_assistant_message: `reviewed\nSUPERLOOPY_AUDIT: ${rel}` }); @@ -114,7 +114,7 @@ test("runAuditorStopHook counts an accepted pass verdict as a monotonic audit", const { repo, entry } = await auditedRepo(); const rel = await writeVerdict(repo, verdictFor(entry)); await runAuditorStopHook({ - hook_event_name: "SubagentStop", agent_type: "robin", cwd: repo, + hook_event_name: "SubagentStop", agent_type: "rovyn", cwd: repo, last_assistant_message: `ok\nSUPERLOOPY_AUDIT: ${rel}` }); const state = JSON.parse(await readFile(join(repo, ".superloopy", "audit-state.json"), "utf8")); @@ -126,8 +126,8 @@ test("runAuditorStopHook does not double-count a byte-identical verdict re-submi const v = verdictFor(entry); const rel1 = await writeVerdict(repo, v, "v1.json"); const rel2 = await writeVerdict(repo, v, "v2.json"); // identical bytes, different path - await runAuditorStopHook({ hook_event_name: "SubagentStop", agent_type: "robin", cwd: repo, last_assistant_message: `ok\nSUPERLOOPY_AUDIT: ${rel1}` }); - await runAuditorStopHook({ hook_event_name: "SubagentStop", agent_type: "robin", cwd: repo, last_assistant_message: `ok\nSUPERLOOPY_AUDIT: ${rel2}` }); + await runAuditorStopHook({ hook_event_name: "SubagentStop", agent_type: "rovyn", cwd: repo, last_assistant_message: `ok\nSUPERLOOPY_AUDIT: ${rel1}` }); + await runAuditorStopHook({ hook_event_name: "SubagentStop", agent_type: "rovyn", cwd: repo, last_assistant_message: `ok\nSUPERLOOPY_AUDIT: ${rel2}` }); const state = JSON.parse(await readFile(join(repo, ".superloopy", "audit-state.json"), "utf8")); assert.equal(state.auditsAccepted, 1); // content-keyed idempotency: counted once despite the new path }); @@ -140,7 +140,7 @@ test("runAuditorStopHook blocks a criterion at the per-criterion fail cap", asyn process.env.SUPERLOOPY_AUDIT_MAX_FAILS = "1"; try { await runAuditorStopHook({ - hook_event_name: "SubagentStop", agent_type: "robin", cwd: repo, + hook_event_name: "SubagentStop", agent_type: "rovyn", cwd: repo, last_assistant_message: `r\nSUPERLOOPY_AUDIT: ${rel}` }); const plan = JSON.parse(await readFile(join(repo, ".superloopy", "goals.json"), "utf8")); @@ -155,7 +155,7 @@ test("runAuditorStopHook ignores non-auditor subagents", async () => { const { repo } = await auditedRepo(); const out = await runAuditorStopHook({ hook_event_name: "SubagentStop", - agent_type: "franky", + agent_type: "fronk", cwd: repo, last_assistant_message: "done" }); @@ -164,7 +164,7 @@ test("runAuditorStopHook ignores non-auditor subagents", async () => { test("runAuditorStopHook still enforces the attempt cap when agent_id is missing", async () => { const { repo } = await auditedRepo(); - const payload = { hook_event_name: "SubagentStop", agent_type: "robin", cwd: repo, last_assistant_message: "no verdict cited" }; + const payload = { hook_event_name: "SubagentStop", agent_type: "rovyn", cwd: repo, last_assistant_message: "no verdict cited" }; // No agent_id: the audit cap must still count down rather than block forever. assert.equal(JSON.parse(await runAuditorStopHook(payload)).decision, "block"); assert.equal(JSON.parse(await runAuditorStopHook(payload)).decision, "block"); @@ -174,7 +174,7 @@ test("runAuditorStopHook still enforces the attempt cap when agent_id is missing test("runAuditorStopHook records a ledger signal when the audit cap is exhausted", async () => { const { repo } = await auditedRepo(); - const payload = { hook_event_name: "SubagentStop", agent_type: "robin", session_id: "s1", agent_id: "a1", cwd: repo, last_assistant_message: "no verdict cited" }; + const payload = { hook_event_name: "SubagentStop", agent_type: "rovyn", session_id: "s1", agent_id: "a1", cwd: repo, last_assistant_message: "no verdict cited" }; await runAuditorStopHook(payload); await runAuditorStopHook(payload); await runAuditorStopHook(payload); diff --git a/test/golden-helpers.js b/test/golden-helpers.js index 5ccc70f..c02fb0d 100644 --- a/test/golden-helpers.js +++ b/test/golden-helpers.js @@ -66,7 +66,7 @@ export async function writeGenuineAuditVerdict(repo, { criterion = "G001/C001", export function reviewStyleQualityGate(paths, overrides = {}) { return { codeReview: { - by: "zoro", + by: "zyro", recommendation: "APPROVE", codeQualityStatus: "CLEAR", reportPath: paths.codeReview, @@ -74,7 +74,7 @@ export function reviewStyleQualityGate(paths, overrides = {}) { blockers: [] }, manualQa: { - by: "usopp", + by: "usk", status: "passed", evidence: "Executed CLI golden scenarios and captured artifact-backed outcomes.", surfaceEvidence: [ @@ -113,7 +113,7 @@ export function reviewStyleQualityGate(paths, overrides = {}) { ] }, gateReview: { - by: "jinbe", + by: "jumbo", recommendation: "APPROVE", reportPath: paths.gateReview, evidence: "Rechecked reviewer reports and manual QA artifacts.", diff --git a/test/golden-hooks.test.js b/test/golden-hooks.test.js index 9a9a671..9865255 100644 --- a/test/golden-hooks.test.js +++ b/test/golden-hooks.test.js @@ -128,8 +128,8 @@ test("golden: SessionStart bootstraps CLI and agents once, then stays quiet", as assert.match(parsed.hookSpecificOutput.additionalContext, /Superloopy bootstrap/); assert.match(parsed.hookSpecificOutput.additionalContext, /CLI wrapper: installed/); assert.ok(existsSync(join(binDir, process.platform === "win32" ? "superloopy.cmd" : "superloopy"))); - assert.ok(existsSync(join(codexHome, "agents", "franky.toml"))); - assert.ok(existsSync(join(codexHome, "agents", "robin.toml"))); + assert.ok(existsSync(join(codexHome, "agents", "fronk.toml"))); + assert.ok(existsSync(join(codexHome, "agents", "rovyn.toml"))); const second = runCli(["hook", "session-start"], { env, @@ -350,7 +350,7 @@ test("golden: SubagentStop accepts legacy EVIDENCE_RECORDED receipts", async () const result = runCli(["hook", "subagent-stop"], { input: `${JSON.stringify({ hook_event_name: "SubagentStop", - agent_type: "franky", + agent_type: "fronk", agent_id: "agent.1", session_id: "sess.1", transcript_path: "", @@ -376,7 +376,7 @@ test("golden: SubagentStop rejects symlink evidence that resolves outside eviden const result = runCli(["hook", "subagent-stop"], { input: `${JSON.stringify({ hook_event_name: "SubagentStop", - agent_type: "franky", + agent_type: "fronk", agent_id: "agent.1", session_id: "sess.1", transcript_path: "", @@ -398,7 +398,7 @@ test("golden: SubagentStop attempt state blocks three claims then clears", async const repo = await tempRepo(); const payload = { hook_event_name: "SubagentStop", - agent_type: "franky", + agent_type: "fronk", agent_id: "agent.1", session_id: "sess.1", transcript_path: "", diff --git a/test/hooks.test.js b/test/hooks.test.js index 7684068..1c1a85e 100644 --- a/test/hooks.test.js +++ b/test/hooks.test.js @@ -76,7 +76,7 @@ test("runSubagentStopHook allows non-empty receipt under .superloopy/evidence", const output = runSubagentStopHook({ hook_event_name: "SubagentStop", - agent_type: "franky", + agent_type: "fronk", cwd: repo, last_assistant_message: `done\nSUPERLOOPY_EVIDENCE: ${artifact}` }); @@ -90,7 +90,7 @@ test("runSubagentStopHook validates Superloopy review worker receipts", async () const output = runSubagentStopHook({ hook_event_name: "SubagentStop", - agent_type: "zoro", + agent_type: "zyro", cwd: repo, last_assistant_message: `reviewed\nSUPERLOOPY_EVIDENCE: ${artifact}` }); @@ -106,14 +106,14 @@ test("runSubagentStopHook uses scoped evidence root when session_id is present", const globalOutput = runSubagentStopHook({ hook_event_name: "SubagentStop", - agent_type: "franky", + agent_type: "fronk", session_id: "sess.1", cwd: repo, last_assistant_message: `done\nEVIDENCE_RECORDED: ${globalArtifact}` }); const scopedOutput = runSubagentStopHook({ hook_event_name: "SubagentStop", - agent_type: "franky", + agent_type: "fronk", session_id: "sess.1", cwd: repo, last_assistant_message: `done\nEVIDENCE_RECORDED: ${scopedArtifact}` @@ -134,7 +134,7 @@ test("runSubagentStopHook suppresses on a context-pressure marker in the transcr const output = runSubagentStopHook({ hook_event_name: "SubagentStop", - agent_type: "franky", + agent_type: "fronk", cwd: repo, transcript_path: transcript, last_assistant_message: "done" @@ -152,7 +152,7 @@ test("runSubagentStopHook ignores a marker outside the bounded transcript tail", const output = runSubagentStopHook({ hook_event_name: "SubagentStop", - agent_type: "franky", + agent_type: "fronk", cwd: repo, transcript_path: transcript, last_assistant_message: "done" diff --git a/test/plugin.test.js b/test/plugin.test.js index ec0cf61..ea8bffa 100644 --- a/test/plugin.test.js +++ b/test/plugin.test.js @@ -48,11 +48,11 @@ test("subagent receipt hook covers Superloopy evidence-reporting agents", async const hook = JSON.parse(await readFile("hooks/subagent-stop.json", "utf8")); const matcher = new RegExp(hook.hooks.SubagentStop[0].matcher); - assert.equal(matcher.test("franky"), true); - assert.equal(matcher.test("zoro"), true); - assert.equal(matcher.test("usopp"), true); - assert.equal(matcher.test("jinbe"), true); - assert.equal(matcher.test("robin"), false); + assert.equal(matcher.test("fronk"), true); + assert.equal(matcher.test("zyro"), true); + assert.equal(matcher.test("usk"), true); + assert.equal(matcher.test("jumbo"), true); + assert.equal(matcher.test("rovyn"), false); }); test("repo marketplace exposes Superloopy plugin install entry", async () => { @@ -120,7 +120,7 @@ test("clone skill preserves exact extraction pipeline and crew dispatch guardrai /plain `loopy clone`.*solo/is, /superloopy loop handoff/, /superloopy loop fleet --json/, - /nami.*franky.*usopp.*zoro.*robin.*jinbe/is, + /nomi.*fronk.*usk.*zyro.*rovyn.*jumbo/is, /Do not.*similar.*redraw/is ]) { assert.match(clone.content, pattern); diff --git a/test/report.test.js b/test/report.test.js index 7535669..d2014c4 100644 --- a/test/report.test.js +++ b/test/report.test.js @@ -60,7 +60,7 @@ test("report artifact surfaces exhausted worker attempts as warnings", async () await createLoop(repo, ["--brief", "Ship a CLI loop"]); const payload = { hook_event_name: "SubagentStop", - agent_type: "franky", + agent_type: "fronk", session_id: "s1", agent_id: "a1", cwd: repo, diff --git a/test/subagent-receipt.test.js b/test/subagent-receipt.test.js index e8764fa..7ddecf1 100644 --- a/test/subagent-receipt.test.js +++ b/test/subagent-receipt.test.js @@ -10,13 +10,13 @@ async function tempRepo() { return mkdtemp(join(tmpdir(), "superloopy-receipt-")); } -test("runSubagentStopHook blocks franky without receipt", async () => { +test("runSubagentStopHook blocks fronk without receipt", async () => { // Isolated temp cwd: the attempt counter persists per (cwd, session, agent), so a shared dir // like /tmp would accumulate across runs and trip the cap intermittently. const repo = await tempRepo(); const output = runSubagentStopHook({ hook_event_name: "SubagentStop", - agent_type: "franky", + agent_type: "fronk", cwd: repo, last_assistant_message: "done" }); @@ -36,7 +36,7 @@ test("runSubagentStopHook blocks a blank (whitespace-only) artifact receipt", as const output = runSubagentStopHook({ hook_event_name: "SubagentStop", - agent_type: "franky", + agent_type: "fronk", cwd: repo, last_assistant_message: "SUPERLOOPY_EVIDENCE: .superloopy/evidence/blank.txt" }); @@ -49,7 +49,7 @@ test("runSubagentStopHook still enforces the attempt cap when agent_id is missin const repo = await tempRepo(); const payload = { hook_event_name: "SubagentStop", - agent_type: "franky", + agent_type: "fronk", cwd: repo, last_assistant_message: "no receipt here" }; @@ -65,7 +65,7 @@ test("runSubagentStopHook records a ledger signal when the attempt cap is exhaus const repo = await tempRepo(); const payload = { hook_event_name: "SubagentStop", - agent_type: "franky", + agent_type: "fronk", session_id: "s1", agent_id: "a1", cwd: repo, diff --git a/web/assets/franky.png b/web/assets/franky.png deleted file mode 100644 index 3217932..0000000 Binary files a/web/assets/franky.png and /dev/null differ diff --git a/web/assets/fronk.png b/web/assets/fronk.png new file mode 100644 index 0000000..ce9bceb Binary files /dev/null and b/web/assets/fronk.png differ diff --git a/web/assets/jinbe.png b/web/assets/jinbe.png deleted file mode 100644 index 8260849..0000000 Binary files a/web/assets/jinbe.png and /dev/null differ diff --git a/web/assets/jumbo.png b/web/assets/jumbo.png new file mode 100644 index 0000000..3344ff5 Binary files /dev/null and b/web/assets/jumbo.png differ diff --git a/web/assets/loopi.jpg b/web/assets/loopi.jpg new file mode 100644 index 0000000..3b5b764 Binary files /dev/null and b/web/assets/loopi.jpg differ diff --git a/web/assets/luffy.svg b/web/assets/luffy.svg deleted file mode 100644 index 63b32eb..0000000 --- a/web/assets/luffy.svg +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/web/assets/nami.png b/web/assets/nami.png deleted file mode 100644 index 4f57b8e..0000000 Binary files a/web/assets/nami.png and /dev/null differ diff --git a/web/assets/nomi.png b/web/assets/nomi.png new file mode 100644 index 0000000..e6c8b56 Binary files /dev/null and b/web/assets/nomi.png differ diff --git a/web/assets/robin.png b/web/assets/robin.png deleted file mode 100644 index e842a07..0000000 Binary files a/web/assets/robin.png and /dev/null differ diff --git a/web/assets/rovyn.png b/web/assets/rovyn.png new file mode 100644 index 0000000..d58058c Binary files /dev/null and b/web/assets/rovyn.png differ diff --git a/web/assets/usk.png b/web/assets/usk.png new file mode 100644 index 0000000..beb4938 Binary files /dev/null and b/web/assets/usk.png differ diff --git a/web/assets/usopp.png b/web/assets/usopp.png deleted file mode 100644 index 4e8d215..0000000 Binary files a/web/assets/usopp.png and /dev/null differ diff --git a/web/assets/zoro.png b/web/assets/zoro.png deleted file mode 100644 index 925746a..0000000 Binary files a/web/assets/zoro.png and /dev/null differ diff --git a/web/assets/zyro.png b/web/assets/zyro.png new file mode 100644 index 0000000..fd738e2 Binary files /dev/null and b/web/assets/zyro.png differ diff --git a/web/index.html b/web/index.html index 8015638..19b384f 100644 --- a/web/index.html +++ b/web/index.html @@ -89,7 +89,7 @@ .sp2{width:5px;height:5px;top:61%;left:54%;box-shadow:0 0 10px 2px rgba(231,222,255,.7)} .vignette{position:absolute;inset:0;z-index:2;pointer-events:none;background:radial-gradient(130% 90% at 45% 45%, transparent 52%, rgba(8,5,24,.72) 100%)} - /* hero figure — a single swappable asset (see assets/luffy.svg). + /* hero figure — a single swappable asset (see assets/loopi.jpg). Replace that file, or point this at any other image, to change the character. */ .stage{position:absolute;inset:0;z-index:3;pointer-events:none} .hero-figure{position:absolute;right:-1%;left:auto;bottom:0;width:min(880px,70vw);height:auto;transform:scaleX(-1); @@ -157,7 +157,7 @@ .nav-pill{display:none} .grid3{grid-template-columns:1fr} .crew{grid-template-columns:repeat(3,1fr)} - .stage svg{opacity:.5;width:150vw;right:-30vw} + .hero-figure{opacity:.5;width:150vw;right:-30vw} .hero{min-height:auto;padding:120px 0 90px} } @@ -196,15 +196,15 @@
- +
Evidence-first loop engineering

Done means proven.
Not just said.

-

Type loopy <task> — an agent does the work, proves every piece with a real artifact, and only then says it's done. Like Luffy reaching the goal: it stretches as far as it takes.

+

Type loopy <task> — an agent does the work, proves every piece with a real artifact, and only then says it's done. Like Loopi reaching the goal: it stretches as far as it takes.