Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
52d1e8b
feat(capacity): publish the dashboard as a persistent tailnet-only co…
purple-phoenix Jul 28, 2026
4f6483c
no-mistakes(review): Harden dashboard rendering, refs, and plist gene…
purple-phoenix Jul 28, 2026
309dd59
no-mistakes(review): Harden dashboard commands, decisions, usage, and…
purple-phoenix Jul 28, 2026
290aef0
no-mistakes(review): Harden decision routing and durable dashboard de…
purple-phoenix Jul 28, 2026
eacd860
no-mistakes(review): Origin-qualify dashboard decision identities
purple-phoenix Jul 28, 2026
7768227
no-mistakes(review): Align dashboard contracts and unregister disable…
purple-phoenix Jul 28, 2026
6ba0a63
no-mistakes(review): Persist and clean up dashboard serve ports
purple-phoenix Jul 28, 2026
aa82bd5
no-mistakes(review): Make dashboard port changes transactional
purple-phoenix Jul 28, 2026
75b09c5
no-mistakes(review): Make dashboard installation fully transactional
purple-phoenix Jul 28, 2026
cce96d6
no-mistakes(review): Restore only observed dashboard mappings during …
purple-phoenix Jul 28, 2026
597973a
no-mistakes(review): Protect occupied Tailscale serve ports during in…
purple-phoenix Jul 28, 2026
3cb44da
no-mistakes(review): Protect foreign mappings during dashboard uninstall
purple-phoenix Jul 28, 2026
2086b13
no-mistakes(review): Classify foreign serve mappings without blocking…
purple-phoenix Jul 28, 2026
da1f682
no-mistakes(test): Captain: align capacity blocker identity expectation
purple-phoenix Jul 28, 2026
32220a3
no-mistakes(document): Document persistent tailnet capacity dashboard
purple-phoenix Jul 28, 2026
50bb3f5
no-mistakes(lint): Captain: targeted ShellCheck notices silenced
purple-phoenix Jul 28, 2026
761c3f0
no-mistakes: apply CI fixes
purple-phoenix Jul 28, 2026
e7cbd85
fix(dash): honest prod rendering - launchd env, no fabricated decisio…
purple-phoenix Jul 28, 2026
34751ed
no-mistakes(review): Fix captain decision, blocker, and degraded-stat…
purple-phoenix Jul 28, 2026
4d3cfd2
no-mistakes(review): Preserve captain blocker roots and tiny-fleet de…
purple-phoenix Jul 28, 2026
4da5461
no-mistakes(review): Resolve captain blocker roots with bounded trave…
purple-phoenix Jul 28, 2026
d5604ad
no-mistakes(review): Complete captain blocker roots across cycles and…
purple-phoenix Jul 28, 2026
6d7b2b1
no-mistakes(document): Document dashboard command handling and keyles…
purple-phoenix Jul 28, 2026
00a5b57
no-mistakes(document): Correct dashboard claim handling reminder
purple-phoenix Jul 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion .agents/skills/capacity/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ Do not assemble a competing snapshot with ad hoc state reads, GitHub calls, term
Never infer current state from `state/<id>.status`, because it is append-only wake-event history rather than current-state truth.
Do not scrape scout reports, browser review artifacts, or Lavish surfaces to discover decisions.
Structured captain holds and the keyed open-decision fold are the only decision inputs.
Decision filing and its structured options document are owned by the decision-hold lifecycle.

The generated dashboard is a polished, responsive, accessible, self-contained HTML file that works directly from disk.
Do not invoke, depend on, open, poll, share, or embed Lavish for `/capacity`.
Do not expose the dashboard through a local, LAN, Tailscale, public, or third-party service.
Do not expose the dashboard through any local, LAN, public, or third-party service; the sole sanctioned exposure is the tailnet-only dashboard service in section 6, and even that surface is never Funnel and never public.
The normal invocation may replace only the generated private dashboard and must not write a cache unless the producing script's help explicitly adds and owns one in the future.
Never put secrets, credentials, PHI, production data, or report bodies into the dashboard.

Expand Down Expand Up @@ -84,3 +85,20 @@ Do not compare against, incrementally patch, or rely on the prior dashboard as c
The normal `/capacity` invocation is read-mostly and must not dispatch, merge, tear down, mutate task state, edit the backlog, register decisions, or create speculative work as a side effect.
If the fresh result reveals an action, report its stable ID and wait for or discuss the captain's ordinary chat direction.
Continue the already-required live supervision cycle after presenting the result whenever fleet work or X mode is under way.

## 6. Dashboard command service

The optional persistent dashboard service (`bin/fm-dash-serve.mjs`, installed by `bin/fm-dash-install.sh`, designed in `docs/dashboard-service.md`) publishes the generated dashboard tailnet-only, never Funnel, and lets the captain click a current `CAP-NN` action or a server-side refresh.
The service never executes fleet commands: a click only writes a durable command record into `state/dash-inbox/`, and the registered `fm-dash` watcher check wakes Firstmate while records are pending.
Its refresh button reruns the producer server-side and is equivalent to a fresh normal invocation, so it needs no Firstmate action.

On a `check:` wake naming `fm-dash.check.sh`, run `bin/fm-dash-inbox.sh claim` and handle each claimed record by its kind:
Claim delivery is at-least-once across interruption, so check whether a re-surfaced record was already handled before applying it again.

- A `CAP-NN` record is the captain's ordinary chat approval of that action ID under section 4, including its full re-resolution and authority limits.
- A `decision` record is the captain's answer for the owner-qualified decision identity with either the recorded option text or bounded custom answer; route `decision_origin` in `decision_home` through `decision-hold-lifecycle` exactly as a chat answer, and re-confirm in chat before acting when the answer has a destructive or irreversible consequence.
- An `idea` record is the captain's verdict on the named `data/ideas/` idea: on approve, create the follow-up work item(s) through the normal backlog lifecycle; on deny, record the outcome against the idea; on suggest, treat the suggestion text as captain input on that idea.

A claimed record never authorizes a PR merge, `local-only` landing, destructive action, irreversible action, security-sensitive action, or discard of unlanded work; when a claimed action leads to such a choice, escalate it to captain chat exactly as section 4 requires.
Report the outcome of handled commands to the captain through normal escalation etiquette rather than assuming the dashboard told them.
While the service is installed and registered, treat pending dashboard commands like X-mode mentions for supervision: keep the live supervision cycle running even with no other fleet work so a click can wake Firstmate.
4 changes: 3 additions & 1 deletion .agents/skills/decision-hold-lifecycle/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ This skill is the single policy owner for unresolved captain decisions discovere

## Policy

Before filing a new decision, author its title, context, options, and per-option impacts in the origin-qualified format owned by `docs/dashboard-service.md`, then pass that file to `bin/fm-decision-hold.sh hold --options-file`; legacy holds that already exist without a document remain answer-in-chat decisions.

Every unresolved decision that belongs to the captain and is discovered while producing, reading, presenting, or ending an investigation or visual review must become a structured captain-held work item in the authoritative backlog of the home that owns the originating work before that work or review may be treated as complete.
The agent performs the semantic inventory because scripts must not infer decisions from report prose, visual-review artifacts, terminal output, or chat.
Give each distinct unresolved decision a stable privacy-safe key, register it through `bin/fm-decision-hold.sh hold`, and use the same key on retry so registration is idempotent while different decisions retain different durable identities.
Expand All @@ -29,7 +31,7 @@ Bearings reads the resulting structured state and must never compensate by scrap

1. Read the complete investigation result and complete the visual review before declaring either complete.
2. Inventory only genuine unresolved choices that require the captain.
3. For each choice, choose a stable key and use the script's `hold` command with a concise title, reason, and repository.
3. For each choice, choose a stable key, author its options document, and use the script's `hold --options-file` command with a concise title, reason, and repository.
4. Run the script's `complete` command with the full unresolved-key inventory for that review pass.
5. Relay the choices to the captain as decisions from Bearings' Captain's Call section under `AGENTS.md` section 9; do not use the word hold in captain chat.
6. After the captain decides, record dependent work with normal tasks-axi commands and block it by the hold identity.
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ config/backend
config/x-mode.env
config/cmux-socket-password
config/wedge-alarm
config/dash.json
7 changes: 6 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ config/backend runtime session-provider backend override for new tasks; LOCAL,
config/cmux-socket-password optional cmux control-socket password; LOCAL, gitignored; read fresh on every cmux CLI call and passed through without ever overriding an operator's own ambient CMUX_SOCKET_PASSWORD when absent (docs/cmux-backend.md "Setup")
config/wedge-alarm optional away-mode wedge-alarm active-alert directives; LOCAL, gitignored; absent means auto (macOS Notification Center when available); see docs/wedge-alarm.md
config/x-mode.env generated X-mode watcher cadence; LOCAL, gitignored; source before arming watcher when present
config/dash.json optional capacity dashboard service settings (loopback port, authorized captain tailnet logins); LOCAL, gitignored; written by bin/fm-dash-install.sh (docs/dashboard-service.md)
data/ personal fleet records; LOCAL, gitignored as a whole
backlog.md task queue, dependencies, history
captain.md this home's domain-local captain preferences and working style; LOCAL, gitignored, canonical even if harness memory mirrors it, and updated with inspect-then-update
Expand Down Expand Up @@ -99,6 +100,9 @@ state/ volatile runtime signals; gitignored
x-context/ generated X-mode durable per-request reply context (platform/budget), keyed by request_id; survives inbox cleanup so a delayed follow-up recovers the original platform (section 14; bin/fm-x-lib.sh)
x-outbox/ generated X-mode dry-run reply and dismiss previews; inspect it when FMX_DRY_RUN is set (section 14)
x-poll.error generated X-mode relay diagnostic dedupe marker
fm-dash.check.sh registered dashboard-service command poll; wakes firstmate while captain dashboard commands are pending (section 7; docs/dashboard-service.md)
dash-inbox/ durable captain commands clicked on the served capacity dashboard; delivered at least once with idempotency checks under the capacity skill
dash-refs.json producer-owned private mapping from opaque dashboard references to real identities, written by fm-capacity.mjs --refs for the authenticated dashboard service
.wake-queue durable queued wakes: epoch<TAB>seq<TAB>kind<TAB>key<TAB>payload
.wake-queue.seq monotonic wake sequence used to distinguish a normal watcher wake handoff from a silent arm-cycle death
.watcher-arm-dead durable alarm from an arm cycle that ended without a wake handoff or healthy successor while tasks remain; cleared by a confirmed healthy arm or normal handoff
Expand Down Expand Up @@ -313,14 +317,15 @@ When the captain invokes `/user-journey-audit` or explicitly asks for a user-jou
That invocation narrowly authorizes confirmed ordinary reversible bug implementation, never feature implementation or merge, and the skill owns the conditional procedure.

When the captain invokes `/capacity` or asks about capacity, bottlenecks, pipeline utilization, work supply, idle lanes, or maximizing fleet throughput, load `capacity`.
Also load `capacity` on a `check:` wake naming `fm-dash.check.sh`: it delivers captain-clicked dashboard commands, and the skill owns their claim and handling.
That read-mostly skill owns the conditional procedure and must never invent work, dispatch for utilization, or weaken lifecycle safety.

## 8. Supervision protocol

Fleet supervision is an always-loaded operational contract; `docs/architecture.md`, `docs/turnend-guard.md`, the emitted session-start block, and script help own mechanisms and harness-specific recipes.

Whenever work is under way, keep exactly one live supervision cycle using the emitted protocol for this primary harness.
X mode may require that same live cycle with no fleet work.
X mode or an installed dashboard command service may require that same live cycle with no fleet work.
Do not substitute another harness's wait shape, use shell `&`, or create a second cycle when a healthy one already exists.
After every actionable wake, resume the emitted protocol as the final action before ending the turn.
No turn ends blind while work is under way, including turns described as holding or waiting.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ Claude and grok use the slash form shown here; codex uses the same names with `$
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `/afk` | Enter away-mode supervision: the sub-supervisor self-handles routine notifications in bash, escalates captain-relevant events and bounded declared-external-wait rechecks as batched digests, and actively alerts if delivery gets stuck while you step away |
| `/bearings` | Generate a standalone current-status report from bounded local fleet and registered-secondmate state, with live PR enrichment only when requested, written to a dated file in `data/` and surfaced concisely in chat; read-mostly, mutates no task state |
| `/capacity` | Diagnose meaningful ready-work supply and delivery bottlenecks, render a private offline pipeline dashboard with stable action IDs, and keep all approved follow-ups inside the normal safety lifecycle |
| `/capacity` | Diagnose meaningful ready-work supply and delivery bottlenecks, render a private offline pipeline dashboard with stable action IDs, optionally publish it through the persistent tailnet-only dashboard service, and keep all approved follow-ups inside the normal safety lifecycle |
| `/user-journey-audit` | Audit one isolated local application through browser-driven, product-derived personas, automatically route confirmed ordinary bugs for fixes, and queue grounded feature opportunities without implementing or merging them |
| `/updatefirstmate` | Self-update the running firstmate and its secondmates to the latest from origin with fast-forward-only pulls, then re-read instructions and nudge secondmates |
| `/stow` | Sweep the session for uncaptured durable knowledge, route each finding to its disk home per AGENTS.md, file undone next steps to the backlog, and report what is now safe to reset |
Expand Down
Loading