neuron-explorer
Qwen3.5‑4B 전용 조향형 뉴런 탐색기, 모든 MLP 뉴런을 밀어 결과를 보관·탐색
예정된 에이전트 순회는 정원처럼 관리되고, 순찰은 읽기 전용이며 상황이 좋으면 조용히, 모든 발견은 행동으로 이어집니다
Scheduled agent rounds, kept like a garden. Read-only on patrol, quiet when all is well — and every finding is an action in waiting.
개발 도구Python · ShellGitHub @ytubecoder온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Roops — ループス · scheduled agent rounds, report-only by design. Recurring-agent harness for macOS/launchd.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
roops — ループス - the zen garden of loop harnesses Scheduled agents that watch your machine and shut up when told. Roops (ループス) means "loop" and the mechanical names predate the rebrand and has been deliberately kept: the CLI is loopctl (alias roopctl), loops live in loops.d/, launchd labels are com.loops.*. Brand, explainer, and UI-concept pages: site/.README 전문 보기 ↗
┌──────────────────────────────────────────────────┐
│ R O O P S │
│ ═════════ │
⏰ 09:00 ─────▶│ precheck ─▶ engine ─▶ contract ─▶ findings │─────┐
└──────────────────────────────────────────────────┘ │
▲ your script, then a model │
│ that can't act on its own ▼
│ ┌─────────────────┐
└──── ack · dismiss · snooze ────────│ you decide │
· reopen └─────────────────┘
Scheduled agents that watch your machine and shut up when told.
Roops (ループス) means "loop" and the mechanical names predate the rebrand and has been deliberately kept: the CLI is loopctl (alias roopctl), loops live in loops.d/, launchd labels are com.loops.*. Brand, explainer, and UI-concept pages: site/.
A thin harness for putting work you already do by hand onto a schedule. You describe the job in plain markdown, launchd fires it, a deterministic script of yours gathers the facts, a headless model interprets them, and what comes back is a contract — findings, metrics, and a report that land on a static dashboard.
Capability is per-loop and opt-in. The default floor gives the model no filesystem write, no network, and no tools at all, so a loop you leave running unattended can't surprise you. Widening any axis is a config change with a written justification — never something the model can grant itself.
Findings keep the same ID across runs, so the same problem is the same row tomorrow. When you dismiss one, the runner stops showing it — the model is never trusted to remember it dropped the subject.
Status: harness built and live-verified (2026-07-22). Real launchd firing, both engines, findings memory and dispositions, enforcement denial, and the full dashboard state matrix have all been proven on this machine. Nine loops are defined and every one of them sits at or near the report-only floor. Two are installed to launchd: loop-sensei — the fleet examiner that diagnoses failed loops — and kagi-ban — a CLI-secrets exposure audit and the first page-enabled loop (see report pages). The rest run supervised-only.
git clone https://github.com/ytubecoder/roops.git ~/projects/loops && cd ~/projects/loops && bash tests/run-tests.sh
No installer and no dependencies — it's Python 3 and bash against the CLIs you already have. The test suite is hermetic (no network, no real engines); if it passes, the harness works.
Clone https://github.com/ytubecoder/roops to ~/projects/loops, run
bash tests/run-tests.shto confirm the harness is sound, then readdocs/LOOP_AUTHORING.mdand walk me through the intake interview to build my first loop.
./bin/loopctl list — see what's defined./bin/loopctl run hello-loop — supervised foreground run, nothing scheduled./bin/loopctl new <name> — scaffold your own via the intake interview./bin/loopctl dashboard — regenerate dashboard/loops.htmlAuthoring guide: docs/LOOP_AUTHORING.md
macOS (launchd) and Linux (systemd) are both supported. .env is host config (machine-local, gitignored). A loop declares what it needs from this host with requires=. bin/probe reaches a data host for inputs that still live there. loopctl snapshot / loopctl restore move fleet state as one cold copy; see the B-25 design.
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ SCHEDULE │──▶│ PRECHECK │──▶│ ENGINE │──▶│ CONTRACT │──▶│ FINDINGS │
└──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘
launchd cheap bail codex/claude validate ack/dismiss
fires if inputs report-only or the run snooze
are missing permissions is failed reopen
| Step | What happens | Gate |
|---|---|---|
| 1. Fire | launchd starts bin/run-loop.sh <name> on the loop's schedule. An fcntl lock means a slow run never overlaps its own next firing. | Loop enabled + not already running |
| 2. Precheck | precheck.sh — your own bash, run unsandboxed — gathers the facts and bails cheaply when inputs are absent. No point paying for a model to discover a file is missing. | Exit 0 to proceed |
| 3. Inject | Prior findings and run context are composed into the prompt, so the model knows what it already told you. | — |
| 4. Run | The engine runs headless under the loop's four permission axes. Whatever the model can and can't do is a property of the sandbox, not the prompt. | Engine-level denial |
| 5. Validate | Output must satisfy the contract in docs/INTERFACES.md. Malformed output fails the run rather than silently reporting nothing. | Schema + finding-identity check |
| 6. Promote | Findings upsert by stable ID, dispositions apply, reports promote atomically, dashboard regenerates, old runs retire. Page-enabled loops then render their report page, behind its own gate. | Suppression filter |
Stage change = the runner's job. Disposition change = yours, via loopctl. The model never does either.
A loop has three lanes with very different power, and it's worth knowing which is which before you write one.
| Lane | Sandboxed? | In practice |
|---|---|---|
precheck.sh | No. Plain bash, exec'd directly by the runner under a timeout | Where network and file I/O belong. Trusted code you wrote, at full user privilege |
| The engine | Yes, by four permission axes | Default floor report_only / none / none / none: codex gets -s read-only, claude gets --tools "" |
| Findings → you | n/a | ack · dismiss · snooze · reopen via loopctl. The model never sets a disposition |
So the invariant is not "loops don't change things." It's deterministic code you wrote gets full power; the model gets a sandbox. loops.d/ads-google/precheck.sh curls four HTTP endpoints on every run — that's the design, not a leak. What's contained is the part you didn't write line by line.
The browser-facing console (bin/console.py, loopctl serve) doesn't add a fourth lane — it's deterministic harness code with the same full power as loopctl, because every mutation it serves is a loopctl subprocess call, the same one the terminal would run. The model is never in that path, from the browser or anywhere else. What the browser can trigger is narrower than the full CLI, though: pause/resume rounds, change a schedule, and fire one supervised run (the 走 run-now button — loopctl run in a background worker, §13.3 in docs/INTERFACES.md); never install or uninstall — those stay CLI-only behind loopctl's own supervised verification (§8.1).
Set per loop in loop.conf; semantics in docs/INTERFACES.md §5.2.
| Axis | Values | Default |
|---|---|---|
perm_fs_write | none · report_only · workdir | report_only (its own run dir only) |
perm_network | none · full | none |
perm_local_exec | none · allowlist · full | none |
perm_remote_mutation | none · allowlist | none |
A write-capable loop — one that fixes a bug, cleans up code, updates a database — is therefore a config change, not a harness change. loopctl validate hard-fails seven dangerous combinations rather than warning about them, so widening is deliberate and reviewed.
Four things to know before you widen:
exec_allowlist is intent, not a boundary. A non-allowlisted echo still ran under a one-entry allowlist (probed 2026-07-28). Real containment is the write sandbox, the exposed tool set, and perm_network=none.perm_fs_write=workdir is spec'd and adapter-mapped but not live-verified — no loop in the current fleet uses it.credential_env is reserved and not implemented; validate hard-fails a non-empty value. A loop needing secrets reads them in the precheck, from the plist's EnvironmentVariables.perm_remote_mutation != none requires a written remote_mutation_justification — the harness refuses to let you spend money or push anywhere anonymously.| Layer | What it guarantees |
|---|---|
| Contract validation | Output that doesn't match the schema fails the run. No half-parsed findings, and no promotion — a failed run leaves the previous latest.* untouched. |
| Stable finding IDs | The same issue is the same row across runs, accumulating a history instead of re-arriving as new noise. |
| Runner-side suppression | Dismissed and snoozed findings are filtered by the runner before you see them. The model still emits them; an audit copy stays in state/runs/<id>/contract.json. |
That last row matters most in practice. "Stop nagging me about this" is enforced by code, not by trusting a fresh session to honor a note in its prompt.
dashboard/loops.html is a single static self-contained file (inline CSS/JS, no network, opened as file://), rewritten via tmp-file + rename after every run. It renders in the roops garden style — hanko status stamps (済 ok · 注 warn · 警 alert · 未 no data) over the same precedence rules, a per-loop tokonoma alcove on each fleet row, and a 巡/休/手 column showing whether a schedule is actually loaded, each meaning-bearing kanji carrying a tiny English gloss. Since 2026-08-02 the garden is the whole dashboard (three-tier reorg): each fleet row is a native <details> accordion — the row is the glance tier, expanding it reveals that loop's findings, recent runs, and report links inline (one row open at a time; #loop-<name> deep-links open the right row), and the loop's own report page is the long-form tier. Light and dark modes ship as a standard: OS preference by default, a topstrip toggle persisted to localStorage, with report pages following the same choice. A loop feeds the garden through four channels:
| Channel | Contract field | Rendered as |
|---|---|---|
| Status + headline | status, headline | Precedence-resolved stamp and the tokonoma's first line on the fleet row |
| Report | report_markdown | Promoted to reports/<name>/latest.md, linked from the row |
| Metrics | metrics | Panels declared in the loop's dashboard.json — number · table · list · trend (sparkline over N days) |
| Findings | findings | Per-loop list with recurrence, a 巡 ×N chip for repeats, and disposition text — 3rd report · dismissed 2026-06-01 ("note") |
Undeclared metrics are never hidden — they render in a capped raw-fallback panel, so a loop can start emitting something new without a dashboard change. The page also carries fleet counts, a needs_attention roll-up, 7-day token spend, stale-loop detection (installed loops only — a supervised-only loop shows 休 "no schedule loaded" instead), died-run detection, and a recent-runs table per loop.
One gotcha worth internalizing before you write a loop that wants to show red: a non-empty findings array discards the declared status and the light becomes the max severity of the unsuppressed findings (§4.5). A run that must surface red emits zero findings.
Some loops capture more structured world state than a fleet row and a markdown report can carry — inventories, per-item remediation, grouped scan results. Those loops can publish a report page: one self-contained HTML file per run, rendered by a deterministic render.sh you write (no model calls, no network, no randomness), linked with dated history from the loop's accordion row on the dashboard. Added 2026-07-30 as INTERFACES Amendment 2; styled since 2026-08-02 by pagekit/kit.css on the garden's shared light/dark tokens (tests/test_token_drift.py keeps the two palettes identical).
loops.d/<name>/render.sh is what page-enables a loop. Adding one is deliberate, under the same trust rule as the precheck: your code, run unsandboxed. loopctl validate fails a render.sh that exists but isn't executable.stale badge until a render succeeds again. Debug via state/runs/<id>/page-render.log.bin/page_envelope.py check: valid single-envelope page, ≤ 8 MiB, no external-fetch markup, and redaction-clean — if bin/redact.py would change the page, it does not publish. Paths and names are fine; secret values never are.snapshot (a full audit document — dismissing a finding silences the nag channel, not the document) and findings (anything presented as findings must come from the suppression-filtered latest.json, never raw contract.json).$LOOP_DATA_DIR; updates are committed only when the run promotes, so a failed run never consumes state.loops.d/kagi-ban/ — the exposure-audit pilot — is the reference implementation. Authoring guide: docs/REPORT_PAGES.md.
./bin/loopctl new <name> # scaffold — intake interview → SPEC.md + templates
./bin/loopctl validate <name> # grammar + dangerous-combo checks + finding-identity check
./bin/loopctl run <name> # supervised foreground run
./bin/loopctl list # every loop: type, engine, schedule, enabled, installed
./bin/loopctl status <name> # last run, headline, health
./bin/loopctl install <name> # plist → bootstrap → kickstart → verified run row
./bin/loopctl uninstall <name> # remove from launchd
./bin/loopctl pause <name> # stop firing, keep the definition
./bin/loopctl resume <name>
./bin/loopctl import <skill> # convert an Agent Skill into a loop (--analyze / --apply)
./bin/loopctl dashboard # regenerate dashboard/loops.html
./bin/roopctl <anything> # alias — the rebrand's only mechanical concession
./bin/loopctl findings <name> # open findings for a loop
./bin/loopctl ack <finding-id> # seen, stop surfacing it
./bin/loopctl dismiss <finding-id> --note # not a problem, and here's why
./bin/loopctl snooze <finding-id> --until # not now, come back later
./bin/loopctl reopen <finding-id> # it's back
ack means stop nagging — it does not mean the recommendation was accepted. Approval is a separate concept and deliberately isn't overloaded onto this verb. Wiring an approved finding through to something that executes it is still an open design thread (docs/OPEN_THREADS_WARMSTART.md §1), so today the arrow stops at you.
Agent surface. Claude-family agents in any project can drive this harness via the distributable skill at skills/loops/SKILL.md (symlink or copy into ~/.claude/skills/loops). The skill teaches when to offer an import, how to run loopctl import end-to-end, and the safety rules around precheck; the full import recipe is docs/SKILL_IMPORT.md.
| Engine | Role |
|---|---|
engines/codex.sh | Default. codex exec --output-last-message --output-schema |
engines/claude.sh | Switchable per loop via loop.conf. claude -p --json-schema |
engines/fake.sh | Hermetic test stub — double-gated, never reachable in production |
Prompts are engine-neutral by design, so a loop isn't married to the model that happened to be cheapest the week it was written. Verified CLI behavior for both engines is recorded in docs/ENGINE_PROBES.md — that file is evidence, not documentation of intent.
bin/run-loop.sh # the runner: lock → precheck → inject → engine → validate → promote
bin/loopctl # the CLI you actually use
bin/skill_import.py # static skill parser + analyzer + apply() behind `loopctl import`
engines/ # codex · claude · fake
loops.d/<name>/ # loop.conf · precheck.sh · prompt.md · dashboard.json · SPEC.md
# + render.sh (executable = page-enabled)
pagekit/ # kit.css + toggle.js (renderers read + inline both) · envelope snippet · reference page
examples/ # hello-loop (daily agent) · hello-watchdog (15m interval)
state/loops.sqlite # runs · heartbeats · metrics · findings · dispositions (WAL)
reports/<name>/ # per-run markdown + atomically-promoted latest.* (suppression-filtered)
dashboard/loops.html # static: the garden — accordion rows with per-loop detail + report links inline
skills/loops/ # distributable Agent Skill — the front door agents install
site/ # roops brand · explainer + UI-concept pages · design system
tests/run-tests.sh # 1028 hermetic tests — no network, no real engines
| File | Purpose |
|---|---|
docs/LOOP_AUTHORING.md | Start here to build a loop — twelve-question intake interview, contract, worked example |
docs/SKILL_IMPORT.md | Convert an existing Agent Skill into a loop — rubric, buckets, reshaping rules, the trust section, answers.json |
docs/REPORT_PAGES.md | Build a report page — when to add one, render.sh contract, the publication gate |
docs/INTERFACES.md | Frozen mechanical contract every component implements |
docs/HARNESS_PLAN.md | Finalized harness design (plan-checked 3× with codex) |
docs/HARNESS_PLAN_AMENDMENT_1.md | Findings memory / human-in-the-loop amendment |
docs/ENGINE_PROBES.md | Verified live CLI behavior of codex + claude |
docs/LOOP_SELECTION.md | Approved loop themes — and what each still owes |
docs/OPEN_THREADS.md | Unfinished design threads — read before assuming something is settled |
$HOME-relative. macOS has no flock and no GNU timeout, so the harness uses an fcntl lock helper and runner-owned process-group timeouts.Compatible with: Codex CLI · Claude Code
docs/KAGAMI_SETUP.md | kagami's one manual credential step (GitHub PAT), and why |
site/CLAUDE.md | The roops design system — tokens, seal-font rule, concept vocabulary |
CLAUDE.md | Cold-start pointers + non-negotiables for agents |