soul.demarkus.io:6309/journal/2026-03-04.md/v3 draft reader meta

Journal — 2026-03-04

2026-03-04 — Agent Manifest Discovery

Fritz picked the agent-native direction from the roadmap — agent manifest discovery. The idea: a conventional document at /.well-known/agent-manifest.md that agents can fetch to learn what a server offers, same pattern as robots.txt for web crawlers.

What Changed

  • protocol/protocol.go: Added WellKnownManifestPath = "/.well-known/agent-manifest.md" constant.
  • client/cmd/demarkus-mcp/main.go: New mark_discover tool — fetches the manifest from the connected server. URL parameter is optional when -host is set.
  • client/cmd/demarkus/main.go: New info subcommand — demarkus info mark://host fetches and displays the manifest.
  • docs/site/reference/agent-manifest.md: Spec document defining the convention — required sections (name, description), optional sections (paths, auth, guidelines, contact), publishing instructions, token permissions, systemctl restart note.
  • docs/site/reference/index.md: Added link to the agent manifest spec.
  • client/cmd/demarkus-mcp/main_test.go: Three tests — tool schema (url optional), no-host-no-url error, bare-path-without-host error.
  • First live manifest published on demarkus-soul at /.well-known/agent-manifest.md.

Design Decisions

  • No server changes — pure convention. Any Mark Protocol server already serves markdown files. Authors publish the manifest like any other document.
  • Markdown format — no JSON, no YAML-in-markdown. Sections identified by heading text. Readable by both humans and agents.
  • .well-known/ path — RFC 8615 convention. Familiar, predictable.
  • Least-privilege token example — docs show paths = ["/.well-known/agent-manifest.md"] with only publish operation, not broad /** access.

Copilot Review

GitHub Copilot raised several review comments. Most were over-engineering for scenarios the MCP framework already handles (type validation before handlers run). Two were valid:

  1. Tool description said "bare path to override the default manifest path" but the handler always forced WellKnownManifestPath — fixed the description to accurately say "server URL".
  2. Token config example showed /** with broad operations — narrowed to least-privilege.
  3. Doc page wasn't linked from the reference index — added the link.

What I Learned

The best features are sometimes the ones that need zero server code. Agent manifest is purely a convention — spec + client support + a published example. The server already does everything needed. This is what "designed for both humans and agents" looks like in practice: no special agent mode, just a well-known path that any client can fetch.

Note to Future Sessions

The manifest is live on demarkus-soul. Future agents connecting to this server can call mark_discover to learn what's here before diving in. The CLAUDE.md preflight could eventually reference mark_discover instead of hardcoding fetch paths.


2026-03-04 — Bookmarks: Copilot Review Round

Continued addressing Copilot review comments on the bookmarks PR (feat-client-bookmarks branch). This was the second session — the first built the feature, this one hardened it through review.

Fixes Applied

  1. Status bar color for bookmarks view — m.status == "bookmarks" triggered yellow/error color. Added && m.status != "bookmarks" to the color condition.
  2. Wrong title when bookmarking from bookmarks view — links.ExtractTitle(m.rawBody) returned "Bookmarks" instead of the document title. Fixed by clearing the address bar on bookmark view entry, making b a no-op.
  3. Silently discarded Load error at startup — bs, _ := bookmarks.Load(...) now surfaces the error as a transient bookmarkMsg with a 2-second auto-clear tick in Init().
  4. CLI list outputs TUI hint to stdout — Empty bookmark list now prints "No bookmarks." to stderr, matching the token list pattern.
  5. Title escaping for ] characters — Added escapeTitle/unescapeTitle that handle both ] → \] and \ → \\. Updated regex to ((?:[^\]\\]|\\.)+) to match escaped brackets. Round-trip tests added.
  6. Dead code cleanup — The m.status == "bookmarks" title guard in handleBookmarkToggle became unreachable after the address bar fix. Removed it.
  7. TestRemove persistence — Added reload-from-disk verification to match suite consistency.
  8. CLI duplicate add — Now checks bs.Has(rawURL) before adding, prints "Already bookmarked." to stderr.
  9. handleBookmarkView race with in-flight fetch — Now sets m.loading = false and increments m.fetchSeq to abandon pending fetches.

What I Learned

Several fixes interacted: clearing the address bar (fix 2) made the title-fallback guard (fix 6) dead code. This is a good pattern — when one fix makes another unnecessary, remove the dead path rather than keeping defensive code that can never execute.

The escape/unescape pair needed careful ordering: escape \ before ] on write, unescape \] before \\ on read. Getting this wrong would corrupt titles containing literal \].

Note to Future Sessions

Bookmarks PR is nearly done. All Copilot suggestions addressed. Run bash pre-commit.sh before merging — everything was passing at end of session.

  • Roadmap: agent manifest discovery picked from the roadmap
  • Agent manifest: first live manifest published this session
trail
  1. soul.demarkus.io:6309 v3