generated from eblume/project-template
docs: reframe tech-spec as historical; heph self-hosts its roadmap
v1 reached Todoist feature-parity, so remaining/future work is now tracked in heph itself — tasks in the Hephaestus project (heph view ondeck) — not in a doc. Renamed docs/reference/tech-spec.md -> v1-prototype-tech-spec.md and rewrote all 27 [[tech-spec]] wiki-links + README/changelog path refs (docs checks green). Retitled + bannered the spec as a historical v1 build record and froze its §14 tracker. AGENTS.md gains a "Planning future work" section (capture via `heph task --project Hephaestus`, triage in heph-tui On Deck); README status reflects parity + the three daily-driver surfaces. The design doc remains the living rationale. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
dd5ef7dc63
commit
6514296b87
10 changed files with 50 additions and 34 deletions
15
AGENTS.md
15
AGENTS.md
|
|
@ -41,7 +41,7 @@ See [[agent-change-process]] for the full methodology.
|
|||
|
||||
## Project Structure
|
||||
|
||||
A Cargo workspace (`Cargo.toml` at the root) plus the Neovim plugin and repo tooling. The build follows the tech-spec §11.1 slice order; the **Rust backend is feature-complete** (all three runtime modes + sync + OIDC auth) and **`heph.nvim` is built and installed** (knowledge base + tasks + a plug-and-play managed daemon). Remaining v1 work is task-scheduling UX + polish (the live tracker is **[[tech-spec]] §14**).
|
||||
A Cargo workspace (`Cargo.toml` at the root) plus the Neovim plugin and repo tooling. **v1 reached Todoist feature-parity on 2026-06-03** — the **Rust backend is feature-complete** (all three runtime modes + sync + OIDC auth) and all three surfaces (`heph` CLI, **`heph-tui`**, **`heph.nvim`**) are installed daily-drivers. **Remaining/future work is now tracked in heph itself** (see *Planning* below), not in a doc; the **[[v1-prototype-tech-spec]]** is the historical build record.
|
||||
|
||||
```
|
||||
./Cargo.toml # workspace manifest (shared deps + members)
|
||||
|
|
@ -50,7 +50,7 @@ A Cargo workspace (`Cargo.toml` at the root) plus the Neovim plugin and repo too
|
|||
./crates/hephd/ # daemon: local/server/client modes — unix-socket RPC + HTTP sync/rpc + OIDC auth
|
||||
./crates/heph/ # CLI (thin client of hephd): next/task/doc/get/export/search/journal/auth
|
||||
./heph.nvim/ # Neovim plugin: primary surface; replaces obsidian.nvim (Lua + headless e2e)
|
||||
./docs/ # Diataxis docs (incl. [[design]] + [[tech-spec]]), Quartz config, release content
|
||||
./docs/ # Diataxis docs (incl. [[design]] + [[v1-prototype-tech-spec]]), Quartz config, release content
|
||||
./docs/changelog.d/ # towncrier fragments for noteworthy changes
|
||||
./.dagger/ # Dagger module (src/hephaestus_ci/) backing docs builds and releases
|
||||
./.forgejo/workflows/ # build + release workflows
|
||||
|
|
@ -58,6 +58,15 @@ A Cargo workspace (`Cargo.toml` at the root) plus the Neovim plugin and repo too
|
|||
./mise-tasks/ # repo automation via `mise run`
|
||||
```
|
||||
|
||||
**Development is TDD** (tech-spec §2, §9): failing test first, implement to green, commit on green. `heph-core` is clock-injected — no ambient wall-clock reads; time is always passed in. Canonical spec is [[tech-spec]]; rationale is [[design]].
|
||||
**Development is TDD** (v1-prototype-tech-spec §2, §9): failing test first, implement to green, commit on green. `heph-core` is clock-injected — no ambient wall-clock reads; time is always passed in. The **historical v1 build spec** is [[v1-prototype-tech-spec]]; the **living rationale/decisions** are [[design]].
|
||||
|
||||
Other doc paths are listed via `mise run ai-docs`. Wiki-links (`[[like-this]]`) refer to `docs/` cards.
|
||||
|
||||
## Planning future work (heph self-hosts its roadmap)
|
||||
|
||||
Since v1 parity, **heph tracks its own remaining/future work as tasks in the `Hephaestus` project inside the live store** (the "bootstrap lift" — heph plans heph). This replaces the old [[v1-prototype-tech-spec]] §14 tracker, which is now a historical build record.
|
||||
|
||||
- **See the roadmap:** `heph view ondeck` (CLI) or `heph-tui` → the **On Deck** sidebar view (the backlog lives as blue/on-deck tasks); open the **Hephaestus** project in the sidebar to see all of it.
|
||||
- **Capture new work:** `heph task "<title>" --project Hephaestus -a blue` (blue = on-deck backlog, kept out of `next`/ToM until pulled up). Add detail in the task's canonical-context doc via `heph.nvim`.
|
||||
- **Don't reopen the §14 tracker** for new work — add a task instead. Update the spec only to correct historical record.
|
||||
- Note the [[design]] doc remains the **living** design/decision log; the tech-spec is frozen as the v1 build description.
|
||||
|
|
|
|||
|
|
@ -6,11 +6,13 @@ It is **offline-first**: fully useful on a laptop with no network, and (when the
|
|||
|
||||
> **Why "what is next?" is the flagship.** heph is organized around concise, honest answers to recurring questions — above all *"what do I do right now?"* — built from ~10 years of the owner's lived prioritization discipline: projects-as-contexts; attention colors (white/orange/red/blue, where **red = a consequence exists if late**, not importance); **do-dates, not due-dates** (earliest-actionable, never a deadline alarm); and working-set tensions surfaced honestly (no "fake happy", no overwhelm).
|
||||
|
||||
See **[docs/explanation/design.md](docs/explanation/design.md)** for the vision and rationale, and **[docs/reference/tech-spec.md](docs/reference/tech-spec.md)** for the implementation-facing specification.
|
||||
See **[docs/explanation/design.md](docs/explanation/design.md)** for the vision and rationale, and **[docs/reference/v1-prototype-tech-spec.md](docs/reference/v1-prototype-tech-spec.md)** for the implementation-facing specification.
|
||||
|
||||
## Status
|
||||
|
||||
**Phase 1 (v1 prototype) — nearly feature-complete** on branch `feature/v1-prototype`. **All three runtime modes work, replicas sync through a hub over HTTP, and op exchange is authenticated end-to-end with OIDC** (Authentik): the hub verifies bearer tokens (JWKS/RS256) and enforces single-tenant ownership, and `heph auth login` runs the device-code flow, caching tokens in the OS keyring. The offline-first everyday config (`local` + `hub_url`) converges with a `yrs` text-CRDT merging bodies. The **`heph.nvim` plugin is built and installed on the dev machine** — knowledge base (journals, wiki-links with follow-or-create, a home/index page, a dailies picker), tasks (capture, the "what is next?" view, interactive list, promotion), and a plug-and-play self-healing daemon. CI is green, fully through Dagger. Built test-first (117 Rust + 17 nvim e2e). The canonical tracker is **tech-spec §14**.
|
||||
**Phase 1 (v1 prototype) — at Todoist feature-parity (2026-06-03)** on branch `feature/v1-prototype`. The Rust backend is feature-complete and **all three surfaces are installed daily-drivers**: the **`heph` CLI** (capture/scripting + the complete daemon API), **`heph-tui`** (the agenda/triage surface — attention-colored views, fzf move-to-project, undo/redo, an Inbox), and **`heph.nvim`** (the context/knowledge base — journals, wiki-links by id with conceal, a `[[` picker, YAML-frontmatter task editing). A global **⌘' quick-capture** popover (`heph-quickadd`) rounds out capture. Under the hood: **all three runtime modes work, replicas sync through a hub over HTTP, authenticated end-to-end with OIDC** (Authentik; JWKS/RS256, single-tenant), the offline-first config (`local` + `hub_url`) converges with a `yrs` text-CRDT, and the daemon runs as an OS service. CI is green, fully through Dagger; built test-first.
|
||||
|
||||
**heph now self-hosts its roadmap.** With parity reached, remaining and future work is tracked **in heph itself** — as tasks in the **`Hephaestus` project** (`heph view ondeck`, or the *On Deck* view in `heph-tui`) — rather than in a document. The [v1-prototype tech-spec](docs/reference/v1-prototype-tech-spec.md) is now the historical build record (its §14 tracker); the [design doc](docs/explanation/design.md) remains the living rationale.
|
||||
|
||||
| Area | State |
|
||||
|---|---|
|
||||
|
|
@ -90,7 +92,7 @@ mise run ai-docs # docs AI agents read firs
|
|||
./crates/hephd/ # daemon: local/server/client modes — unix-socket RPC + HTTP sync/rpc
|
||||
./crates/heph/ # CLI: thin client of the daemon
|
||||
./heph.nvim/ # Neovim plugin (primary surface) — Lua, headless e2e harness
|
||||
./docs/ # Diataxis docs (design, tech-spec, how-to), Quartz config
|
||||
./docs/ # Diataxis docs (design, v1-prototype-tech-spec, how-to), Quartz config
|
||||
./.forgejo/ # CI build + release workflows and hooks
|
||||
./.dagger/ # Dagger module backing docs builds/releases
|
||||
./mise-tasks/ # repo automation via `mise run`
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Add the project design document (`docs/explanation/design.md`, rationale + decision history) and the distilled technical specification (`docs/reference/tech-spec.md`, the build artifact) defining hephaestus as a unified, self-hosted, **client/server + offline-first** task + knowledge-base system: typed node graph, the lived priority discipline ("what is next?"), recurrence with fresh-per-occurrence checklists, op-log/CRDT sync with conflict resolution, OIDC/Authentik auth, the heph.nvim surface, and a test-driven development strategy.
|
||||
Add the project design document (`docs/explanation/design.md`, rationale + decision history) and the distilled technical specification (`docs/reference/v1-prototype-tech-spec.md`, the build artifact) defining hephaestus as a unified, self-hosted, **client/server + offline-first** task + knowledge-base system: typed node graph, the lived priority discipline ("what is next?"), recurrence with fresh-per-occurrence checklists, op-log/CRDT sync with conflict resolution, OIDC/Authentik auth, the heph.nvim surface, and a test-driven development strategy.
|
||||
|
|
|
|||
1
docs/changelog.d/v1-selfhost-roadmap.doc.md
Normal file
1
docs/changelog.d/v1-selfhost-roadmap.doc.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
- **heph self-hosts its roadmap (the "bootstrap lift").** With v1 at Todoist feature-parity, remaining/future work is now tracked **in heph itself** — as tasks in the `Hephaestus` project (`heph view ondeck`) — rather than in a document. The tech-spec is reframed accordingly: `tech-spec.md` → **`v1-prototype-tech-spec.md`** (all wiki-links + paths updated), retitled and bannered as a **historical** record of the v1 build, with its §14 tracker frozen. `AGENTS.md` gains a *Planning future work* section (capture via `heph task "…" --project Hephaestus`, triage in `heph-tui` On Deck); `README.md`'s status reflects parity + the three daily-driver surfaces. The living **[[design]]** doc remains the rationale of record.
|
||||
|
|
@ -8,7 +8,7 @@ tags:
|
|||
|
||||
# Hephaestus — Design Document
|
||||
|
||||
> **Status:** Living design record. This is the **rationale + decision-history** document. For the clean, implementation-facing spec the next session builds from, see **[[tech-spec]]**. Sections marked **❓ OPEN** are unresolved; **🔒 DECIDED** are settled.
|
||||
> **Status:** Living design record. This is the **rationale + decision-history** document. For the clean, implementation-facing spec the next session builds from, see **[[v1-prototype-tech-spec]]**. Sections marked **❓ OPEN** are unresolved; **🔒 DECIDED** are settled.
|
||||
|
||||
## 1. Purpose & Vision
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ Today these are loosely coupled by fragile cross-links (`todoist://<task-id>` in
|
|||
### 3.1 Identity
|
||||
|
||||
- 🔒 **DECIDED — ULID for content nodes** (`doc`/`task`/`project`), sortable and sync-safe, with a human-facing `slug`/`alias` layer so `[[wiki-links]]` can be written by name. The ZK's timestamp-IDs (`1722897441-MWFE`) are ULID-like already; a future migration can map them.
|
||||
- 🔒 **DECIDED — deterministic ids for key-unique kinds.** Random ULIDs *diverge* when two offline replicas independently create the *same logical singleton* (today's `journal`, a `tag` by name) — duplicates that never merge. So `journal` ids derive deterministically from `(owner, ISO-date)` and `tag` ids from `(owner, normalized-name)`; independent creation then yields the *same* id and the CRDT/op-log coalesce them (two partial daily notes even merge). `project` stays a random ULID (deliberately created, renameable, tiny stable set). Tag rename = retag (no in-place key change); the normalization function is a fixed, versioned constant. See [[tech-spec]] §4.5.
|
||||
- 🔒 **DECIDED — deterministic ids for key-unique kinds.** Random ULIDs *diverge* when two offline replicas independently create the *same logical singleton* (today's `journal`, a `tag` by name) — duplicates that never merge. So `journal` ids derive deterministically from `(owner, ISO-date)` and `tag` ids from `(owner, normalized-name)`; independent creation then yields the *same* id and the CRDT/op-log coalesce them (two partial daily notes even merge). `project` stays a random ULID (deliberately created, renameable, tiny stable set). Tag rename = retag (no in-place key change); the normalization function is a fixed, versioned constant. See [[v1-prototype-tech-spec]] §4.5.
|
||||
|
||||
### 3.2 Scalar task attributes vs. links
|
||||
|
||||
|
|
@ -81,7 +81,7 @@ A **recurring task** carries an **RFC-5545 RRULE** and acts as a recurring **def
|
|||
- A recurring task is a **single node**. On completion: (1) append the finished occurrence to the per-task **log** (§6.4), (2) reset the body's checkboxes to unchecked (a body-CRDT edit), (3) advance the do-date to **the next RRULE instance strictly after `now`**, *skipping* missed occurrences. So a fresh, all-`outstanding` checklist each occurrence; **completion never carries forward**; a missed daily routine is **one** gently-overdue item, not a pile.
|
||||
- History is narrative (the log), matching "narrative > list" (§6.1). RRULE expansion stays **lazy** — only "next instance after now" is ever computed, never the series (§6.6).
|
||||
|
||||
**Why not occurrence-instances?** The rejected alternative (a fresh node per occurrence) was attractive for queryable per-occurrence history, but under Fork A each occurrence would need its own body — hence its own node — turning every daily recurrence into a new node-pair: exactly the explosion §6.6 forbids. No v1 query needs occurrence rows (the ranking reads the single node's do-date), and adherence/streak stats can be reconstructed from the log later. See [[tech-spec]] §4.4.
|
||||
**Why not occurrence-instances?** The rejected alternative (a fresh node per occurrence) was attractive for queryable per-occurrence history, but under Fork A each occurrence would need its own body — hence its own node — turning every daily recurrence into a new node-pair: exactly the explosion §6.6 forbids. No v1 query needs occurrence rows (the ranking reads the single node's do-date), and adherence/streak stats can be reconstructed from the log later. See [[v1-prototype-tech-spec]] §4.4.
|
||||
|
||||
## 4. Architecture
|
||||
|
||||
|
|
@ -92,9 +92,9 @@ Layers, top to bottom:
|
|||
- **Surfaces (thin clients) — a three-surface model (revised 2026-06 after the §6.2.1 Todoist study; supersedes the earlier "nvim is *the* primary surface" framing).** Tasks and knowledge pull in different interaction directions, so each surface plays to its strength rather than one trying to do everything:
|
||||
- **`heph.nvim` — the primary *context / knowledge-base* surface.** The full "org-mode"-style experience (markdown buffers backed by `doc` nodes; wiki-links, journaling, the canonical-context doc, per-task log, checklists). The explicit **successor to obsidian.nvim** (telescope picker, follow `[[wiki-links]]` on `<Enter>`, dailies, multi-state checkboxes); must reach that parity (§6.5). It surfaces tasks for **navigation/reading and context**, not as the primary place to *edit* structured task fields.
|
||||
- **`heph` CLI — capture/scripting + the complete daemon API.** Every structured task field is a flag (`-a red --do tomorrow --late fri --recur weekly --project Maintenance`), which is exactly what command-line flags are good at and dissolves the "how do I edit N structured fields" problem. The CLI implements the *entire* API (admin, sync, conflicts, export) so it is also the scripting/automation surface.
|
||||
- **`heph-tui` — the primary *task agenda / triage* surface (planned, [[tech-spec]] §8.1).** The §6.2.1 study shows the dominant task activity is *interactive triage of a large set* (daily orange reconfirm, blue keep/drop review, browse-by-project) — work that is awkward as either CLI flags or nvim buffers. A terminal UI owns that, and **launches into nvim** for a task's context (and nvim launches back). Not yet built.
|
||||
- **`heph-tui` — the primary *task agenda / triage* surface (planned, [[v1-prototype-tech-spec]] §8.1).** The §6.2.1 study shows the dominant task activity is *interactive triage of a large set* (daily orange reconfirm, blue keep/drop review, browse-by-project) — work that is awkward as either CLI flags or nvim buffers. A terminal UI owns that, and **launches into nvim** for a task's context (and nvim launches back). Not yet built.
|
||||
- The **web UI** is the occasional hub-served surface. A later iOS/Watch client talks to the hub directly.
|
||||
- 🔒 **Single binary, three modes.** One Rust binary runs as `local` / `server` / `client` ([[tech-spec]] §3.1); the `heph` CLI shares the same command surface. Mode is two orthogonal axes (backend + inbound listener) plus an optional `hub_url` that makes any `local` instance a syncing **spoke** — the everyday device is `local` + `hub_url`, the hub is `server`, `client` is the online-only convenience.
|
||||
- 🔒 **Single binary, three modes.** One Rust binary runs as `local` / `server` / `client` ([[v1-prototype-tech-spec]] §3.1); the `heph` CLI shares the same command surface. Mode is two orthogonal axes (backend + inbound listener) plus an optional `hub_url` that makes any `local` instance a syncing **spoke** — the everyday device is `local` + `hub_url`, the hub is `server`, `client` is the online-only convenience.
|
||||
- **Per-device daemon (`hephd`):** owns the local SQLite handle, the CRDT/op-log state, and background sync. All local surfaces connect to it over a local socket. This is what makes multi-surface access concurrent and safe on one SQLite file, and gives one place to run background sync.
|
||||
- 🔒 **Lifecycle = an explicit OS service; surfaces are connect-only (decided 2026-06).** Since the daemon is shared across surfaces (CLI, TUI, nvim), no single surface owns it — so none auto-spawns it (an earlier nvim "managed daemon" that spawned + killed-on-exit was removed: a surface-owned daemon can't be shared, and "when do we stop it?" has no good answer). Instead it runs as a launchd agent (macOS) / systemd user service (Linux), managed by **`heph daemon start/stop/restart/status`** ([[run-the-daemon]]). Surfaces only connect, and tell you to run `heph daemon start` if nothing is serving the socket.
|
||||
- **Core crate (Rust lib):** data model, query engine, markdown parsing + wiki-link extraction, and sync logic. Linked by both `hephd` and the hub server.
|
||||
|
|
@ -252,7 +252,7 @@ The owner's old rule — "avoid ncurses and interactive UIs; write atomic code a
|
|||
|
||||
**heph's default "what is next?" (Tactical blank-slate)** therefore ≈ Top of Mind (Red first — by *consequence*, then Orange) **+** White items whose do-date has arrived, scoped to the current project/context, **with Blue hidden**. Concise, honest, light.
|
||||
|
||||
> 🔒 **DECIDED ranking mechanics ([[tech-spec]] §7):** `do_date` is a *boolean candidacy filter only* (null ⇒ "now"), **never** an urgency input; **`late_on` is the sole urgency signal** (a global "now a problem" top tier); within a band, FIFO by `created_at` — **age never becomes urgency**. The order is expressed as a reorderable named-dimension list so it can be retuned without touching the engine.
|
||||
> 🔒 **DECIDED ranking mechanics ([[v1-prototype-tech-spec]] §7):** `do_date` is a *boolean candidacy filter only* (null ⇒ "now"), **never** an urgency input; **`late_on` is the sole urgency signal** (a global "now a problem" top tier); within a band, FIFO by `created_at` — **age never becomes urgency**. The order is expressed as a reorderable named-dimension list so it can be retuned without touching the engine.
|
||||
|
||||
### 6.2.1 Todoist study (2026-06): empirical confirmation + new requirements
|
||||
|
||||
|
|
@ -261,7 +261,7 @@ The owner's old rule — "avoid ncurses and interactive UIs; write atomic code a
|
|||
**Confirms the model:**
|
||||
|
||||
- **Projects = contexts, used heavily and hierarchically.** 34 projects organized into top-level life-areas (`Life`, `Work`, `Coding`, `Camano`, `Culture`) → sub-projects (`Child`, `Blumeops`, `Daily Routine`, `Maintenance`, `Movies`…). The *hierarchy* is new information (§6.2 listed projects flat).
|
||||
- **Huge backlog, tiny hot set.** Priority split p1=2, p2=8, p4(default)=229, p3=148 — i.e. the genuinely "hot" set is ~10, the rest is white/blue backlog. The dominant *activity* is therefore **triage of a large set**, not editing single tasks — a direct argument for an interactive agenda surface (§4, [[tech-spec]] §8.1).
|
||||
- **Huge backlog, tiny hot set.** Priority split p1=2, p2=8, p4(default)=229, p3=148 — i.e. the genuinely "hot" set is ~10, the rest is white/blue backlog. The dominant *activity* is therefore **triage of a large set**, not editing single tasks — a direct argument for an interactive agenda surface (§4, [[v1-prototype-tech-spec]] §8.1).
|
||||
- **Do-date, not due-date — validated to the hilt.** **Zero** Todoist *deadlines* are used; only 107/387 carry a due (do) date. `late_on` will be genuinely rare.
|
||||
- **Recurring checklists are real** ("Prep For Day", every day @ 07:00, 6 children) — exactly the §3.3 reset-each-occurrence mechanism.
|
||||
- **Daily rituals exist as tasks**: "Excess Tasks to On Deck" (= the blue keep/drop review), "Coordinate with Allison", "Check Personal Email" (= orange reconfirm). The §6.2 working-set rituals are alive in the data; the TUI should make them first-class filters.
|
||||
|
|
@ -274,7 +274,7 @@ The owner's old rule — "avoid ncurses and interactive UIs; write atomic code a
|
|||
- **Natural-language recurrence** — 95/107 dated tasks recur, expressed as `every 3 days`, `every 6 months`, `every workday`, `every April 15`, `every other wed`. heph stores RFC-5545 RRULE; capture should accept the common NL forms and compile them (the easy subset; time-of-day like "at 08:00" deferred — heph's `do_date` is date-grained for ranking).
|
||||
- **Tags are noise** — 7 labels, **5 task-uses across 387**. Confidently **defer** a tag surface; it is not load-bearing.
|
||||
|
||||
**The saved filters, verbatim (the basis for heph's filter views, [[tech-spec]] §8.2):**
|
||||
**The saved filters, verbatim (the basis for heph's filter views, [[v1-prototype-tech-spec]] §8.2):**
|
||||
|
||||
| Filter | Todoist query |
|
||||
|---|---|
|
||||
|
|
@ -285,13 +285,13 @@ The owner's old rule — "avoid ncurses and interactive UIs; write atomic code a
|
|||
| Chores | `(today \| overdue \| no date) & (#Chores \| #Camano Chores)` |
|
||||
| On Deck | `p3 & (no date \| overdue \| today)` |
|
||||
|
||||
These define both the **agenda slices** heph must offer ([[tech-spec]] §8.2) and, by what "Tasks" *excludes* (`##Culture` = Movies/Books/Theater; `#Camano Info`), which contexts are **not tasks at all**.
|
||||
These define both the **agenda slices** heph must offer ([[v1-prototype-tech-spec]] §8.2) and, by what "Tasks" *excludes* (`##Culture` = Movies/Books/Theater; `#Camano Info`), which contexts are **not tasks at all**.
|
||||
|
||||
**Reference contexts → wiki, not tasks (decided 2026-06).** The `##Culture` subtree (Movies/Books/Theater) and `#Camano Info` are reference lists (films to watch, books to read, contractor phone numbers), deliberately excluded from every task filter. In heph they belong as **`doc` pages**, not committed tasks — otherwise they flood "what is next?". On the initial Todoist import these 5 projects (~59 items) were reclassified into one wiki list-doc each and the task/project nodes tombstoned. (A useful general principle: a "task" that never appears in any of your filters is probably a note.)
|
||||
|
||||
**Future direction (noted 2026-06, not scheduled):**
|
||||
|
||||
- **Chores as a first-class feature.** Chores want **different do-date / recurrence semantics** from regular tasks (the every-N-days "do it again sometime after" rhythm, tuned-down urgency). Rather than model them as a `#Chores` *project* you scope to, make "chore" a **first-class task property** (kind/flag) with its own scheduling rules — which retires the `#Chores` / `#Camano Chores` projects (and the Camano split) entirely. The interim `Chores` filter view ([[tech-spec]] §8.2) is project-scoped until then.
|
||||
- **Chores as a first-class feature.** Chores want **different do-date / recurrence semantics** from regular tasks (the every-N-days "do it again sometime after" rhythm, tuned-down urgency). Rather than model them as a `#Chores` *project* you scope to, make "chore" a **first-class task property** (kind/flag) with its own scheduling rules — which retires the `#Chores` / `#Camano Chores` projects (and the Camano split) entirely. The interim `Chores` filter view ([[v1-prototype-tech-spec]] §8.2) is project-scoped until then.
|
||||
- **Drop the `Schedule` filter.** Schedule was Todoist's timed-routine view (`!no time`); heph's `do_date` is date-grained, so it is **omitted** (not approximated). It's entangled with the chores rework (timed routines), so reconsider both together if/when time-of-day lands on tasks.
|
||||
|
||||
### 6.3 Two kinds of task: commitments vs. context items
|
||||
|
|
@ -306,7 +306,7 @@ These define both the **agenda slices** heph must offer ([[tech-spec]] §8.2) an
|
|||
|
||||
#### Editing surface for context items — *deliberately deferred to the prototype*
|
||||
|
||||
> 🔑 **DECIDED — Fork A "index" backend (the affordance is still trialed both ways).** The stored source of truth is the `doc` **body markdown**: context items are `- [ ]` lines in it, and a context item's checked state *is* the `[ ]`/`[x]`. They are **not** synced nodes — each replica derives a **local index** from its converged CRDT body, so they converge for free (no divergent ULIDs across offline edits — the original sync trap). Identity is pinned only at **promotion**, which mints a real committed `task` node and rewrites the source line into a link to it. This collapses the hardest sync problem into "the body CRDT already converges" and matches this section's "ephemeral, low-stakes identity" intent. **What's still trialed both ways is purely the nvim *affordance*** (Option A checkboxes-in-body vs. Option B command-driven capture) — the backend is shared, so ergonomics can be judged in the prototype. See [[tech-spec]] §4.3, §5.
|
||||
> 🔑 **DECIDED — Fork A "index" backend (the affordance is still trialed both ways).** The stored source of truth is the `doc` **body markdown**: context items are `- [ ]` lines in it, and a context item's checked state *is* the `[ ]`/`[x]`. They are **not** synced nodes — each replica derives a **local index** from its converged CRDT body, so they converge for free (no divergent ULIDs across offline edits — the original sync trap). Identity is pinned only at **promotion**, which mints a real committed `task` node and rewrites the source line into a link to it. This collapses the hardest sync problem into "the body CRDT already converges" and matches this section's "ephemeral, low-stakes identity" intent. **What's still trialed both ways is purely the nvim *affordance*** (Option A checkboxes-in-body vs. Option B command-driven capture) — the backend is shared, so ergonomics can be judged in the prototype. See [[v1-prototype-tech-spec]] §4.3, §5.
|
||||
|
||||
- **Option A — checkboxes in the body, derived on save.** Edit the task's canonical context doc as plain markdown; `- [ ]` lines are materialized into context-item state on `:w` (`BufWritePost`), reusing the wiki-link extraction machinery. **No real-time scanning needed** (debounced live updates are optional polish). Remote CRDT edits are *pushed* from the daemon to reconcile an open buffer. Item identity is low-stakes (reword = tombstone-old + add-new) since items are ephemeral; identity is pinned only at **promotion**. Most "personal org-mode"-native; millisecond capture = "type a line."
|
||||
- **Option B — command-driven capture, rendered.** Capture via a leader chord + `vim.ui.input` (no raw checkbox typing); the new item is still written as a `- [ ]` line into the body-backed store (Fork A), then **rendered** inline via virtual text/extmarks or a transient **floating window** (avoids the disliked persistent cutaway). Heavier capture; more UI to build; promotion identical.
|
||||
|
|
@ -410,7 +410,7 @@ Reuse the established blumeops patterns (🔒 confirmed by repo conventions):
|
|||
1. **CRDT library** for body merge: `yrs` (leaning) vs `automerge`; bespoke op-log/HLC for scalar fields either way.
|
||||
2. **Hub network transport** (tech-spec §6.1): `axum` HTTP/JSON (leaning) vs gRPC; sync propagation cadence (push vs periodic pull); **device-id provisioning** (how a spoke mints its `origin` id and registers with the hub).
|
||||
|
||||
*Resolved in the second-pass review (2026-05-31), now folded into [[tech-spec]]:*
|
||||
*Resolved in the second-pass review (2026-05-31), now folded into [[v1-prototype-tech-spec]]:*
|
||||
|
||||
3. ✅ **Recurrence → roll-forward in place** (§3.3) — occurrence-instances rejected (would explode into a node-per-occurrence under Fork A); advance to the next RRULE instance after `now`, skipping misses.
|
||||
4. ✅ **Context items → Fork A "index" backend** (§6.3) — body markdown is the source of truth; context items are a local derived index, not synced nodes; identity at promotion. The nvim *affordance* (A vs B) is still trialed in-prototype.
|
||||
|
|
@ -430,10 +430,10 @@ Reuse the established blumeops patterns (🔒 confirmed by repo conventions):
|
|||
|
||||
## 10. Roadmap (provisional)
|
||||
|
||||
- **Phase 0 — Design** (this document + [[tech-spec]]): done enough to build.
|
||||
- **Phase 0 — Design** (this document + [[v1-prototype-tech-spec]]): done enough to build.
|
||||
- **Phase 1 — v1 prototype (a single C1 effort, deliberately — a one-shot test of delivering a high-complexity prototype from the spec; built in TDD slices):** `heph-core` (model, schema, extraction, recurrence, "what is next", `Store` trait, op-log/HLC/CRDT merge) → `hephd` **local mode** → **server + client modes (+ lock handoff)** → **offline sync + conflict queue** → **OIDC/Authentik auth + per-user isolation** → `heph.nvim` + `heph` CLI. Local-only works standalone; runnable client/server + offline sync on the tailnet. The build order doubles as the cross-session resume tracker (next un-green slice = where to resume). C2/Mikado is *not* used: it sequences prerequisites against existing code under test, and this is greenfield delivery from a complete spec; follow-up C1s or a C2 refactor come later as needed.
|
||||
|
||||
**Phase 1 progress** (branch `feature/v1-prototype`, PR #1; 102 tests green as of 2026-06-01 — see [[tech-spec]] §14 for the per-area tracker):
|
||||
**Phase 1 progress** (branch `feature/v1-prototype`, PR #1; 102 tests green as of 2026-06-01 — see [[v1-prototype-tech-spec]] §14 for the per-area tracker):
|
||||
- [x] `heph-core` library — schema/`Store`/`LocalStore`, extraction, tasks/links/canonical-context + wiki-link materialization, "what is next?" ranking, recurrence roll-forward + per-task logs.
|
||||
- [x] `hephd` **local mode** — file lock + JSON-RPC over a unix socket (tokio blocking pool); `heph` CLI + `export`.
|
||||
- [x] Local query surface — `list`, `health`, `journal`, `search` (FTS5).
|
||||
|
|
@ -447,7 +447,7 @@ Reuse the established blumeops patterns (🔒 confirmed by repo conventions):
|
|||
|
||||
> The handoff target for the next context session. Items here are **proposals to ratify**; once ratified, a fresh session can build directly from this.
|
||||
|
||||
> **The canonical, implementation-ready scope/stack/schema/API now live in [[tech-spec]].** This section keeps the *intent* and the kickoff process; defer to the spec for details (and update the spec when decisions change).
|
||||
> **The canonical, implementation-ready scope/stack/schema/API now live in [[v1-prototype-tech-spec]].** This section keeps the *intent* and the kickoff process; defer to the spec for details (and update the spec when decisions change).
|
||||
|
||||
### 11.1 Scope — *local-to-distributed via a targetable backend* (ratified)
|
||||
|
||||
|
|
@ -464,7 +464,7 @@ Core: `rusqlite` (bundled) + migrations · `tokio` + JSON-RPC/unix-socket (local
|
|||
|
||||
### 11.3 First-session kickoff checklist
|
||||
|
||||
1. `mise run ai-docs`; read **[[tech-spec]]** (the build spec) and this doc's §3/§6 for rationale.
|
||||
1. `mise run ai-docs`; read **[[v1-prototype-tech-spec]]** (the build spec) and this doc's §3/§6 for rationale.
|
||||
2. **Classify as a single C1** (deliberate — a one-shot test of delivering this high-complexity prototype from the spec; C2/Mikado is for sequencing prerequisites against *existing* code, not greenfield delivery). Single long-lived feature branch + early draft PR, docs-first, push as you go ([[agent-change-process]]). The §11.1 build order is the resume tracker; the hairy slices (sync/CRDT) may spin off follow-up C1s rather than blocking the prototype.
|
||||
3. Scaffold the cargo workspace + `heph.nvim` skeleton; **fill the AGENTS.md Project Structure section** (last template TODO).
|
||||
4. Build outward in testable slices (TDD, tech-spec §2/§9): `heph-core` (schema, model, extraction, recurrence, "what is next", `Store` trait, **op-log/HLC/CRDT merge**) → `hephd` **local mode** (LocalStore + lock + local RPC) → **server + client modes** (network endpoint, RemoteStore, lock handoff) → **sync + conflict queue** → **OIDC auth** → `heph.nvim` + `heph` CLI.
|
||||
|
|
@ -472,6 +472,6 @@ Core: `rusqlite` (bundled) + migrations · `tokio` + JSON-RPC/unix-socket (local
|
|||
|
||||
## Related
|
||||
|
||||
- [[tech-spec]] — clean implementation-facing technical specification distilled from this document
|
||||
- [[v1-prototype-tech-spec]] — clean implementation-facing technical specification distilled from this document
|
||||
- [[ai-assistance-guide]] — conventions for AI agents in this repo
|
||||
- [[agent-change-process]] — C0/C1/C2 change methodology
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ doing something separately from *how loud* it should be.
|
|||
is next").
|
||||
- **`done`** — you did it. Terminal. For a **recurring** task, completing rolls
|
||||
it *forward* to its next occurrence with a fresh checklist (it reappears as a
|
||||
new outstanding instance — see [[design]] §3.3 and [[tech-spec]] §4.4), rather
|
||||
new outstanding instance — see [[design]] §3.3 and [[v1-prototype-tech-spec]] §4.4), rather
|
||||
than ending.
|
||||
- **`dropped`** — you've decided **not** to do it ("let it go"). Terminal, and
|
||||
the sibling of `done`: "didn't do" vs "did". The distinction from `done` is
|
||||
|
|
@ -67,7 +67,7 @@ either keeping it blue ("later") or **dropping** it ("let go").
|
|||
the task node `tombstoned` and removes it from *everything* — the agenda,
|
||||
full-text search, and export. It is a **soft delete** (the row is retained with
|
||||
a flag, recoverable at the database level, and CRDT-safe — heph never hard-deletes,
|
||||
see [[tech-spec]] §12), but for all practical purposes the task is gone.
|
||||
see [[v1-prototype-tech-spec]] §12), but for all practical purposes the task is gone.
|
||||
|
||||
Deleting a task tombstones **only the task node** — its canonical-context doc
|
||||
(your notes/checklist for it) is **kept**, so deleting a task doesn't throw away
|
||||
|
|
@ -90,7 +90,7 @@ without cluttering your working set.
|
|||
## How you move a task between states
|
||||
|
||||
The model is surface-agnostic; the gestures differ per surface. In the TUI
|
||||
([[tech-spec]] §8.1):
|
||||
([[v1-prototype-tech-spec]] §8.1):
|
||||
|
||||
| Gesture | Effect |
|
||||
|---|---|
|
||||
|
|
@ -109,4 +109,4 @@ committed task ([[design]] §6.3).
|
|||
## Related
|
||||
|
||||
- [[design]] §6.2 (the lived priority discipline), §6.3 (commitments vs context items)
|
||||
- [[tech-spec]] §4.3 (task semantics), §7 (ranking), §8.1 (the TUI), §12 (tombstones)
|
||||
- [[v1-prototype-tech-spec]] §4.3 (task semantics), §7 (ranking), §8.1 (the TUI), §12 (tombstones)
|
||||
|
|
|
|||
|
|
@ -85,4 +85,4 @@ talks to the dev daemon. They never share a socket or DB. `.dev/` is gitignored.
|
|||
## Related
|
||||
|
||||
- [[heph-nvim]] — the plugin surface and its managed-daemon lifecycle
|
||||
- [[tech-spec]] — §3.1 runtime modes; the daemon's exclusive DB lock
|
||||
- [[v1-prototype-tech-spec]] — §3.1 runtime modes; the daemon's exclusive DB lock
|
||||
|
|
|
|||
|
|
@ -119,5 +119,5 @@ identical to the native `mise run test-nvim` path.
|
|||
|
||||
## Related
|
||||
|
||||
- [[tech-spec]] — §8 surface spec, §6 RPC API, §9 testing strategy
|
||||
- [[v1-prototype-tech-spec]] — §8 surface spec, §6 RPC API, §9 testing strategy
|
||||
- [[design]] — the mode model (Tactical/Strategic/Organizational) and rationale
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ Technical reference material for the repository tooling that ships with this pro
|
|||
|
||||
## Project
|
||||
|
||||
- [[tech-spec]] — Hephaestus technical specification (data model, RPC API, "what is next?" ranking, recurrence, testing strategy, v1 scope)
|
||||
- [[v1-prototype-tech-spec]] — Hephaestus technical specification (data model, RPC API, "what is next?" ranking, recurrence, testing strategy, v1 scope)
|
||||
- [[heph-nvim]] — The Neovim plugin surface: architecture, buffer-backed editing, RPC dependencies, commands, and the headless e2e harness
|
||||
|
||||
## Template Surface Area
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
---
|
||||
title: Technical Specification
|
||||
title: Technical Specification — v1 Prototype (historical)
|
||||
modified: 2026-06-03
|
||||
tags:
|
||||
- reference
|
||||
- design
|
||||
---
|
||||
|
||||
# Hephaestus — Technical Specification
|
||||
# Hephaestus — Technical Specification (v1 Prototype)
|
||||
|
||||
> Clean, implementation-facing spec for the v1 prototype. For the *why* behind every choice (history, prior art, decision trail), see [[design]]. Where this spec and the design doc disagree, the design doc's latest decision wins — file an update here.
|
||||
> ⚠️ **Historical document.** This is the implementation spec for the **v1 prototype**, kept as the record of what was designed and built. **v1 reached Todoist feature-parity on 2026-06-03** — the Rust backend is feature-complete and all three surfaces (`heph` CLI, `heph-tui`, `heph.nvim`) are daily-drivers. **heph now self-hosts its own roadmap:** remaining and future work lives as tasks in the **`Hephaestus` project inside heph** — capture with `heph task "…" --project Hephaestus`, triage in `heph-tui` (the *On Deck* view) or `heph view ondeck`. The §14 tracker below is preserved as the **build history, not a live TODO**. See `AGENTS.md` for the working process.
|
||||
|
||||
> Clean, implementation-facing spec for the v1 prototype. For the *why* behind every choice (history, prior art, decision trail), see [[design]] (the living design doc). Where this spec and the design doc disagree, the design doc's latest decision wins.
|
||||
|
||||
## 1. Overview
|
||||
|
||||
|
|
@ -424,6 +426,8 @@ See [[design]] §5–§7 for the constraints later phases impose on present choi
|
|||
|
||||
## 14. Implementation status (Phase 1 tracker)
|
||||
|
||||
> 📜 **Historical, as of v1 parity (2026-06-03).** This tracker recorded the Phase 1 build slice-by-slice. With parity reached, **ongoing/future work is no longer tracked here** — it lives in heph itself, in the **`Hephaestus` project** (`heph view ondeck` · `heph-tui` → *On Deck*). What remains below (the ⏳ items) was captured into that project as tasks; this section is kept as the build record.
|
||||
|
||||
> Cross-session resume tracker for the Phase 1 C1 (branch `feature/v1-prototype`, PR #1). Updated 2026-06-03 — **186 Rust tests** (`cargo test --all`) + **18 heph.nvim headless e2e specs** (`mise run test-nvim`; also runs in CI via `dagger call test-nvim`), `clippy -D warnings` + `fmt` + `prek` clean. Workspace: `crates/heph-core`, `crates/hephd`, `crates/heph`, **`crates/heph-tui`**, plus `heph.nvim/` (slices 11a–11c **+ a UX iteration + filter views + the heph-tui agenda**, below). **The plugin is installed and running on the dev machine** (built from the forge; see [[install-heph]]).
|
||||
|
||||
**Done**
|
||||
Loading…
Add table
Add a link
Reference in a new issue