Design: migrate panels to coily verbs + cli-web-ops, sunset the Go daemon #4

Closed
opened 2026-05-23 20:55:19 +00:00 by coilysiren · 0 comments
Owner

Originally filed by @coilysiren on 2026-05-14T04:25:35Z - https://github.com/coilysiren/personal-dashboard/issues/53

Honest framing

The Go HTTP daemon built in #36 through #48 is a working prototype that confirmed the panel set and shook out the redact-by-default UX. It is also a parallel reimplementation of cli-web-ops, which already exists for this exact purpose: a mobile-first MCP-client web executor with annotation-driven favorites via tool.Meta["webops.*"] and a Tailscale-only bind by default.

The right architecture is:

  1. Each internal/sources/* package becomes a coily subcommand (e.g. coily inbox list, coily denials list, coily steam recent). Same data, exposed as a CLI tree.
  2. cli-mcp projects those verbs as MCP tools automatically. No new MCP code to write.
  3. cli-web-ops renders the MCP tools as panels, picking up webops.favorite=true Meta annotations. Mobile-first PWA shell for free.
  4. The redact-by-default reveal mechanism (#41) belongs in cli-guard as a data-security-mode primitive, not in the dashboard repo. See prereq chain below.

Prerequisite chain

This migration is blocked on the lockdown-profile work in flight:

  • coilysiren/coilyco-ai#396 - umbrella: execution-mode-scoped lockdown profiles.
  • coilysiren/coily#150 - consumer-side per-session lockdown profiles (three-layer architecture: cli-guard categorical / coily.yaml mapping / session sentinel keyed by CLAUDE_CODE_SESSION_ID).
  • coilysiren/cli-guard#32 - package-side hoist of the categorical pattern.

Architecture already settled:

  • cli-guard owns gate-enforceable axes (data security, blast radius, network egress, filesystem reach).
  • Agent-side posture stays in kai-execution-mode-* skills.
  • Sentinel at ~/.coily/audit/sessions/<CLAUDE_CODE_SESSION_ID>/profile.

Until coily#150 and cli-guard#32 land, the dashboard's MCP/web-ops integration would lack the per-session profile gate that makes mobile-dictation from a public space safe. That is the prerequisite gate.

Migration plan

Sequence, once prereqs land:

  1. Source extraction. Each internal/sources/* package becomes a coily subcommand under a new namespace. Suggested: coily inbox, coily denials, coily steam, coily luca, coily social, coily home. Each verb emits structured JSON (kai-tech-prefs JSON-twin pattern).
  2. Meta annotations. Stamp tool.Meta["webops.favorite"] = "true" plus any webops.icon / webops.title per panel so cli-web-ops shows them in the mobile favorites list. Annotation surface defined by cli-mcp.
  3. Reveal mechanism migration. The internal/session/ reveal store and redact-by-default CSS class are repackaged as a cli-guard data-security-mode primitive. The dashboard never holds reveal state directly; cli-guard's session sentinel decides which fields a verb's output redacts.
  4. Voice migration. ElevenLabs TTS becomes either a coily verb (coily say <text>) or a cli-web-ops extension. Out of scope for the initial port.
  5. Sunset. Once panels are reachable through cli-web-ops with parity to the current HTTP daemon, personal-dashboard repo either:
    • Becomes a thin catalog repo listing which coily verbs to favorite (a YAML manifest cli-web-ops consumes), or
    • Archives. coily owns the verbs, cli-web-ops owns the rendering.

What survives the prototype

  • Panel set: six panels validated against real data (daily inbox, allowlist gap, steam, luca/o2r, social, home).
  • Redact-by-default UX: per-page granularity + per-session persistence (#41). Will inform the cli-guard data-security-mode design.
  • Vault inbox parser: YAML frontmatter + llm-synthesis block extraction is reusable in coily inbox list.
  • Coily audit JSONL reader: the rejection-row filter logic is reusable in coily denials list.
  • Dispatcher abstraction (#40): the coily:// URL pattern is exactly what cli-web-ops emits anyway, so the abstraction was correct - just lived in the wrong repo.
  • AWS-region bug surfaced: pre-existing meta-improvement filed as a spawn-task chip.
  • Template namespace collision lesson: lol, glad it bit me here and not in cli-web-ops.

What dies

  • cmd/personal-dashboard/main.go HTTP daemon.
  • internal/server/ (cli-web-ops handles rendering).
  • internal/dispatcher/ (cli-web-ops emits the coily:// URLs).
  • internal/session/ (data-security-mode in cli-guard).
  • internal/voice/ (migrates to a coily verb).
  • The PWA shell, manifest, service worker, htmx vendor.
  • The dev watcher (cmd/dev) is still useful as a personal tool but does not belong in this repo.

Holding state

The prototype keeps running on 127.0.0.1:31337 until prereqs land. Existing panels are useful as a reference implementation while porting. Once the migration begins, the HTTP daemon path is a one-way door - we delete it, not maintain two surfaces.

Out of scope here

  • Designing the data-security-mode primitive itself. That belongs on coily#150 / cli-guard#32.
  • Deciding whether personal-dashboard repo lives on as a catalog or archives. Depends on whether cli-web-ops favorites need per-user customization beyond what annotations provide.

Action items, deferred until prereqs land

  • Add coily inbox namespace with list / mark-read / mark-unread verbs.
  • Add coily denials namespace with list / propose-allowlist.
  • Add coily steam recent verb.
  • Add coily luca digest + grafana / phoenix deep-link verbs.
  • Add coily social namespace (bluesky / reddit / discord sub-verbs).
  • Add coily home namespace (hue / sonos / cast preset verbs).
  • Define and stamp webops.* annotations on each panel-favorite verb.
  • Migrate reveal mechanism to cli-guard data-security-mode primitive.
  • Delete cmd/personal-dashboard/, internal/server/, internal/dispatcher/, internal/session/.
  • Decide catalog-vs-archive for this repo.
_Originally filed by @coilysiren on 2026-05-14T04:25:35Z - [https://github.com/coilysiren/personal-dashboard/issues/53](https://github.com/coilysiren/personal-dashboard/issues/53)_ ## Honest framing The Go HTTP daemon built in #36 through #48 is a working prototype that confirmed the panel set and shook out the redact-by-default UX. It is also a parallel reimplementation of [cli-web-ops](https://github.com/coilysiren/cli-web-ops), which already exists for this exact purpose: a mobile-first MCP-client web executor with annotation-driven favorites via `tool.Meta["webops.*"]` and a Tailscale-only bind by default. The right architecture is: 1. Each `internal/sources/*` package becomes a coily subcommand (e.g. `coily inbox list`, `coily denials list`, `coily steam recent`). Same data, exposed as a CLI tree. 2. [cli-mcp](https://github.com/coilysiren/cli-mcp) projects those verbs as MCP tools automatically. No new MCP code to write. 3. cli-web-ops renders the MCP tools as panels, picking up `webops.favorite=true` Meta annotations. Mobile-first PWA shell for free. 4. The redact-by-default reveal mechanism (#41) belongs in cli-guard as a **data-security-mode** primitive, not in the dashboard repo. See prereq chain below. ## Prerequisite chain This migration is blocked on the lockdown-profile work in flight: - [coilysiren/coilyco-ai#396](https://github.com/coilysiren/coilyco-ai/issues/396) - umbrella: execution-mode-scoped lockdown profiles. - [coilysiren/coily#150](https://github.com/coilysiren/coily/issues/150) - consumer-side per-session lockdown profiles (three-layer architecture: cli-guard categorical / coily.yaml mapping / session sentinel keyed by `CLAUDE_CODE_SESSION_ID`). - [coilysiren/cli-guard#32](https://github.com/coilysiren/cli-guard/issues/32) - package-side hoist of the categorical pattern. Architecture already settled: - cli-guard owns gate-enforceable axes (data security, blast radius, network egress, filesystem reach). - Agent-side posture stays in `kai-execution-mode-*` skills. - Sentinel at `~/.coily/audit/sessions/<CLAUDE_CODE_SESSION_ID>/profile`. Until coily#150 and cli-guard#32 land, the dashboard's MCP/web-ops integration would lack the per-session profile gate that makes mobile-dictation from a public space safe. That is the prerequisite gate. ## Migration plan Sequence, once prereqs land: 1. **Source extraction.** Each `internal/sources/*` package becomes a coily subcommand under a new namespace. Suggested: `coily inbox`, `coily denials`, `coily steam`, `coily luca`, `coily social`, `coily home`. Each verb emits structured JSON (kai-tech-prefs JSON-twin pattern). 2. **Meta annotations.** Stamp `tool.Meta["webops.favorite"] = "true"` plus any `webops.icon` / `webops.title` per panel so cli-web-ops shows them in the mobile favorites list. Annotation surface defined by cli-mcp. 3. **Reveal mechanism migration.** The `internal/session/` reveal store and `redact-by-default` CSS class are repackaged as a cli-guard data-security-mode primitive. The dashboard never holds reveal state directly; cli-guard's session sentinel decides which fields a verb's output redacts. 4. **Voice migration.** ElevenLabs TTS becomes either a coily verb (`coily say <text>`) or a cli-web-ops extension. Out of scope for the initial port. 5. **Sunset.** Once panels are reachable through cli-web-ops with parity to the current HTTP daemon, personal-dashboard repo either: - Becomes a thin catalog repo listing which coily verbs to favorite (a YAML manifest cli-web-ops consumes), or - Archives. coily owns the verbs, cli-web-ops owns the rendering. ## What survives the prototype - **Panel set**: six panels validated against real data (daily inbox, allowlist gap, steam, luca/o2r, social, home). - **Redact-by-default UX**: per-page granularity + per-session persistence (#41). Will inform the cli-guard data-security-mode design. - **Vault inbox parser**: YAML frontmatter + llm-synthesis block extraction is reusable in `coily inbox list`. - **Coily audit JSONL reader**: the rejection-row filter logic is reusable in `coily denials list`. - **Dispatcher abstraction (#40)**: the `coily://` URL pattern is exactly what cli-web-ops emits anyway, so the abstraction was correct - just lived in the wrong repo. - **AWS-region bug surfaced**: pre-existing meta-improvement filed as a spawn-task chip. - **Template namespace collision lesson**: lol, glad it bit me here and not in cli-web-ops. ## What dies - `cmd/personal-dashboard/main.go` HTTP daemon. - `internal/server/` (cli-web-ops handles rendering). - `internal/dispatcher/` (cli-web-ops emits the `coily://` URLs). - `internal/session/` (data-security-mode in cli-guard). - `internal/voice/` (migrates to a coily verb). - The PWA shell, manifest, service worker, htmx vendor. - The dev watcher (cmd/dev) is still useful as a personal tool but does not belong in this repo. ## Holding state The prototype keeps running on `127.0.0.1:31337` until prereqs land. Existing panels are useful as a reference implementation while porting. Once the migration begins, the HTTP daemon path is a one-way door - we delete it, not maintain two surfaces. ## Out of scope here - Designing the data-security-mode primitive itself. That belongs on coily#150 / cli-guard#32. - Deciding whether personal-dashboard repo lives on as a catalog or archives. Depends on whether cli-web-ops favorites need per-user customization beyond what annotations provide. ## Action items, deferred until prereqs land - [ ] Add `coily inbox` namespace with `list` / `mark-read` / `mark-unread` verbs. - [ ] Add `coily denials` namespace with `list` / `propose-allowlist`. - [ ] Add `coily steam recent` verb. - [ ] Add `coily luca digest` + grafana / phoenix deep-link verbs. - [ ] Add `coily social` namespace (bluesky / reddit / discord sub-verbs). - [ ] Add `coily home` namespace (hue / sonos / cast preset verbs). - [ ] Define and stamp `webops.*` annotations on each panel-favorite verb. - [ ] Migrate reveal mechanism to cli-guard data-security-mode primitive. - [ ] Delete `cmd/personal-dashboard/`, `internal/server/`, `internal/dispatcher/`, `internal/session/`. - [ ] Decide catalog-vs-archive for this repo.
coilysiren 2026-05-30 05:44:19 +00:00
  • closed this issue
  • added the
    icebox
    label
Commenting is not possible because the repository is archived.
No labels
icebox
P0
P1
P2
P3
P4
No milestone
No project
No assignees
1 participant
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
coilysiren/personal-dashboard#4
No description provided.