superboard 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,221 @@
1
+ # Architecture
2
+
3
+ Superboard is a single local Python package with no runtime dependencies: a
4
+ small HTTP server renders and edits one markdown file (`inbox/board.md`), and
5
+ a headless runner drives a Claude Code (or Codex) subprocess per card. There
6
+ is no database and no account — the markdown file plus a handful of local
7
+ JSON registries and caches are the entire durable state. This document
8
+ covers the invariants and trust boundaries that don't change from run to
9
+ run; day-to-day facts (current version, open issues, in-flight decisions)
10
+ belong in the CHANGELOG or the board itself, not here — keeping temporary
11
+ facts out of this file is what keeps it worth reading.
12
+
13
+ ## Components
14
+
15
+ - `server.py` — the local single-writer HTTP server: serves the board UI,
16
+ parses/renders `board.md`, and exposes the JSON API the frontend and the
17
+ runner both call.
18
+ - `gc_runner.py` — the headless agent runner: picks up a `@gc:` board item,
19
+ assembles its prompt (contract + working state + thread), and drives a
20
+ Claude Code / Codex subprocess to a reply.
21
+ - `contract.py` — composes the agent's completion contract from generic core
22
+ rules plus an optional instance-specific rule file (`board.contract.md`,
23
+ not shipped in this extraction).
24
+ - `sidecar.py` — long-turn externalization: writes oversized thread turns to
25
+ `inbox/gc-threads/` and leaves a short pointer in the thread.
26
+ - `sweep.py` — retention: moves finished (`done`) items out of the live
27
+ board into the archive on a schedule.
28
+ - `registries.py` — fail-soft loaders for `actions.json` (cockpit action
29
+ cards) and `rituals.json` (recurring ritual definitions).
30
+ - `thread_search.py` — cross-run context retrieval: lexical search over
31
+ board/archive/thread history with a bounded, evidence-only selection.
32
+ - `terminal.py` — read-only web view of an item's live agent session, plus
33
+ the `resume` command table per runner lane.
34
+ - `bump.py` — mechanical version bump (patch/minor/major from commit size),
35
+ paired with the CHANGELOG-sync convention checked by the test suite.
36
+ - `receipt.py` / `receipt_hook.py` — machine-readable per-run fact log and
37
+ its optional extension boundary.
38
+ - `retro_scan.py` — deterministic candidate finder for error retrospectives
39
+ over past runs.
40
+ - `dev_radar.py` — live status rollup of open dev topics on the board.
41
+ - `board_lint.py` — fast diagnostic for why the board file is locked or
42
+ malformed, including duplicate ids and duplicate topic headings.
43
+ - `guard_hook.py` — its optional Claude Code PostToolUse companion: after a
44
+ write it re-lints and reports a fresh structural duplicate back into the
45
+ agent's own context. Opt-in; see `docs/USING-SUPERBOARD.md`.
46
+ - `board_write.py` — the agent-facing board client, and the whole sanctioned
47
+ write surface: replace an item body against a revision token, append a
48
+ process stage, create a to-do, create a topic, or read the product's own
49
+ docs. It is deliberately pure standard library and imports nothing from this
50
+ package, because `_bootstrap` copies it into every workspace at
51
+ `.superboard/board_write.py` and the agent's shell is a separate process that
52
+ may not be able to import `superboard` at all. Prompts name that workspace
53
+ path, never `python3 -m superboard.board_write`. Unlike the user-owned
54
+ starter files it is refreshed on every start: it is product mechanics, and an
55
+ upgraded server must not leave an agent holding an older client.
56
+ Its workspace path stays `.superboard/board_write.py` even when `GC_DATA`
57
+ redirects journals and caches elsewhere. Every spawned runner receives the
58
+ active server URL as `GC_BOARD_URL`, so the same command works on `--port`
59
+ overrides instead of silently falling back to 47822.
60
+ - `board_ls.py` — quick agent-facing overview of board contents.
61
+ - `paths.py` / `config.py` — the one place that resolves where the board's
62
+ data lives and what is instance configuration versus mechanic.
63
+ - `markers.py` — the frozen data-format strings persisted in `board.md`
64
+ (thread tags, sidecar references, protocol prefixes) — never translated,
65
+ never renamed casually.
66
+ - `git_state.py` — git status/delta used by the runner prompt, independent
67
+ of optional telemetry.
68
+ - `claude_identity.py` — explicit, non-secret identity boundaries for board
69
+ subprocesses (which binary/account lane runs, and why).
70
+ - `migrate_diet.py` — one-time `board.md` migration helper.
71
+
72
+ ## Package and workspace ownership
73
+
74
+ The installed package is read-only mechanics. On first start the user names the
75
+ mutable instance explicitly (`superboard <workspace>`); an existing workspace
76
+ may still be served by running plain `superboard` from inside it. Before creating
77
+ files, the console reports the resolved path, a containing Git repository, a
78
+ non-fatal Claude installation/authentication check, and the inherited host/config
79
+ trust boundary of auto-mode runs. A fresh Git-repository root
80
+ is refused unless `--allow-code-repo` records the user's explicit intent. On
81
+ every console start, the bootstrapper creates missing workspace files with
82
+ exclusive-create semantics and never overwrites an existing one:
83
+
84
+ - `inbox/board.md` and `inbox/gc-threads/` — board content and conversations;
85
+ - `actions.json` and `rituals.json` — repeatable jobs and recurring prompts;
86
+ - `board.config.json` and optional `board.contract.md` — instance identity,
87
+ opt-in behavior and additional agent rules;
88
+ - `.claude/skills/superboard/SKILL.md` — the workspace administration guide;
89
+ - `.superboard/` — runtime journals, usage data, and caches.
90
+
91
+ `paths.py` is the single source of truth for all of these locations. Product
92
+ assets such as `index.html`, the Python modules, and the generic starter sources
93
+ remain in the package. `actions.json` and `rituals.json` are read fresh by their
94
+ API paths; owner configuration, opt-in night-rest behavior and the rendered agent
95
+ contract are imported at process start and therefore require a restart after
96
+ changes. The whole night-rest ladder (footer pill, reminders and mandatory pause)
97
+ defaults off and is enabled only by a literal `night_pause.enabled: true` in the
98
+ workspace config.
99
+
100
+ This boundary is also the upgrade contract: installing a newer wheel may change
101
+ mechanics and generic starter sources, but it must not replace the user's board,
102
+ actions, rituals, configuration, contract, or skills.
103
+
104
+ First-run onboarding is data on that same boundary, not a separate state machine.
105
+ Only a missing `board.md` produces two neutral topics: a seeded Getting started
106
+ checklist and an empty My to-dos area that makes ordinary work visible from frame one.
107
+ Each onboarding card has its own id and one pending user turn. The first prepared
108
+ round opens the same-origin introduction; the UI itself injects no card-specific
109
+ tour button. Runs, threads and cache are taught as a concrete agent-led to-do in
110
+ plain language. The sequence then establishes the workspace boundary/context,
111
+ creates one genuine normal card, explains settings/help, confirms the already-working agent/model profile, configures an explicit Off Duty
112
+ projection and reveals the Cockpit payoff. Email digest, one routine and later
113
+ thread-learning remain separate ordinary cards: optionality is expressed by completing
114
+ or consciously skipping a concrete outcome, not by a generic chooser that creates more
115
+ cards. The Backlog closer can finish only when the other cards are done;
116
+ its normal Done path first closes the thread, then
117
+ atomically archives the topic's item blocks and moves their sidecars before removing the
118
+ Getting started topic. The packaged action and
119
+ ritual registries stay empty. A browser with no saved tab choice lands on To-dos while every seeded card
120
+ is still unstarted, so the checklist is visible. Restarting does not recreate it,
121
+ and after the first render the ordinary persisted tab choice wins.
122
+
123
+ The Cockpit is capability-revealed, not an empty product shell. `/api/actions` is
124
+ loaded before tab selection; zero valid actions means no Cockpit tab, while a
125
+ configured Cockpit renders only zones containing actions. Base setup must first
126
+ idempotently ensure one extension card, inventory only non-secret capability
127
+ metadata, and obtain approval before surgically editing `actions.json`. The same-origin
128
+ `/onboarding-showcase` is packaged fictional data: it can explain customization
129
+ without leaking or seeding the maintainer's personal or work data.
130
+
131
+ Scheduled triage is fail-soft and gets one automatic attempt per slot. Its model
132
+ contract uses a flat JSON object; conservative closing-bracket repair handles a
133
+ truncated envelope without inventing entries. A failed reply never replaces the last
134
+ good snapshot, is retained as `journal/triage-last-raw.txt`, and blocks another
135
+ automatic attempt until the next slot (manual refresh remains available).
136
+
137
+ ## Invariants and trust boundaries
138
+
139
+ - `board.md` has a single writer (the local server) — the runner and the UI
140
+ only ever go through its API, never edit the file directly. Agents are held
141
+ to the same rule by giving them a client that always works rather than only a
142
+ prohibition: an agent told "never edit board.md" whose only sanctioned tool
143
+ fails will do the helpful thing and edit the file, and every later run reads
144
+ that thread and learns the hand edit is normal.
145
+ - Dynamic onboarding cards use the workspace client `--ensure-card`, which checks
146
+ exact active titles before creating. This makes interruption/resume idempotent;
147
+ in particular Cockpit base setup cannot duplicate or lose its extension card.
148
+ - The product's own documentation is SERVED, never copied into a workspace.
149
+ `GET /api/docs/{readme,architecture,changelog}` reads it from the running
150
+ version; a copied doc goes stale on the next upgrade, and onboarding cards
151
+ that read one would then teach from a stale source.
152
+ - The runner preflight (is Claude Code installed and signed in?) has one
153
+ implementation, `server.runner_status`, used by both the terminal preflight
154
+ and `GET /api/runner-status`. The browser must be able to say why ▶ Agent
155
+ cannot run; a terminal line the user never saw is not an explanation.
156
+ - Off Duty is an explicit view projection from
157
+ `board.config.json.off_duty.{hidden_topics,visible_topics}`. Only exact hidden
158
+ names are filtered, so unknown and newly created topics remain visible; no card
159
+ is moved, completed, or rewritten.
160
+ - Binding to `127.0.0.1` is not an authentication boundary. A browser is a local
161
+ program too, so any page the user visits can reach the server. `Content-Type:
162
+ text/plain` is a CORS simple request and travels without a preflight, so a
163
+ foreign page could once create cards and start agent runs — a code-execution
164
+ path, not merely a write. Every state-changing request now passes a guard
165
+ first: `Sec-Fetch-Site: cross-site` is refused, an `Origin` that is not this
166
+ server on this port is refused, and a request carrying a body must declare
167
+ `application/json`. Requests with no `Origin` at all stay allowed — that is
168
+ what every local, non-browser tool looks like — and reads are untouched.
169
+ - The lost guards protect LINES, not IDENTITY. They compare known line families
170
+ before a write; free text is not a family, so a line the parser drops silently
171
+ is invisible to them. That is why the parser keeps mis-indented lines (one
172
+ space, a tab) as body instead of discarding them, and why losing an item's
173
+ `@gc-id` to a hand edit is recovered best-effort rather than prevented: from
174
+ the text alone, "never had an id" and "just lost its id" are the same string.
175
+ Duplicate ids are linted and reported, never blocked. See the known-limitations
176
+ section of `docs/USING-SUPERBOARD.md` — this is a documented boundary of the
177
+ plain-file model, not an oversight.
178
+ - Protocol markers in `markers.py` (`@gc:`/`@gc-re:`/`@gc-done:`, sidecar
179
+ reference labels, the compact/handoff prefixes) are a persisted data
180
+ format, not UI copy — they stay byte-stable across languages and rewrites.
181
+ - The agent contract (`contract.py`) always renders a safe core even with no
182
+ workspace `board.contract.md` present; an instance file, if present, must be
183
+ well-formed or startup fails loudly rather than silently degrading.
184
+ - Bootstrap is create-only for user-owned workspace files. Restart and package
185
+ upgrade never overwrite existing instance content. The bundled board client is
186
+ refreshed in place because it is product mechanics, not user content; redirecting
187
+ runtime data never moves that advertised command path.
188
+ - Setup steps are normal pending threads and never auto-run. Process start itself
189
+ spends no agent tokens; the owner must explicitly click `▶ Agent` per step.
190
+ - Completing from the card overlay and completing from the matrix share the same
191
+ `toggleDone()` path. Both honor the ritual gate, persist the completion timestamp,
192
+ close an open thread, and keep a just-completed card visible until reload for undo.
193
+ - The Getting started closer is the one deliberate exception to that last visibility
194
+ behavior: after the canonical Done/thread-close path it archives the complete topic and
195
+ removes it. It refuses while any of the other seven cards is open, and history reaches
196
+ `board-archive.md` before the active topic disappears.
197
+ - A runner session and a provider prompt cache are different state. The session handle in
198
+ `board.md` can resume a vendor transcript; prompt caching only reuses repeated input.
199
+ Either may be absent without losing board truth, because fresh runs are rebuilt from the
200
+ local thread and item context.
201
+ - A fresh browser starts on the Claude CLI's own default model (no `--model`
202
+ override). Optional and alternative profiles are explicit per-user choices;
203
+ unsupported runners are never presented as if they were already configured.
204
+ - Subprocess identity (`claude_identity.py`) is explicit and never inherited
205
+ silently from parent-process environment variables.
206
+ - The standalone package starts no scheduled agent work. Runs begin with an
207
+ explicit board/UI action; background scheduling is instance configuration,
208
+ not a v0 default.
209
+ - Codex receives no MCP server configuration or credential variables in v0.
210
+ Integrations need an explicit, reviewed boundary before they can ship.
211
+ - The local file viewer blocks `personal/`, `private/`, dot-directories,
212
+ environment files, unknown suffixes, oversized files and paths outside the
213
+ active workspace.
214
+ - A board process binds its port BEFORE it starts the journal watch. The watch
215
+ talks to `127.0.0.1:<port>`; started first, a second instance on an occupied
216
+ port would post its orphaned runs into the board that already owns that port.
217
+ Binding first means the port is ours or the process is already gone.
218
+ - Workspace isolation is a file boundary, not a sandbox. Two workspaces never
219
+ share a board, threads or runtime data, and the runner's identity wrapper can
220
+ strip the operator's Claude configuration from a run — but an agent started in
221
+ a workspace still has the read access of the user who started it.
@@ -0,0 +1,405 @@
1
+ # Changelog
2
+
3
+ **Version numbers.** This file is the internal BUILD history: the number counts every
4
+ change by its size and is not a stability promise. The PUBLIC package version lives in
5
+ `pyproject.toml` and `RELEASES.md` on its own 0.x track and moves only at deliberate
6
+ releases. Until 25.08.2026 both were one number, which is why this file runs from 0.1.1
7
+ to 6.x and why the public version restarted at 0.1.0.
8
+
9
+ ## [6.21.5] — 2026-08-26
10
+ - fix(release): allow GitHub merge noreply identity
11
+ History leak scans accept GitHub's exact synthetic merge identity
12
+ `GitHub <noreply@github.com>` while continuing to reject other github.com mail.
13
+
14
+ ## [6.21.4] — 2026-08-26
15
+ - feat(onboarding): separate setup from real work
16
+ - Fresh workspaces now seed an empty `My to-dos` topic beside the finite
17
+ `Getting started` checklist, so ordinary work is visible without implying
18
+ that every card is an agent job.
19
+ - The first card now asks the agent to open the same-origin introduction and
20
+ keep the card thread available for questions; the hard-coded tour buttons
21
+ and opaque session-cut copy are gone.
22
+ - Dedicated task-shaped cards explain threads/cache and help/settings, while
23
+ the real-work step creates one approved manual card before offering an agent
24
+ hand-off.
25
+ - Normal cards receive their stable ID in the browser before their first save,
26
+ and board saves are serialized, so consecutive additions cannot churn IDs or
27
+ duplicate an ID-less local card during conflict recovery.
28
+ - The release workflow can now build and smoke safely on a pull request or
29
+ manual dispatch; PyPI publishing remains strictly tag-gated.
30
+
31
+ ## [6.21.3] — 2026-08-26
32
+ - fix(onboarding): keep renamed tour card linked
33
+ Card 4's clearer title initially stopped matching the UI's direct-guide rule.
34
+ The static thread/cache CTA now follows the renamed card, with a regression test.
35
+ - fix(release): make the installed-wheel smoke import the installed wheel
36
+ The smoke now launches from the fresh workspace and rejects any module path
37
+ inside the checkout, preventing source-tree shadowing from producing a false pass.
38
+
39
+ ## [6.21.2] — 2026-08-26
40
+ - fix(onboarding): make every starter card concrete
41
+ - Replaced the generic optional-setup chooser with separate email digest,
42
+ routine and later thread-learning cards.
43
+ - Renamed the vague real-work hand-off to the literal outcome: add 3–8 current
44
+ to-dos and run one; agent/model readiness is now its own verified step.
45
+ - Removed Cockpit emphasis while retaining the deliberately highlighted Start
46
+ card, and synchronized the tour, operating guide, architecture and tests.
47
+
48
+ ## [6.21.1] — 2026-08-26
49
+ - fix(release): keep smoke compatible with Python 3.10
50
+ The installed-wheel smoke now reads the public version without Python 3.11's
51
+ `tomllib`, so the repository's declared Python 3.10 minimum is exercised honestly.
52
+
53
+ ## [6.21.0] — 2026-08-26
54
+ - feat(port): board integrity guard, chat-card retirement, stale-tab save guard, CREW token count
55
+ Port audit against the board this repo is projected from — the previous port pass had
56
+ drifted; these are the genuine, tested gaps it found, not a full re-sync.
57
+ - **Board integrity guard** (`board_integrity.py`, new): detects data loss board.md can't
58
+ catch itself — a dead sidecar reference, a `@gc-parent` pointing at nothing, an orphaned
59
+ thread file. Surfaces in the cockpit payload and, on a finding, a small header tile
60
+ (silent otherwise — a permanent green 0 is a tile nobody reads after a week).
61
+ - **Cockpit chat-card retirement** (`sweep.py`): daily Cockpit chat cards now retire
62
+ themselves after 3h of inactivity instead of piling up unarchived.
63
+ - **Stale-tab save guard** (`server.py`/`index.html`): a whole-board save can no longer
64
+ silently drop an item the saving tab never loaded — the server 409s unless the client
65
+ explicitly declares the deletion (`removedIds`), and the client's conflict-retry now
66
+ adopts server-only items instead of losing them.
67
+ - **CREW token count**: the finished-runs header now counts `cache_read`/`cache_creation`
68
+ into `tok`, so a cheap warm-cache run with millions of cached tokens no longer looks
69
+ like a run with no context.
70
+ - **gc_runner**: a successful run with an unreadable usage block now still stamps
71
+ `@gc-last` (as `~0k`) instead of leaving the item looking like it never ran.
72
+ - **bump.py**: stopped auto-writing `pyproject.toml` on every commit — that's the public
73
+ release number, moved only by a deliberate release, never by a build-stand bump.
74
+ - **make-icon.py**: fixed a live break — `index.html` had already renamed its brand-mark
75
+ constant, this script's regex hadn't followed.
76
+ - Left open on purpose (see the origin repo's port ledger for why): the OpenCode runner
77
+ adapter, the color-token-discipline ratchet (needs its own migration here first), and
78
+ the waiting-rail UI (needs a visual pass).
79
+
80
+ ## [6.20.3] — 2026-08-26
81
+ - fix(release): close the final public trust-surface gaps
82
+
83
+ - **Fresh files and protocol links are English.** New workspaces create `rituals.json`
84
+ with an English key and emit `full text` / `full reply` sidecar pointers; existing
85
+ `rituale.json` files and German pointers remain readable. Upgrade bootstrap copies
86
+ legacy ritual content before it seeds the new filename, so nothing silently vanishes.
87
+ - **A started run stays visibly started.** The thread remains open with persistent
88
+ progress and stop/inspect controls instead of disappearing after a successful click;
89
+ it adopts a newly assigned card ID and refreshes the completed reply in place. The
90
+ footer now says `active` so zero cannot be mistaken for a cumulative run count.
91
+ - **The release contract is executable.** Public version `0.1.0`, package URLs,
92
+ SECURITY policy, release notes, release ritual, and a tag-gated Trusted Publishing
93
+ workflow are present. Internal bumps cannot overwrite the public version; the CLI
94
+ reports it explicitly. The workflow publishes the exact artifact it built and smoked,
95
+ then creates the matching GitHub release.
96
+
97
+ ## [6.20.2] — 2026-08-25
98
+ - fix(onboarding): rebuild the stranger-safe first run
99
+
100
+ - **The first two paid documentation rounds are gone.** One numbered Start card
101
+ opens a desktop-width walkthrough directly, while a second static lesson explains
102
+ manual to-dos, standing threads, context cuts and prompt cache without using a model.
103
+ - **Workspace setup now earns its place as step two.** It adapts to a blank home or
104
+ code repository, creates only approved context/topics, and warns that moving to a
105
+ parent workspace does not carry over worked threads or spend history.
106
+ - **Optional work is optional.** Email, routines, later thread-learning and extra
107
+ agent platforms are created only after one applicability round. Cockpit setup moves
108
+ into Now, states its longer expectation and announces the tab when it appears.
109
+ - **The auto-mode boundary is explicit.** README and first-start output explain that
110
+ agent runs inherit host access and MCP/provider configuration, and point interactive
111
+ work to exact terminal handoffs instead of pretending Superboard adds approvals.
112
+ - **Fresh files speak one vocabulary.** Bootstrap now writes `Now / Next / Backlog`
113
+ and English section headings; old German headings remain readable internally.
114
+ - **Triage survives the failure seen in all stranger journeys.** A flatter response
115
+ contract plus conservative bracket repair accepts the malformed reply, keeps the last
116
+ raw failure for diagnosis, and prevents automatic retries inside a failed slot.
117
+
118
+ ## [6.20.1] — 2026-08-25
119
+ - feat(onboarding): personalize off-duty view
120
+
121
+ - **Off Duty is personalized, not a hard-coded worldview.** Its setup card shows
122
+ a fictional before/after, asks what this board is for, and saves approved exact
123
+ hidden/visible topic sets. The toggle remains view-only, and unknown/new topics
124
+ stay visible by default.
125
+
126
+ ## [6.20.0] — 2026-08-25
127
+ - feat(onboarding): build capability-grounded first run
128
+
129
+ - **First run is concrete without becoming fragmented.** Welcome, visual tour,
130
+ real-work import and workspace boundaries lead; email, Cockpit, night rest,
131
+ one optional routine and thread learning stay separate. Claude Code, Codex and
132
+ OpenCode receive one setup card each only when missing, and installation plus
133
+ the platform's truthful login/provider connection remain one outcome.
134
+ - **A fresh workspace has no empty Cockpit.** The tab appears only after at least
135
+ one valid action exists, carries the subtitle “your one-click actions,” and
136
+ renders only populated action zones. Existing `actions.json` entries are never
137
+ rewritten by onboarding.
138
+ - **Cockpit setup is resumable and capability-grounded.** The workspace client’s
139
+ new `--ensure-card` verb creates the extension follow-up exactly once. The setup
140
+ mission verifies skills, MCP names and CLIs without reading secrets or starting
141
+ logins, then requests approval before a surgical `actions.json` edit.
142
+ - **The visual tour is real, local and safe to publish.** A packaged same-origin
143
+ page explains board/thread/decision-sheet interaction and shows fictional
144
+ maintenance, knowledge and personal-sports Cockpits. It contains no maintainer,
145
+ user or work data, and onboarding derives its URL from the running board origin
146
+ instead of assuming the default port.
147
+ ## [6.19.0] — 2026-08-24
148
+
149
+ The first five minutes of a fresh install were not true. Three verified breaks,
150
+ all on the path a newcomer actually walks.
151
+
152
+ - **Night-rest overlays are inactive by default.** The footer pill, reminder
153
+ ladder and mandatory 23:00–06:00 pause require a literal
154
+ `night_pause.enabled: true` in the workspace's `board.config.json`; the setting
155
+ applies after restart.
156
+ - **Late-night rendering no longer aborts the UI during script startup.** The
157
+ shared DOM helper and view filters are initialized before render-capable clock
158
+ callbacks, and clock ticks are isolated so a failure cannot leave navigation
159
+ half-wired.
160
+ - **The workspace board client follows the server it belongs to.** Agent runs now
161
+ receive the active URL, so `--docs`, card and topic commands work on supported
162
+ non-default ports; redirecting runtime data with `GC_DATA` no longer moves the
163
+ advertised `.superboard/board_write.py` path.
164
+
165
+ - **The very first card read files that were not there.** `Start here` told the
166
+ agent to answer from "this workspace's own README.md" and to point at
167
+ `ARCHITEKTUR.md` for depth. A fresh workspace receives neither. Copying them in
168
+ would only move the problem — a copied doc goes stale on the next upgrade — so
169
+ the docs are now SERVED by the running version at
170
+ `GET /api/docs/{readme,architecture,changelog}`, and the card reads them with
171
+ `python3 .superboard/board_write.py --docs readme`. If that fails, the card now
172
+ tells the agent to say so rather than improvise.
173
+
174
+ - **Agents were told "never edit board.md" while holding no tool that reliably
175
+ worked.** Setup cards ask the agent to create topics and to-dos; the bundled
176
+ skill named no write mechanism at all, and the run prompt named
177
+ `python3 -m superboard.board_write`, which assumes the agent's shell can import
178
+ a package installed in the server's (possibly ephemeral `uvx`) environment. An
179
+ agent in that position does the helpful thing and edits the file by hand — which
180
+ breaks the single-writer invariant, and every later run reads the thread and
181
+ learns that hand edits are normal. `board_write.py` is now pure standard library,
182
+ imports nothing from the package, is copied into every workspace at
183
+ `.superboard/board_write.py` (refreshed on each start, so an upgrade never leaves
184
+ an agent on an old client), and covers the whole write surface: `--show`,
185
+ `--body-file` + `--body-etag`, `--stage`, `--new-card`, `--new-topic`, `--docs`.
186
+ `--new-card` never starts a run: creating work on the user's behalf must not also
187
+ spend the user's tokens. The bundled skill and the run contract both name that
188
+ path now.
189
+
190
+ - **"Claude Code is not installed" was printed to the terminal only.** A newcomer
191
+ who never installed it met a ▶ Agent button that silently did nothing. The check
192
+ has one implementation (`server.runner_status`) behind
193
+ `GET /api/runner-status`; the board shows the reason on the first screen and
194
+ marks the buttons `▶ Agent (not installed)` / `(not signed in)` with install
195
+ instructions on hover.
196
+
197
+ Also: the first real hand-off moved from step four to step two. `Bring in your
198
+ real work` now sits directly behind `Start here` — shaping paths, topics and run
199
+ profiles before any real work exists asks people to configure a tool they have not
200
+ used yet. The checklist stays optional and visibly finite at eight cards.
201
+
202
+ ## [6.18.16] — 2026-08-24
203
+
204
+ Release candidate: the onboarding work, the launch assets, the macOS smoke test
205
+ and the pending board changes are one codebase again, and three things that
206
+ should not ship were fixed first.
207
+
208
+ - **A page in your browser could start agent runs on your machine.** Binding to
209
+ `127.0.0.1` kept the server off the network but not away from the browser, and
210
+ a browser is a local program: any site you visited could POST to the board.
211
+ `Content-Type: text/plain` is a CORS simple request, so no preflight fired and
212
+ the `Origin` was never examined — a foreign page could create a card and start
213
+ a run, which is code execution, not just a write. Every state-changing request
214
+ now passes a guard first: `Sec-Fetch-Site: cross-site` is refused, an `Origin`
215
+ that is not this server on this port is refused, and a request with a body must
216
+ declare `application/json`. Requests without an `Origin` still work — that is
217
+ what non-browser tooling looks like — and reads are unaffected.
218
+ - **Mis-indented lines are no longer thrown away.** A body line needs two leading
219
+ spaces; one space or a tab fell through every branch and vanished on the next
220
+ save. The lost guards compare known line families, and free text is not one, so
221
+ nothing complained while `board_lint.py` could see the loss. The parser keeps
222
+ such lines now, in all three places that parse an item.
223
+ - **`board_lint.py` reports duplicate ids and duplicate topic headings.** A bad
224
+ edit that splices a section twice is now visible instead of quietly doubling a
225
+ board.
226
+ - **The installed-wheel smoke test can no longer pass on a stale wheel.**
227
+ `dist/` is ignored and survives between sessions, and Superboard's version
228
+ travels with the code it is projected from — so several commits legitimately
229
+ carry the same number and the version string could never prove which commit a
230
+ wheel came from. The build clears `dist/`, refuses more than one wheel, and
231
+ stamps the commit into `dist/BUILD_SHA`; the assertions refuse a stamp that
232
+ disagrees with the checkout. `scripts/smoke-local.sh` is the local path the
233
+ docs promised and nothing implemented.
234
+ - **A forced five-minute prompt-cache bucket is no longer set.** Measured over 357
235
+ resumed runs, only 7 % started warm — the board's own cadence is far longer than
236
+ five minutes, so the cache was written and almost never read. The variable is now
237
+ actively removed from the run environment (a run started from inside a run would
238
+ otherwise inherit it), and the CLI picks its own bucket. The card's recency pill
239
+ is unchanged.
240
+ - **`board_write.py` ships, so the agent contract is true.** The contract tells
241
+ agents to write item bodies through the API rather than editing `board.md`;
242
+ `python3 -m superboard.board_write` is that path, with a revision token and a
243
+ 409 on a stale one. `guard_hook.py` is the optional Claude Code companion that
244
+ re-lints after every write.
245
+ - **The macOS smoke test now actually exercises the product.** It was written
246
+ against an older base and never survived the onboarding change: it started the
247
+ server without a workspace path, which a first start refuses by design, so the
248
+ server never came up and every assertion below it was unreachable. It also still
249
+ looked for a welcome card that the onboarding journey replaced. It now passes the
250
+ workspace explicitly, as a user types it, and asserts the Getting started row and
251
+ the Start here card — the two things screen one actually promises.
252
+ - **Documented rather than pretended away:** `docs/USING-SUPERBOARD.md` now has a
253
+ known-limitations section for the two places where hand-editing `board.md` can
254
+ cost an item its identity, and says what to do instead.
255
+
256
+ ## [6.13.2] — 2026-08-23
257
+ - feat(onboarding): recommend workspace capabilities
258
+
259
+ Shape this workspace now inventories existing skills, tools, and MCPs and
260
+ recommends a small baseline tied to the user's work. Browser automation is the
261
+ default recommendation for web/product work so agents can operate and verify
262
+ rendered interfaces, not merely inspect source.
263
+
264
+ ## [6.13.1] — 2026-08-23
265
+ - fix(onboarding): make email setup a concrete digest
266
+
267
+ The Soon card now builds and tests an email digest instead of discussing an
268
+ abstract mail workflow. Its prepared turn focuses on the desired signal,
269
+ cadence, real sample, and repeatable action; redundant credential and approval
270
+ warnings were removed from the starter copy.
271
+
272
+ ## [6.13.0] — 2026-08-23
273
+ - feat(onboarding): add superskills setup journey
274
+
275
+ A fresh workspace now gets eight small, checkable setup missions: workspace
276
+ foundation and email are concrete, optional skills come from a separate
277
+ workspace-owned catalogue, and a final Parked card archives the completed
278
+ Getting started topic without discarding its history.
279
+
280
+ ## [6.12.7] — 2026-08-23
281
+ - fix(onboarding): highlight Start here instead of Shape this workspace
282
+
283
+ The bold/bordered highlight — the board's own "one card stands out" convention
284
+ — sat on the second setup card by leftover default. Owner call: if one card
285
+ gets the visual lead, it should be the 60-second first step, not the second
286
+ one. The other six cards are unchanged.
287
+
288
+ ## [6.12.6] — 2026-08-21
289
+ - feat(onboarding): make instance files workspace-owned
290
+
291
+ First-run bootstrap now creates `actions.json`, `rituale.json`,
292
+ `board.config.json`, and a Superboard administration skill in the user's
293
+ workspace with create-only semantics. Server registries, configuration, and an
294
+ optional instance contract resolve there instead of inside the installed
295
+ package, so an agent can genuinely personalize a wheel-installed board and an
296
+ upgrade cannot clobber that work.
297
+
298
+ - feat(onboarding): replace sample content with one explicit setup mission
299
+
300
+ A fresh workspace now contains one neutral topic, one pending `Set up my board`
301
+ thread, and no generic actions or rituals. A browser with no saved tab preference
302
+ lands on To-dos for that first render, while startup remains token-free and later
303
+ visits continue to honor the user's own tab choice.
304
+
305
+ - feat(onboarding): make setup a checklist of separate to-dos
306
+
307
+ The single `Set up my board` mission becomes six ordinary to-dos — topics, paths,
308
+ cockpit actions, first real hand-off in Now; one optional connection and a
309
+ look-back-after-a-few-days review in Soon. Each has its own id, its own thread and
310
+ its own pending turn, so a first-time user starts one step, sees a result, ticks it
311
+ off, and can skip the rest. Owner direction: onboarding should be work you check
312
+ off, not a wizard you sit through.
313
+
314
+ - feat(onboarding): make the first-run boundary explicit
315
+
316
+ A new installation now names its high-level workspace in the start command and
317
+ gets a non-fatal preflight for repository placement and Claude readiness before
318
+ any files are created. The first run profile is the authenticated Claude CLI's
319
+ own default instead of a hard-coded Opus choice. The six setup cards now follow
320
+ the real journey: shape the workspace, choose the agent mode, bring in real work,
321
+ build one useful button, optionally connect a tool, then learn from day-three
322
+ evidence. A blank workspace may grow a tiny neutral context scaffold, but only
323
+ after showing the user the proposal.
324
+
325
+ - feat(board): complete a to-do from its card overlay
326
+
327
+ A right-aligned `✓ Done` action now completes the open to-do without returning to
328
+ the matrix first. It reuses the existing checkbox path, closes the overlay, and
329
+ keeps the just-completed card visible until reload so the checkbox remains an
330
+ immediate undo.
331
+
332
+ - feat(onboarding): a 60-second first to-do before the real setup starts
333
+
334
+ A new "Start here" card now leads the checklist (five in Now, still two in Soon).
335
+ Its only pending turn is one queued question — a very short overview of how this
336
+ board works — answered from the workspace's own README, so the first thing a new
337
+ user does is open a card, press `▶ Agent`, read a short reply, and tick it off in
338
+ under a minute, before any of the heavier setup cards ask for real decisions.
339
+
340
+ - fix(ui): the item overlay's primary action is now visually correct
341
+
342
+ `▶ Agent` — the button that actually starts a run — carries the filled accent
343
+ color that used to sit on `Send`, which only appends a thread turn and never runs
344
+ anything. `Send` is renamed `Save` and restyled as the secondary action, with a
345
+ tooltip spelling out that it does not dispatch to the agent; `▶ Agent`'s tooltip
346
+ now says it saves the message too. Matching hint text, keyboard-shortcut labels,
347
+ and decision-sheet copy elsewhere in the overlay were adjusted for the same
348
+ distinction.
349
+
350
+ ## [6.12.5] — 2026-08-21
351
+ - feat: catch up with the board this package is projected from
352
+
353
+ First full port pass since the extraction. Twenty files had drifted; the version
354
+ number jumps from 6.8.1 to 6.12.5 because it is the *board's* number, not a
355
+ separate public track.
356
+
357
+ What arrived, grouped:
358
+ - **Board file boundary is bilingual.** `parse` accepts German and English column
359
+ and section headings forever, `serialize` always writes English — an existing
360
+ board migrates itself on the next save, no migration step.
361
+ - **Multi-agent run profile** `opus-multi`: the `Workflow` tool stays disabled by
362
+ default (its schema costs ~8k tokens per turn) and is opt-in for a single item.
363
+ - **Codex cache window** is now measured instead of guessed: a live 60-minute
364
+ countdown plus a counter for how many foreign runs are eating the window.
365
+ - **Acknowledge instead of run** (`✓`): an action card whose round is finished but
366
+ whose thread is still open can be checked off, with a per-zone counter.
367
+ - **Restart drain guard:** while a restart waits for running agents to finish, no
368
+ new run starts. (The restart *trigger* stays out — an installed package restarts
369
+ through its own process, not through a script in a repo.)
370
+ - **`radar_watch`** is new: it lets the dev radar report only what actually moved
371
+ since the last sweep, and has a small agent judge each finding in the item thread.
372
+ - Fixes: a guaranteed `NameError` on the quick-capture path, repo links opening
373
+ inconsistently, an unvalidated session id reaching the clipboard, the retro scan
374
+ trusting a neighbouring sidecar as evidence, and a lint false positive on
375
+ round-tripped headings.
376
+ - `bump.py` no longer counts instance content (`actions.json`, `rituale.json`,
377
+ `board.config.json`), and `major` is never automatic any more.
378
+
379
+ Deliberately not ported: everything that serves a private integration (product
380
+ metrics, SSO, personal tooling) and the categories in `index.html`, which stay an
381
+ empty `INSTANZ-CONFIG` block — grouping belongs to whoever runs the board.
382
+
383
+ ## [6.8.1] — 2026-08-18
384
+ - chore(version): adopt the upstream board version instead of a separate 0.x track
385
+
386
+ `pyproject.toml` and `server.py` now both read 6.8.1, written by the origin
387
+ instance's port tooling. Two numbers for the same code were exactly the drift
388
+ the port ledger exists to prevent — an installed Superboard should say which
389
+ board build it contains.
390
+
391
+ ## [0.1.1] — 2026-08-18
392
+ - fix(server): fail readably on a taken port and bind before starting the journal watch
393
+
394
+ Starting a second board on an occupied port raised a bare `OSError: [Errno 48]`
395
+ traceback; it now exits with one line naming the port and the way out. The bind
396
+ also moved ahead of the journal watch: that watch talks to `127.0.0.1:<port>`,
397
+ so on an occupied port the losing process used to post its orphaned runs into
398
+ the board that already owned the port.
399
+
400
+ ## [0.1.0] — 2026-08-18
401
+
402
+ Initial standalone extraction: Markdown-backed board, persistent agent threads,
403
+ local runner, cockpit frame, fictional sandbox workspace and installable package.
404
+ Private instance integrations and content are deliberately excluded.
405
+ Scheduled agent work and MCP credential forwarding are disabled by default.
superboard/__init__.py ADDED
@@ -0,0 +1,6 @@
1
+ """Superboard — a personal task board where every to-do is a standing agent thread.
2
+
3
+ The modules in this package import each other as top-level modules (``import
4
+ server``), mirroring the flat layout the tool grew up in. The console entry
5
+ point (`__main__.run`) puts this directory on ``sys.path`` before importing.
6
+ """