You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 23feaaf
Browse filesBrowse the repository at this point in the historyBrowse files
console: Audit & Setup view; Timeline, Setup, Venues, Balances and Plans retired -- four views (#13 PR4) (#966)
* timeline: blocked on system rows; kind=keel composite filter
Cycle rows now name their blocked count between signals and entered
("blocked unknown" when a cycle object carries none). gather_timeline
learns one composite kind word, keel = {system, attestation}, echoed
back and listed first in kinds_present when either member is present;
the CSV export resolves it the same way so the file matches the screen.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* console: Audit & Setup view; Timeline, Setup, Venues, Balances and Plans retired
One auditView at /audit reads /api/setup (primary, needs no database, so
the stopped view's setup link lands somewhere that answers), /api/timeline
and /api/venues. Its sections are exported builders: timelineSection
(opens on kind=keel, seeded once at boot; chips, CSV, chain verdict),
setupSection (stage tabs, page-level job panel; the CSRF token is still
remembered from this reading) and readinessSection (readiness only).
The nav is Pulse, Holdings, Rules, Audit & Setup plus Docs. /setup,
/timeline, /venues, /balances and /plans join RETIRED_CLIENT_ROUTES;
main.js's MOVED_ROUTES sends the first three to /audit, the rest land on
Pulse. /api/balances, /api/plans, their readers and payload builders,
keel/commands/plans.py and keel/commands/balances.py (no CLI reads
either) and their tests are removed, with positions.with_readiness (its
only caller was gather_balances) and docs.TERMS's venue 'session'.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* gates: say where the Tier 1 phrase is actually public
The docstring said "the modal prints it"; no resume modal exists. The
phrase is a literal in TIER1_ACTIONS; release is keel resume /
keel resume-entries at a terminal behind the TTY gate.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* serve: help and runbook name the POST surface instead of claiming GET/HEAD only
keel serve --help said the server implements GET and HEAD and nothing
else; do_POST has served /api/setup/<step> since #437 and the gate
routes (halt, resume, resume-entries) since #781. The help now names
each POST and how it is gated, and a test derives the expected routes
from server.py's constants and gates.TIER1_ACTIONS so it cannot drift.
The operator runbook carried the same claim and is corrected.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(web): ROUTES sweep covers every data GET and cannot drift again
ROUTES, the secret-leak and create-nothing sweep, listed 7 of the API
routes; timeline, the CSV export, the four research reads and dca-plan
were never swept. A new test holds ROUTES equal to api.API_ROUTES plus
CSV_EXPORT_PATH, minus /api/balances and /api/plans (being removed in a
parallel change; _ROUTES_BEING_REMOVED is marked for deletion) and the
SSE stream. The sweeps now assert each route actually answered, so they
cannot pass by reading 404 bodies.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(web): the ROUTES sweep needs no exclusion now /api/balances and /api/plans are gone
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs: the four console views
The runbook's console section names Pulse, Holdings, Rules and Audit &
Setup, with a paragraph each, and says where the retired Timeline, Setup,
Venues, Balances and Plans views went (pinned in test_runbook_console).
architecture.md and the go-live runbook say the same.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* serve: the startup line names the console, not a read-only view
The console halts the engine and runs setup steps, so 'keel is serving a
read-only view' was false. Pinned in test_serve_command.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(web): pin routeFor's moved-name lookup whole
A lookup whose result was discarded left /setup landing on Pulse with the
suite green (mutation run).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(web): the composite-kind export test tolerates an engine log in the cwd (#964)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(console): keep the applied keel chip, say when the engine log is missing, pin the timeline error split
The keel chip stays on the bar when it is the applied kind, so a window with only
trades and flows no longer opens on an empty table with no current chip. The
timeline wire carries the engine-log status and the page renders one line when
the log did not reach it. The no-database / read-failed branches of
timelineSection are pinned to their own output.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(console): comments and docstrings this PR made false; drop dead _JOB_REFRESH_SEC
Module docstrings, the KeelHandler docstring, the PWA manifest description and
sw.js no longer say the console is read-only or GET-only: it halts and runs setup
steps. Comments naming deleted venueCard / balances view are reworded. The unread
_JOB_REFRESH_SEC is removed. A test pins the manifest description.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs: living docs say the console halts and runs setup; dated notes on historical docs
Runbook, remote-access and the web UI spec are rewritten to be true (four views,
gates POST surface, HALT from a tunnel, no release control drawn). The PR plan,
evolution plan and presentation get short 2026-10-11 correction notes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(runbook): the console section names the HALT route instead of "no verb"
The runbook no longer says the server implements no verb that reaches a
capability-increasing action (it serves halt and two phrase-gated releases), so
the pin asserts the true property of the server and the routes that write.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(console): round-2 review - write-surface wording, engine-log state, capability text
N1: five docstrings no longer say do_POST routes only through setup.ACTIONS; a source scan pins it.
N2: the engine-log note state follows TimelineReport.log_gap, so the page and the CSV agree
(empty warns); each status is pinned to its exact sentence and state.
N3: kinds_present says keel also leads when it is the applied filter.
N4: the runbook count is the registry's (ten) and the /api/gates/ sentence is asserted whole.
N5: web capability rows name POST /api/gates/<key>, not buttons the console never drew.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/evolution-plan.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -250,6 +250,8 @@ itself is a moat, because every competitor's UI depends on hiding what keel show
250
250
- Feature-gating inside the engine. The Plans page ships **inverted** (#706): a
251
251
transparency artifact stating what is free forever and why — not a paywall matrix.
252
252
253
+
> **Correction (2026-10-11).** The console is now four views (Pulse, Holdings, Rules, Audit & Setup). The Venues and Plans views named above are retired: venue readiness lives on Audit & Setup, and the declared capabilities stay with `keel brokers list`. Holdings has no cancel control (cancelling stays `keel orders cancel`), so "one-click even from the web" below describes the 2026-08 design, not the present console. The console's one-tap action is HALT, on Pulse.
254
+
253
255
### What keel does beyond parity
254
256
255
257
-**The cancel asymmetry** (#707): cancelling an entry is refusing risk — frictionless,
Copy file name to clipboardExpand all lines: docs/operator-runbook.md
+42-17Lines changed: 42 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -421,15 +421,19 @@ It prints a URL carrying a one-time token for that run and opens your browser (`
421
421
skip). The `--config`/`--db` pair still decides which account you are looking at, and still bites
422
422
the same way.
423
423
424
-
It is **read-only**, and structurally so: the server answers `GET` and `HEAD` and implements no
425
-
other verb, so there is no request it can answer that changes anything. Attesting, promoting a
426
-
rule, recording a flow and arming autonomy stay CLI commands behind the interactive-terminal gate.
424
+
It **reads with `GET` and `HEAD`, and its writes are a closed set of `POST`s** under `/api/`:
425
+
`/api/gates/halt` engages the kill-switch (a gate token, nothing more — stopping must never be
426
+
slower than starting); `/api/gates/resume` and `/api/gates/resume-entries` release a halt only
427
+
from a loopback session on a loopback bind, with a gate token and a typed phrase (the console
428
+
offers neither — release a halt with `keel resume` at a terminal); and `/api/setup/<step>` runs
429
+
one of `keel setup`'s idempotent mechanical steps. Attesting, promoting a rule, recording a flow
430
+
and arming autonomy stay CLI commands behind the interactive-terminal gate.
427
431
428
432
Four things stand between that page and the rest of the machine: it binds `127.0.0.1`; it checks
429
433
the `Host:` header, so a hostname rebound to loopback is refused even though its packets arrive
430
434
on loopback; it requires the session token, which is minted per run and never written to disk; and
431
-
it serves no write verb. `--host` will bind anywhere you ask, and says plainly what that costs —
432
-
on a non-loopback address your positions, equity and full trade history are readable by anyone who
435
+
every write also needs the console's own request headers and a token derived from that session.
436
+
`--host` will bind anywhere you ask, and says plainly what that costs — on a non-loopback address your positions, equity and full trade history are readable by anyone who
433
437
can reach the port, with a cleartext token as the only obstacle.
434
438
435
439
**Placing an order is gated differently.** Paper places freely against synthetic cash — nothing is
@@ -836,12 +840,11 @@ Rewards item: account settings no rail can see, re-checked after any account cha
836
840
837
841
## The operator console, in a browser
838
842
839
-
`keel serve` opens keel's **operator console**: a local web page showing Pulse (the home view),
840
-
Setup, Holdings, Balances, Timeline, Rules, Venues and Plans, over the same `keel/commands/*`
841
-
service layer the CLI commands call. It is being slimmed to four engine
842
-
views -- Pulse, Holdings, Rules, Audit & Setup; see
843
-
`docs/superpowers/plans/2026-10-10-console-four-views.md`. An architectural test (`tests/commands/test_console_thinness.py`) pins that thinness -- the
844
-
front-end renders and dispatches, and every behaviour comes from the services.
843
+
`keel serve` opens keel's **operator console**: a local web page with four engine views -- Pulse
844
+
(the home view), Holdings, Rules and Audit & Setup -- plus a link to the documentation, over the
845
+
same `keel/commands/*` service layer the CLI commands call. An architectural test
846
+
(`tests/commands/test_console_thinness.py`) pins that thinness -- the front-end renders and
847
+
dispatches, and every behaviour comes from the services.
845
848
846
849
```bash
847
850
keel --config config.live-sandbox.yaml --db keel-live.db serve
@@ -850,6 +853,11 @@ keel --config config.live-sandbox.yaml --db keel-live.db serve
850
853
It binds loopback and prints a URL carrying a one-time token for that run. Stopping the server
851
854
invalidates it: the token is new every run.
852
855
856
+
**Pulse.** The glance page: the kill switch, autonomy and its lapse, today's cycle counts
857
+
(signals, entered, blocked, errors), why keel did not trade, the last cycle's time, the next DCA
858
+
buy due per live DCA rule, data freshness and the market session, and any tranche missing its
859
+
bracket. It carries the HALT button (below).
860
+
853
861
**Holdings.** One table of open tranches per rule: per-tranche cost (what the tranche paid to
854
862
open, entry fee included), the entry-gate verdict, the asset attestation, the bracket, the stop
855
863
only when a tranche carries one, and the entry order's placement and expected-vs-actual fill. The
@@ -867,10 +875,22 @@ command it shows, at a terminal), then the research record: every trial, the evi
867
875
gauntlet and the slippage assumptions. Track records, promotion-gate distances and the research
868
876
record used to be the Insights and Research views. The equity charts and the closed-trade table
869
877
left the console: the closed-trade journal is `keel insights journal`, your own journal is `keel
870
-
journal list`, and in the browser every fill is still a Timeline `trade` row and every journal
871
-
entry a Timeline `attestation` row. A live rule's track record is `keel insights summary --mode
878
+
journal list`, and in the browser every fill is still a `trade` row on the Audit & Setup timeline and every
879
+
journal entry an `attestation` row there. A live rule's track record is `keel insights summary --mode
872
880
live`.
873
881
882
+
**Audit & Setup.** The tamper-evident timeline, the setup checklist and venue readiness, on one
883
+
page. The timeline opens on keel's own record -- `kind=keel`, the engine's cycle rows (each with
884
+
its signals, blocked, entered, exited and error counts) and the attestations -- and the `trade`
885
+
and `flow` chips (or `all`) bring back fills and cash flows; the Export CSV link carries the same
886
+
scope and kind, so the file holds what the screen shows, with each row's hash and chain status.
887
+
Below it is Setup: the runbook stages as tabs, each mechanical step a button, and the job panel
888
+
reporting a running step such as the market-data fetch. Last is venue readiness: whether a live
889
+
entry can be placed on this deployment now, and the fix when it cannot. The adapters' declared
890
+
capabilities are `keel brokers list`. This page is where "Set keel up on this machine" lands
891
+
when no deployment exists yet, and the old `/setup`, `/timeline` and `/venues` addresses open it.
892
+
The Balances and Plans views are gone; their old addresses open Pulse.
893
+
874
894
**Halting from the browser.** Pulse carries a HALT button. It engages the kill switch through the
875
895
same operation `keel kill` performs (`POST /api/gates/halt`), after one confirm dialog and nothing
876
896
else: stopping must never be slower than starting. It needs the console session and the gate token
@@ -998,10 +1018,15 @@ covers the rest from a plain shell.
998
1018
999
1019
**What the browser cannot do, and that is deliberate.** Every capability-increasing action --
1000
1020
arming autonomy, releasing the kill-switch, clearing a consecutive-loss halt, re-seeding the
1001
-
drawdown high-water mark, declaring a deposit or withdrawal, attesting withdrawal capability, and
1002
-
replacing the binary -- is a CLI command behind a typed confirmation at an interactive terminal.
1003
-
`keel capabilities` lists all seven with the gate covering each. The server implements no verb
1004
-
that would reach one, so this is a property of the server rather than of what the page draws.
1021
+
drawdown high-water mark, declaring a deposit or withdrawal, attesting withdrawal capability, scope
1022
+
or posture, declaring an out-of-band close, and replacing the binary -- is a CLI command behind a
1023
+
typed confirmation at an interactive terminal. `keel capabilities` lists all ten with the gate
1024
+
covering each. The one exception is the console's
1025
+
HALT button, which engages the kill-switch (stopping is never gated). The server's gated routes
1026
+
under `/api/gates/` can also release the kill-switch and clear the consecutive-loss halt, but only
1027
+
for a loopback session on a loopback bind with the typed phrase, and the page draws no control for
1028
+
either: releasing remains a terminal act in practice. Everything else in the list has no route
1029
+
at all, so that is a property of the server rather than of what the page draws.
Copy file name to clipboardExpand all lines: docs/presentations/se.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -80,6 +80,8 @@ packages/ the uv workspace (7,190)
80
80
└── keel-broker-fake/ ⭐ adapter existing ONLY to exert design pressure on the port
81
81
```
82
82
83
+
*Note (2026-10-11): `web/` is no longer purely read-only. The console halts the engine (the HALT button on Pulse) and runs idempotent setup steps; releasing a halt and every other capability-increasing action stays at the terminal.*
84
+
83
85
**Two things to notice before we go further.**
84
86
85
87
`commands/` is 23,188 lines — larger than the engine it drives. That is deliberate rather than
Copy file name to clipboardExpand all lines: docs/superpowers/plans/2026-10-10-console-four-views.md
+6Lines changed: 6 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,11 @@
1
1
# Console — four engine views (Pulse · Holdings · Rules · Audit & Setup) — Implementation Plan
2
2
3
+
> **As built (correction note, 2026-10-11).** This plan is kept as written; where it differs from what shipped:
4
+
> -**PR2 (Holdings):** the entry order is matched by product, BUY, `placed <= opened_at` and the exact fill price (nearest earlier wins), NOT by the `created_at == opened_at` timestamp join -- paper stamps orders with bar time and tranches with cycle time, so the join missed every paper tranche.
5
+
> -**PR3 (Rules):**`rules_payload(records=...)` is a required keyword, not `None` falling back to `count(0)` (a zero nobody passed is unknown-as-zero); the CSV export link gets no class, not `.linkaction`.
6
+
> -**PR4 (Audit & Setup):**`keel/commands/balances.py` was deleted, not kept (no `keel balances` CLI exists; the web reader was its only caller). The Audit sections are exported builders (`setupSection`, `timelineSection`, `readinessSection`), so the key-parity scan runs per section against its own endpoint rather than `_view_keys("auditView", "setup")`. `timelineSection` takes the read error as an argument: no database reads "No timeline yet: there is no database on this machine. Setup creates one.", a failed read reads "The timeline could not be read: <detail>" (not "keel isn't running here yet"). The timeline wire also carries `engine_log`, and the page says when the engine log is missing or unreadable.
7
+
8
+
3
9
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. Never ask the user anything; every open question in this initiative is settled in a "Rulings" list below.
4
10
5
11
**Goal:** Replace the console's thirteen screens with four engine views -- PULSE (home, with the HALT button), HOLDINGS, RULES, AUDIT & SETUP -- shipped as four sequential PRs, each leaving the console fully working and the suite green. The ledger's "Done means" (`.superpowers/orchestrate/2026-10-10-console-four-views/ledger.md`) is the acceptance list; the screen inventory with line numbers is `inventory.md` beside it. Line numbers below are at BASE_SHA `9b1db8755cf7ac6a65cb118c615dc8e630998143`.
Copy file name to clipboardExpand all lines: docs/superpowers/specs/2026-08-23-web-ui-rewrite-design.md
+9-2Lines changed: 9 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,6 +3,12 @@
3
3
**Date:** 2026-08-23 · **Status:** shipped. Every step of §"Build order" landed (#533–#541, v0.12.0);
4
4
kept unrewritten as the design record.
5
5
6
+
**Note (2026-10-11):** the console is now four views -- Pulse, Holdings,
7
+
Rules, Audit & Setup -- and its write surface also includes a gates POST surface (`/api/gates/*`,
8
+
#781; the console's HALT button uses `halt`). Where this document names the earlier views
9
+
(Status, Activity, Gates, Timeline, Setup, Venues, Balances, Plans) or says the write surface is
10
+
only `setup.ACTIONS`, read it as the 2026-08 design, not the present.
11
+
6
12
This document describes the browser interface keel serves from the operator's own machine: what the
7
13
server does, what the client does, and why each decision was made the way it was. It follows the
8
14
shape of [youperiod.app's SPECS.md](https://github.com/getify/youperiod.app/blob/main/SPECS.md) and
@@ -137,8 +143,9 @@ Subresource Integrity authorises any inline `<script>` or `<style>` block, as in
137
143
3.**A session token**, minted per run, never written to disk, exchanged on first load for a
138
144
`SameSite=Strict`, `HttpOnly` cookie. `Strict` rather than `Lax` is deliberate: `Lax` attaches the
139
145
cookie to top-level navigations, so a link on a hostile page would arrive authenticated.
140
-
4.**A closed action set.** The entire write surface routes through `keel.commands.setup.ACTIONS`,
141
-
every member declared `MECHANICAL`, idempotent and non-destructive, and **a test asserts that set
146
+
4.**A closed action set.** The setup write surface (`/api/setup/*`) routes through
147
+
`keel.commands.setup.ACTIONS` (as of 2026-10 the gated `/api/gates/*` routes are a second,
148
+
separately gated surface -- see the note in the header), every member declared `MECHANICAL`, idempotent and non-destructive, and **a test asserts that set
142
149
is disjoint from the eleven capability-increasing actions in `keel/capabilities.py`.**
143
150
5.**A CSRF token on every write**, derived from the session token by HMAC rather than stored — "the
144
151
layer that does not depend on the browser being current." Comparisons use
0 commit comments