Skip to content

Session plan — 2026-09-22

Spec produced by a grilling session after the workspace reorg. Every decision below was confirmed by Nathan; anything not confirmed is listed under Open questions in its item rather than filled in.

Order: 0 → 2 → 4 → 5 → 1 → 6 → 7 → 3. Security first, the open-ended pilot last.


0. Land the backlog MR — done (merged)

MR !6: code-library, voice, dashboard, workspace layout, vendored laya-integration skill. make check green.

  • The Laya SKILL.md has no stated license (model is Apache-2.0); recorded in shared/skills/laya-integration/PROVENANCE.md.

1. Case-only renames in workspace_layout.py apply

On macOS (case-insensitive FS) OSS → oss is treated as already done and silently skipped.

  • apply detects source/target that differ only by case and renames via a temporary name (OSS → OSS.tmp-<pid> → oss).
  • plan shows the two-step rename.

Done when: a new test fails on current code and passes after; make check green.

2. Keep agents out of the Sensitive Anytype space

Verified: a scoped key works. The new key (Agent-Key-Scoped-RW) is granted 3 spaces, not Sensitive; /v2/spaces returns has_not_granted_spaces: true. Scoped keys are v2-only (/v1 → 403 v1_not_available_for_scoped_keys); @anyproto/anytype-mcp 2.0.1 loads /v2/docs/openapi.json first, so the MCP is unaffected after a restart.

Remaining:

  • 2b. Add anytype_id (compact id, e.g. 5smqsi) to each entry in knowledge/anytype-integration/schemas/spaces.json; match on id, not name. Fix the name drift while there. tenancy.py --check validates the field.
  • 2c. make anytype-scope-check: reads the key from the shell env, calls /v2/spaces, fails if any space with agent_read: false is visible. Not in make check / pre-commit (Anytype isn't always running, never in CI); surfaced as a health item on the dashboard.
  • 2d. Restart Claude Code; confirm mcp__anytype__API-list-spaces shows 3 spaces.

Done when: the check fails against a key that can see Sensitive (fixture / stubbed response) and passes against the live scoped key.

3. code_library pilot — blocked on item 7

Paused 2026-09-22: a dry scan showed the tool-only model doesn't fit (see item 7). Categories are enabled on feat/code-library-pilot; processing waits until repos have kinds, so accepted entries aren't redone.

  • Enable all categories: ai, infosec, finance, ml, utility.
  • Process through the dashboard: everything-claude-code, langgraph, strix, agentshield, nautilus_trader.
  • Write down friction as follow-up items (append to this file).

Done when: search_tools returns relevant hits from ≥3 of those repos, and a friction list exists.

4. make mcp-smoke — lesson from the code_library serve crash

  • For each [mcp.*] in tool-chest.toml: launch over stdio with a timeout, initialize, list_tools, assert ≥1 tool.
  • Separate target, not pre-commit (uv/npx cold starts are slow; anytype needs the app). CI runs it with anytype skipped.
  • Record in the lesson ledger (/lesson).

Done when: it fails against the pre-fix code_library (calibrated on the known failure) and passes on all current servers.

5. Dashboard write-endpoint hardening

Found 2026-09-22: scripts/dashboard.py POST routes do no Origin/Host checks, so any web page open in the browser can reach 127.0.0.1:8787 (CSRF, DNS rebinding). Item 6's connect would widen this to writing agent config. Must land before 6e.

  • Reject requests whose Host isn't 127.0.0.1:<port> / localhost:<port>.
  • Reject POSTs whose Origin isn't the dashboard's own origin.
  • Per-launch random token embedded in the served page, required on every POST.

Done when: tests cover foreign Origin, foreign Host and missing/wrong token (each rejected) and the real UI still works.

6. Capability ring — dashboard home

A visual home view: one central workspace object ringed by capability areas. Each area can be configured, activated, and connected to agent clients, and clicks through to its list/detail view.

Decisions

Topic Decision
Ring nodes Capability areas (not one per MCP)
Registry [capability.<id>] in tool-chest.toml is the source of truth
States Configure (settings) → Activate (prereqs met, health probe passes) → Connect (exposed to clients)
Connect Toggles generated MCP config; UI shows "restart client to apply"
Granularity Per area × client; clients = [...] replaces [mcp.*].scope
Clients (v1) Extensible: a [client.<id>] registry (label, config path, format); built-in writers per common JSON shape, a small adapter only for a genuinely new shape (e.g. CLI-driven). Planned beyond v1: OpenCode, Cline, Cody… v1 set: claude-project (.mcp.json), claude-user (via claude mcp add/remove -s user, never editing ~/.claude.json directly), cursor (.cursor/mcp.json). Local agent dropped: local-agent has no model/MCP layer
Placement Ring replaces Home; existing sections are the drill-downs
Rendering Vanilla SVG, no build step; stacks to a list on narrow screens. Style: C · Constellation (cards on an ellipse). Cards show name, status line, health bar — no client chips; connections appear only in the side panel
Center Overall health (make check, layout, anytype scope), client status and pending restarts, workspace bucket counts, global actions (regenerate configs, run checks, open docs)
v1 scope Ring + side panel + connect + health; areas lacking a view get a count-only placeholder

Areas

Area Backed by Drill-down
Code library mcp code_library Code library section
Reference library mcp library placeholder (book count)
Research mcp research placeholder (article count)
Patterns mcp patterns Search
PKM (Anytype) mcp anytype, skills pkm-* Inbox / Tasks / People
Voice cli voice Voice
Model routing service OmniRoute OmniRoute
Sandbox & labs cli sandbox, labs Labs / Sandbox plan

Skills, MCP list, Harnesses and Workspaces are cross-cutting, reached from the center.

Slices

  • 6a Registry. [capability.*] schema (label, mcp, cli, skills, drill-down section, health probe). Drift check in make check: every [mcp.*] belongs to exactly one area. GET /api/capabilities.
  • 6b Generator. A [client.<id>] registry plus built-in format writers; clients (ids from the registry) replaces scope in gen_mcp_config.py; migration test proves today's generated .mcp.json / .cursor/mcp.json are unchanged; claude-user goes through claude mcp add/remove -s user (also fixes make mcp-install-user).
  • 6c Ring (read-only). Constellation-style SVG ring replaces Home; node badges for the three states; click → side panel → drill-down link.
  • 6d Health. Per-area probe from the registry, shown on nodes and the center.
  • 6e Connect. One toggle per registered client in the side panel; writes tool-chest.toml, regenerates, shows pending-restart. Blocked on 5.
  • 6f Configure / activate. Side-panel settings and setup actions.

Open questions

  • 6f: which settings are editable per area, and may the dashboard run setup targets (e.g. make voice-setup)? If yes, from a fixed allowlist?
  • Pending restart: how to clear it (a timestamp compare against client start, or a manual "I restarted" dismiss)?
  • Cursor user scope (~/.cursor/mcp.json): out of v1?

Answers:

  • 6f: for each area, v1 should only expose the settings necessary to correctly configure that area. Exposing additional, optional config surfaces can come later, if the core thesis of this approach bears out.
  • Pending restart: Unclear what the best solution is here. Users can be unreliable, and may dismiss the warning even if they have not restarted yet. What is the simplest, safest solution here?
  • Cursor usage scope: include in v1

Resolutions (2026-09-22)

  • Pending restart: derived, no dismiss button. A client is "restart pending" while any of its running processes started before its config last changed; it clears itself. May over-warn, never under-warn.
  • 6f settings (v1, required only): Code library source_root, enabled_categories; Reference library calibre_library; Research archive_dir (archive lives outside the repo); Patterns none (in-repo corpus); PKM api_base_url + key status only; Voice model; Model routing enabled, base_url; Sandbox & labs none. Secrets are never editable.
  • 6f setup runs: fixed allowlist, at most one setup target per capability, declared in the registry, behind item 5's token.
  • Cursor user scope: in v1 as client cursor-user (~/.cursor/mcp.json).

7. Code library: repo kinds

Found in the pilot dry scan (205 proposals over 5 repos, almost all noise): README backtick mentions became "tools" (sk-ant-, StateGraph); build and maintenance targets swamped real entry points; libraries yielded nothing.

Decisions

Topic Decision
Kinds collection (many discrete units, e.g. everything-claude-code), library (one unit, used as a detailed reference though imported normally, e.g. langgraph), tool (one runnable app, e.g. strix, agentshield)
Assigning a kind Scanner suggests on Process; Nathan confirms or changes before anything is indexed; stored in library.toml
Collection units Known shapes: skill (dir with SKILL.md), agent, command, hook, MCP server, CLI entry point. Each proposed separately; new shapes are added to the detector as met
Tool entry Its CLI recipe (bin / pyproject script)
Library reference Docs + examples, public API surface (static: modules, classes, signatures, docstrings, never imported or run), source passages as a last resort
Version match Clone version/tag vs pins found in lockfiles under ~/Documents/workspace/projects/* (uv.lock, package-lock.json, pyproject, Cargo.lock); a mismatch is flagged on the library entry

Slices

  • 7a Drop README-mention proposals (bug).
  • 7b Repo kind: suggest + confirm + persist. Existing proposals flow under tool; the kind drives which extractor runs.
  • 7c Tool kind proposes entry points only, not build/lint/test targets.
  • 7d Collection units: detect the known shapes, accept per unit.
  • 7e Library reference: index docs + examples + source passages, searchable per library.
  • 7f Library API surface: static extraction of the public API.
  • 7g Version match against projects' lockfiles.

Pilot (item 3) is blocked by 7a–7e.

Open question

  • 7c: is "entry points only" right for tools, or should the review still list other targets hidden by default? Resolved (Nathan, 2026-09-23): entry points only. Build, lint, test and install targets are not proposed, not even hidden.