Commit Graph
361 Commits
Author SHA1 Message Date
randRuFlo f047a545f0 fix(console): fold the Sessions list, honest wording, read budget for first reads, Codex sub-agent lineage
- Sessions list starts folded; jumping from the queue opens it.
- First reads past a pass's byte budget wait for the next pass ("not read yet").
- A Codex sub-agent rollout's trailing parent session_meta is lineage, not a second identity.
- ADR/CHANGELOG/README say discovery spawns nothing; the only write is the four-count summary.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-09 17:24:09 -04:00
randRuFlo c53bed71e3 feat(console,mods): session workspace on the Room: attention queue, session browser, preview (ADR-486)
Needs-you queue (approvals, questions, failures, finished-unread) across Claude Code, Codex and Ruflo
sessions, a browser grouped by repository and worktree, and a preview of the selected session. Local,
read-only discovery (no model call, no process); ambiguous identity goes to an unassigned bucket;
finished work clears only after its preview was drawn; transcript text never reaches a model, the
state, the disk or a text answer. ruflo-mods gains an optional counts-only attention row.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-09 17:18:27 -04:00
randRuFlo 0e99d1961a chore(console,swarm): console 0.40.8 and swarm 0.3.6 changelog and versions; merge main
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-09 12:49:55 -04:00
r dbbd1b14bc Merge remote-tracking branch 'origin/main' into w3942 2026-10-09 12:48:34 -04:00
randRuFlo 5e6e454ee5 chore(console): 0.40.7 changelog; merge main
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-09 12:33:15 -04:00
r 88bdd80977 Merge remote-tracking branch 'origin/main' into w3939 2026-10-09 12:32:12 -04:00
randRuFlo f407072f35 chore(console): 0.40.6 changelog; keep perf probe entries gated as delete (do not lower the gate); reduce instead of Math.max spread
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-09 12:14:54 -04:00
randRuFlo df6aea0a46 Merge origin/main into fix/console-display-truth
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-09 12:13:19 -04:00
randRuFlo 41b2175901 chore(console): 0.40.5 changelog; bound the answer scan on unclosed openers; merge main
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-09 12:11:58 -04:00
r 56ea638508 Merge remote-tracking branch 'origin/main' into w3934 2026-10-09 12:09:34 -04:00
randRuFlo 555ee880e7 chore(console): 0.40.4 changelog and version, drop regex fallback in isOpenTask, test wf-links isOpen
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-09 11:43:41 -04:00
Dragan SpiridonovandRuflo & AQE a6608e8c84 fix(console,swarm): linear ADR scope matcher, ADR titles refused not cut, ADR digest validated and framed, prototype-safe What's new
- adr-scope: each `*` became a stacked `[^/]*`, so an ADR scope entry with
  many stars hung the console (10 stars: 8-15 s, ~6x per star) during verify
  and goal suggestions. A segment-wise glob matcher with the same semantics.
- ADR-481: a title over 120 is refused with the count at the proposal itself
  (page field, adr-propose palette, console_run); a mission-objective draft
  title that is shortened says so on the confirm card; cuts and counts are in
  code points (no lone surrogates; 120 emoji read back whole).
- ruflo-swarm: .claude-flow/console/adr-digest.json (committable by a cloned
  repo) was appended to every subagent prompt unframed. The reader now accepts
  only the console's shape (statuses, file identity, washed text, no
  duplicates), quotes each record's text with marker words neutralised, and
  frames the block as project data. A model-level mitigation, not a boundary.
- What's new: plugin-name maps are null-prototype with own-key lookups;
  __proto__/constructor/prototype never enter seen, toasted, pinned or
  dismissed records.

Co-Authored-By: Ruflo & AQE
Claude-Session: https://claude.ai/code/session_01CGoza3gyxBjpaiMPhGHcHs
2026-10-09 16:27:56 +02:00
Dragan SpiridonovandRuflo & AQE f598890888 fix(console): disk writes work on macOS/BSD (append, exclusive create, create-with-folders, copy)
The console wrote every file through GNU-only argv: dd oflag=append
iflag=fullblock, dd conv=excl, install -D and cp --no-clobber. BSD dd,
install and cp (macOS) refuse all of them, so on a Mac events never
persisted ("345 waiting to write · write failed: the write exited 1"), ADR
initialise/propose never created a file (and blamed a race), exports and
first-time state files failed, the autopilot journal was never appended or
rotated, and its cross-session kill switch was never written.

- data/write-flavor.ts detects the platform once (uname -s, own 3 s
  deadline, process.platform fallback) before the controller exists; every
  flavor-dependent write awaits it and its builder requires the flavor.
- Linux keeps the GNU argv byte for byte.
- macOS/BSD use a frozen set of seven constant sh scripts with the path as
  "$1" (and "$2" for the copy source), never interpolated: each sets its
  umask, refuses a link or a non-regular target, uses noclobber for
  exclusive creates and creates missing folders. smoke.sh enforces the set.
- adr.ts reports the real write failure; worktree /proc specs skip off Linux.

Co-Authored-By: Ruflo & AQE
Claude-Session: https://claude.ai/code/session_01CGoza3gyxBjpaiMPhGHcHs
2026-10-09 16:23:20 +02:00
Dragan SpiridonovandRuflo & AQE 3c3ed992d0 fix(console): show times as times, a swarm's own agents, and labels that match the gate
- AgentDB mod panel read updatedMs through countOf, whose 1e12 cap (added
  in 44b157b52) clamps every epoch-ms time to 2001-09-09: "written 9161d ago
  (an earlier session)" for a file written minutes before. Times are read as
  times; implausible ones (before 2000, more than a day ahead) read n/a.
- Overview/Swarm/Workflows/status bar/topology credited a swarm with the whole
  agent store ("running · max 3 · 259 agents" for a swarm with 0 agents) and
  disagreed on its status (running vs finished). One helper
  (data/swarm-status.ts) gives each page the swarm's own listed/found count
  and its age; "stale" only on evidence (old record, no busy member, no
  recent member). An empty fresh swarm is still its own Workflows run; the
  roster of unlisted agents keeps the run id saved views and pins used.
- mission-goal's label said "(nothing is written)" but it is a write action;
  perf-bottleneck/optimize were gated as delete (needs full) because their
  note said the probe file is "removed". Labels and notes now match the gate.

Co-Authored-By: Ruflo & AQE
Claude-Session: https://claude.ai/code/session_01CGoza3gyxBjpaiMPhGHcHs
2026-10-09 16:14:47 +02:00
Dragan SpiridonovandRuflo & AQE df7af622ab fix(console): a verdict command's "found something" exit is an answer, and a failure names its real reason
security defend / scan / channel-scan / scan-plan and the metaharness alert
scripts exit non-zero to say "found something" while printing a valid JSON
verdict. The runner treated every non-zero exit as a failure, so exactly when
a safety check caught something, Claude (console_run / console_state) was told
it failed and got no verdict. Failure reasons took the first stderr line, which
on many installs is "[WARN] Skipped helper auto-refresh", hiding the [ERROR].

- ActionSpec.findings = { exits, isAnswer, found } per entry, taken from the
  CLI source: such an exit is an answer only when stdout holds a complete
  answer of that command's shape, judged on its top-level keys (a hostile span
  quoting "[ERROR]" or a nested failure cannot flip it), the answer says it
  found something, and nothing outside it (trailing stdout, stderr) reports a
  failure. A banner object before the verdict is skipped.
- The one-line outcome carries the verdict ("answered: UNSAFE · 2 threats").
- data/failure.ts: one failure-reason helper (wrapped MCP isError, top-level
  error, [ERROR] line, error-naming line; [WARN]/[INFO]/Parameters skipped),
  used by the runner, CLI probes and mission verify notes.

Co-Authored-By: Ruflo & AQE
Claude-Session: https://claude.ai/code/session_01CGoza3gyxBjpaiMPhGHcHs
2026-10-09 16:12:36 +02:00
Dragan SpiridonovandRuflo & AQE bc14216777 fix(task,console): task_update accepts only the five statuses; a task stored as "complete" is never shown pending or re-dispatched
task_update stored any string as a task's status, so an agent writing
"complete" left a finished task every reader misread: the ruflo-console
Automation kanban listed it under PENDING (offering assign/cancel), and
Mission Control derived it as ready, so nextTask() would hand finished work
to Claude again as a new billed turn.

CLI (mcp-tools/task-tools.ts)
- statusOf(): trimmed, case-insensitive, aliases complete/done/canceled/
  running/in-progress; anything else (incl. "" and prototype keys) is
  refused with the allowed list and the task is left unchanged.
- No schema enum on purpose: the HTTP/WebSocket registry validates enums
  before the handler, which would refuse aliases there but not over stdio.
- Completing through task_update now finishes the task as task_complete
  does (progress 100, completedAt, worker idle and counted once per
  hand-out); cancelling frees workers as failing already did. Worker
  effects run after the task store is saved.

Console
- taskStatusOf() reads the spellings older CLIs already stored; used by the
  kanban lanes and verbs, Mission Control derive (no re-dispatch), mission
  cancel, workflow links and the workflow guide.

Co-Authored-By: Ruflo & AQE
Claude-Session: https://claude.ai/code/session_01CGoza3gyxBjpaiMPhGHcHs
2026-10-09 15:54:18 +02:00
randRuFlo ba810a05fb fix(console): approvals badge counts only rows with an approve/deny action (0.40.3, #3920)
A refused mod or a permission deny has no action, so it held 'n to approve' up
with nothing to press. The band, menu badge, change notices and the Approvals
header now count waitingApprovalsOf(); notices stay listed, named apart.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-08 22:54:19 -04:00
3991f40670 fix(console): card-bound confirm, one model-facing sanitiser, linear escape stripping, own-key lookups, wrapped Approvals (0.40.2)
- A Yes runs only the card it was pressed on: every pending card has an id,
  the Yes / Always allow / Always accept buttons carry it, runner.confirm(seen)
  runs nothing (and says so) when another card took its place. A card Claude
  raised is re-checked against the level and Stop when it lands and when the
  Yes arrives.
- Everything returned to the model goes through modelLine (escapes, then
  control and invisible characters removed, cut, withheld whole when it holds
  a secret shape or an invite code) and every answer leaves through
  modelLines; a version such as v2.1.0-beta.3 is not an invite.
- ESCAPES is linear: an unterminated OSC ends at the next introducer or the
  end of the text (7.7 s on the old pattern became milliseconds on 1 MB).
- Mission state/status, hive role, audit severity and Settings plugin names
  that are Object.prototype keys read as unknown (own()).
- Approvals and a mission objective wrap at 80 columns instead of being cut
  with an ellipsis (#3899).

Specs ported from #3820, #3821 and #3822, adapted to main.

Co-authored-by: Dragan Spiridonov <spiridonovdragan@gmail.com>
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-08 17:38:02 -04:00
ruv 56a638190d fix(console): CLI launcher resolution and cold-start handling for settings writes (fixes #3914)
With the ruflo CLI option on npx, a confirmed action ran a cold online npx under the 90 s default and aborted with 'still running after 90000ms'. Resolve ruflo on PATH, a project-local bin or the cached npx copy first; give a cold download a 300 s limit and a first-run label; turn a timeout or ENOTCACHED into an error naming the fix. Console 0.40.1; ADR-407 update.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-08 15:25:08 -04:00
ruv aeaa51e99a feat(console): advisor checkpoints for mission loops (ADR-483)
Default-off Settings rows: a read-only claude -p consult (asked first, exact argv, turn budget, mission spend cap) before a plan locks, when the same check fails twice in a row, and before done; a third failure pauses the mission. Honest about not being the in-session advisor tool. Console 0.40.0.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-08 12:20:26 -04:00
ruv 817dcfe0e3 fix(console): manually entered text is never silently truncated (ADR-481)
The mission goal was cut at 500 characters and drawn on one clipped line; the host Input is one line and hides the rest. A live mirror
under every field shows all lines, views draw text in full with an explicit marker, limits are checked before sending with the exact
count, and every silent slice/plain cap on typed text is removed or made a counted refusal. console 0.39.1.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-07 18:20:32 -04:00
ruv 2a08b54a4c Merge origin/main into fix/console-input-truncation
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-07 18:14:01 -04:00
ruv dd180a29ed test: stronger wrap checks 2026-10-07 18:10:29 -04:00
ruv 7483d28f3c test(console): full-text helpers and input classes (ADR-481)
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-07 18:09:56 -04:00
ruv 5d3d145ac9 wip(console): inputs never cut: chokepoints raised, refusals counted (ADR-481)
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-07 18:02:19 -04:00
ruv bf67d3e304 wip(console): full-text helpers, mission goal never truncated (ADR-481)
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-07 17:44:12 -04:00
ruv b62b7d334c fix(console): keep the swarm ADR digest true to the active mission; verify's confirm names its git reads; real-pane ADRs test (ADR-480)
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-07 17:16:11 -04:00
ruv aed428c43e feat(console,adr): ADR management registry, page and mission/loop/swarm integration (ADR-480)
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-07 17:08:41 -04:00
ruv 578a1d3686 wip(console,swarm): ADR registry, page, mission/swarm integration (ADR-480)
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-07 16:54:03 -04:00
ruv 7670a02849 docs(plugins): CHANGELOG.md for every plugin in the ADR-478 format, derived from git history
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-07 14:37:29 -04:00
ruv 9cef4cb070 feat(console): What's new page under TOOLS, plugin changelog parser and marker (ADR-478), console 0.38.0
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-07 14:37:28 -04:00
ruv 04ff98bb32 fix(mods): a toast needs no engine.create (bind at session.start too), a throwing clock falls back to the wall clock; update the cost ladder expectation in the v3 mods contract
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-07 13:08:53 -04:00
ruv 24806b7e78 fix(mods): console toasts release held errors on a timer; settings section names toasts; ADR wording
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-07 12:54:37 -04:00
ruv 146febd999 feat(mods): shared toast system with levels, dedupe, persistence and Settings (ADR-477)
One dependency-free policy (canonical in ruflo-mods, byte-identical copies in console,
swarm and protector, checked by scripts/sync-toast-policy.mjs and each smoke.sh): level
prefixes, one washed line of at most 120 characters, 60 s de-duplication, four toasts a
minute per source with errors held and counted, the person's all/important/off setting and
per-source mute (console Settings, mirrored to a file the others read), and a digest of
every toast kept for the console's Events page. All call sites migrated; new toasts for a
mission that finishes or fails and a swarm subagent that fails or a loop that is stuck.

Versions: console 0.37.0, swarm 0.3.4, protector 0.1.1, mods 0.3.16.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-07 12:50:30 -04:00
ruv 1175bc19c9 Merge origin/main into feat/mod-toasts 2026-10-07 12:40:10 -04:00
ruv a65be10ed4 feat(mods): shared toast policy and its call sites (ADR-477), work in progress
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-07 12:40:10 -04:00
ruv b461822280 fix(console): CONSOLE_VERSION follows the manifest (0.36.1)
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-07 11:08:46 -04:00
ruv 5a0e5bff4a feat(console): Settings puts Claude control and spending first, folds ruflo config and plugin options to the end
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-07 10:29:40 -04:00
ruv 1ac200432c feat(console): 0.36.0 integration: eventsPersist option, shared whole-batch append argv, hostile-time hardening, init ignores console/
- plugin.json declares eventsPersist (default true); version 0.36.0 in plugin.json, version.ts, smoke.sh
- data/append-argv.ts: one dd argv (bs=1M iflag=fullblock) shared by the Events store and the autopilot journal; real-dd 8-writer test fails on the old argv
- history decoders and Events/Timeline displays use #3874's timeOf/countOf/isoOf, so a hostile time or count cannot throw
- cli init: .claude-flow/.gitignore template lists console/
- ADR-474 updated to the reviewed behaviour and the open low items

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-07 02:19:20 -04:00
ruv 027e180c39 Merge verify/events-0.36 into feat/console-0.36
Conflict in views/manage.ts: #3874 (isoOf) edited eventsView, which the Events work moved to views/events.ts; the move wins and the isoOf clamp is applied at every Events/Timeline site instead.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-07 02:19:20 -04:00
ruv 7782ccbf60 fix(console): log Claude's refused request when the person's card is waiting; mission-auto why when not wired; document the local-read allowlist
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-07 01:06:51 -04:00
ruv 44b157b522 fix(console): session control cap, gate on read-only entries that act, hostile text/data, mission auto-run guards (#3814 #3815 #3816 #3817 #3818)
- RUFLO_CONSOLE_CONTROL is kept as session state and applied on every load and save of the AI prefs; only the person's own level is stored (#3814)
- A Claude call to an entry flagged read-only that spends, writes or reaches the network is queued for the level/budget/confirm gate; deferred asks keep their origin and are awaited; Claude's ask never replaces a waiting card; mission-auto parses on/off (#3815)
- One strip set for plain() and termText(); guidance errors and perf readers cleaned; console_state withholds secret-looking lines and invite codes (#3816)
- Times clamped to Date's range, counts and ratios bounded, unique Room ids, links never read as docs, own-property cli option, objectIn closes at the JSON end (#3817)
- A failed task_update sends no prompt, hand-outs are limited, the cap needs a fresh reading and is read off-page, cap 0 is refused (#3818)

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-07 00:57:27 -04:00
ruv b17a497916 chore(console): 0.35.0; re-sign the helpers manifest for the recall-log hook changes (ADR-472)
Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-06 19:19:42 -04:00
ruv 0406f27b4b merge feat/recall-log-vectors-0.35 2026-10-06 19:17:27 -04:00
ruv 128266082b merge feat/autopilot-complete-0.35 2026-10-06 19:17:27 -04:00
ruv 978572d731 merge fix/control-verified-0.35 2026-10-06 19:17:27 -04:00
ruv 7f560f7d72 merge fix/console-layout-0.35 2026-10-06 19:17:27 -04:00
ruv b531aa9279 perf(console): incremental transcript parsing, kit-seq runner, tsc clean for specs (ADR-473)
A transcript that grew is parsed from where its last parse ended, not from its
first line: checked resume (head + anchor), unfinished last line taken back,
bounded ring and id set, LRU memo, tail windows by unique anchor. Reference
parsers untouched and used as the oracle by a seeded property test plus
mutation checks. Refresh warms the parse memo for the search (400k chars a tick).

scripts/kit-seq.sh runs the 25 kit tests one file at a time in a temp copy;
scripts/typecheck.sh makes tsc find the ambient types in a fresh worktree; the
specs' type errors are fixed (sources of other lanes listed in the report).

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-06 19:16:55 -04:00
ruv 75b0188e0d feat(ruflo-console): autopilot envelope editor, parallel hand-over, spend windows, band segment, and the first live run (ADR-470)
- list editor for folders, repos, hosts, secret names and verify commands, every edit checked by the loader's own validator, shown as a diff against the approved envelope
- bounded parallel hand-over up to min(envelope concurrency, adaptation) through a narrow startable() beside nextTask; a park no longer holds the other tasks back
- spend: windows never start before Start, Claude Code only, unpriced models and old trackers say why the reading is unknown
- the band segment is drawn through registerBarSource
- ruflo autopilot_* tools: probed, not used (ADR-470 section 2.5)
- live run in a scratch repo found and fixed: dead 8/9 hotkeys, Start unreachable without a run, an input-less permission probe that parked every task, a failed record for a step that finished after Stop, a lost step retried without a question, a false "allow every class"

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-06 19:14:02 -04:00
ruv a6f35488df fix(ruflo-console): control plane measured in an interactive session (ADR-471)
Replaces every "unverified" label with what Claude Code 2.1.289 actually answered:
- Stop a run: TaskStop takes the Workflow TASK id (read from the session transcript, last launch wins); the wf_ run id and a workflow agent's id are "No task found", so Stop-one-agent is removed and shows the engine's refusal.
- Message: delivered mid-task to a running workflow agent; to a named Agent-tool agent it arrives when its turn ends (161-165 s measured).
- $.tool.call opens the engine's real dialog for ask-class tools; deny resolves {deny}; never bypassed.
- Codex "tokens used" is a total (tokensTotal), stdout trimmed; federation argv checked against the helper's parser; stub OpenAI endpoint receives the card's exact bytes; the engine does not block link-local, so isBaseUrl is the only SSRF gate.
- Real answers are fixtures (tests/fixtures/control-real.ts); new wf-send-stub spec uses a real HTTP server.

Mutation check: 13 mutations (first-launch task id, run id passed to TaskStop, deny ignored, tool_use_error kept, stop-agent spec, codex total as output, untrimmed error, link-local allowed, plain http, transcript path unchecked, huge transcript unread, task id never re-read, usage field on every endpoint) each killed.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-10-06 19:02:33 -04:00