~bigbes/sr-ht-dolt · parade

main · last commit 6 hours ago · ti41arbu

← Back to the parade

sr-ht-dolt-b08 Memory view: surface bd memories kept in the config table Past Stand

status: closed P2 feature
bd reopen sr-ht-dolt-b08
Created byEugene Blikh
Ownerbigbes@gmail.com
Created2026-08-10T11:01:48Z
Updated2026-08-13T05:53:37Z
Closed2026-08-13T05:53:37Z
Description
`bd remember` stores agent memories in the beads `config` table as ordinary
key/value rows: the key is `kv.memory.<slug>`, the value is the memory text.
Today they are reachable only through the generic table browser, mixed in with
the tracker's tuning knobs (`compact_*`, `issue_prefix`, ...), and every memory
is squeezed into a single table cell — which is unreadable for the multi-line
handoff notes that make up most of them.

Give them their own view, registered the same way Beads and Milestones are: a
separate `View` implementation whose tab appears next to them for any beads DB.
Design
Shape it on web/milestones.go, which is the smallest existing companion view:

- `web/memory.go`: `memoryView` registered from `init()` via `RegisterView`.
  `Name() == "memory"`, `Label() == "Memory"`, `Template() == "memory.html"`.
- `Applies`: the beads fingerprint (reuse `(&beadsView{}).Applies`, as
  milestones does) plus a `config` table carrying `key` and `value` columns.
  `Applies` only sees table shapes, never rows, so a beads DB with no memories
  still gets the tab and renders an empty state — same contract milestones has.
- `Build`: read `config` through `readRowsOptional`, keep rows whose key has the
  `kv.memory.` prefix, strip it for the display slug, sort by slug. Optional
  `?q=` substring filter over slug + text, and `?key=<slug>` for a single-memory
  detail, both parsed from the query values Build already receives.
- Values are stored as written, so they carry both real newlines and literal
  `\n` two-character escapes (agents type them into shell strings). Normalise
  both into paragraphs before rendering rather than dumping one blob.
- `web/templates/memory.html`: same flat todo.sr.ht idiom and inlined
  `<style>` block as milestones.html, with the `viewtabs` partial and
  `"Current" "memory"`.
- Tests next to `web/milestones_test.go`: fingerprint accept/reject, prefix
  filtering (a `compact_batch_size` row must not show up), escape handling,
  filter and detail modes, empty state.
Acceptance criteria
A beads DB shows a Memory tab beside Beads and Milestones; it lists every kv.memory.* config row as a readable, multi-paragraph entry keyed by its slug; non-memory config rows never appear; a DB with no memories renders an empty state instead of a broken tab.
Notes
Owns the revision walk (docs/DESIGN.views.md ch.2.1) now that browse.TableHash exists (97e0f8a): add TableHash to web/deps.go BrowseSession, walk the log newest-first skipping commits whose config table hash is unchanged, cap at 500 commits, render 'older than the last 500 commits' when a key does not resolve.
The 'ago' func landed in 6459298 with chrome's unit ladder: it says '2 months ago' where ch.2.2's mockup wants 'written 71 days ago'. For judging staleness days are the informative unit, so this view needs a day-resolution spelling of its own rather than a change to 'ago' (which is shared with the freshness line).

Depends on

  • sr-ht-dolt-44n.2 — Freshness line in the beads/milestones/memory header blocks closed
  • sr-ht-dolt-44n — Beads views, round two: stream, memory, freshness, cross-database parent-child closed
  • sr-ht-dolt-44n.3 — browse: TableHash and the memory revision walk blocks closed

Depended on by

  • sr-ht-dolt-0qf.8 — mcpsrv: list_memories over the shared memory projection blocks

Prerequisite chain — everything this waits on, transitively

  • sr-ht-dolt-44n.2 — Freshness line in the beads/milestones/memory header blocks closed
  • sr-ht-dolt-44n — Beads views, round two: stream, memory, freshness, cross-database parent-child closed
  • sr-ht-dolt-44n.3 — browse: TableHash and the memory revision walk blocks closed

No comments.

Close reason

Landed in 231b776: beads.BuildMemories with the bounded revision walk, the memory View after Milestones, agoDays for day-resolution staleness, stale? at 60 days. The walk was proven to skip rather than read (reads recorded at three refs out of five commits; 501 untouched commits cost one read). Real-data smoke: sourcehut-artifacts 9 memories attributed to distinct commits in 16.5 ms. Follow-up 0190aab replaced the init-order trick with an explicit registration list in views.go.
  • Eugene Blikh created the issue · 2026-08-10T14:01:47Z
  • Eugene Blikh added under epic sr-ht-dolt-44n · 2026-08-12T23:12:48Z
  • Eugene Blikh added dependency on sr-ht-dolt-44n.3 · 2026-08-12T23:12:58Z
  • Eugene Blikh added dependency on sr-ht-dolt-44n.2 · 2026-08-12T23:12:59Z
  • Eugene Blikh updated notes to Owns the revision walk (docs/DESIGN.views.md ch.2.1) now that browse.TableHash exists (97e0f8a): add TableHash to web/deps.go BrowseSession (and mcpsrv/ports.go if that seam exists by then), walk the log newest-first skipping commits whose config table hash is unchanged, cap the walk at 500 commits, render 'older than the last 500 commits' when a key does not resolve. browse/ tests are stdlib style, not testify — new browse-side tests live in their own file if any are needed. · 2026-08-12T23:18:40Z
  • Eugene Blikh updated notes to Owns the revision walk (docs/DESIGN.views.md ch.2.1) now that browse.TableHash exists (97e0f8a): add TableHash to web/deps.go BrowseSession, walk the log newest-first skipping commits whose config table hash is unchanged, cap at 500 commits, render 'older than the last 500 commits' when a key does not resolve. The 'ago' func landed in 6459298 with chrome's unit ladder: it says '2 months ago' where ch.2.2's mockup wants 'written 71 days ago'. For judging staleness days are the informative unit, so this view needs a day-resolution spelling of its own rather than a change to 'ago' (which is shared with the freshness line). · 2026-08-13T08:28:17Z
  • Eugene Blikh sr-ht-dolt-0qf.8 now depends on this · 2026-08-13T08:46:42Z
  • Eugene Blikh closed the issue · 2026-08-13T08:53:37Z
    Landed in 231b776: beads.BuildMemories with the bounded revision walk, the memory View after Milestones, agoDays for day-resolution staleness, stale? at 60 days. The walk was proven to skip rather than read (reads recorded at three refs out of five commits; 501 untouched commits cost one read). Real-data smoke: sourcehut-artifacts 9 memories attributed to distinct commits in 16.5 ms. Follow-up 0190aab replaced the init-order trick with an explicit registration list in views.go.
Stored rows — what this pane was built from, as read
issues 1 row
id sr-ht-dolt-b08
content_hash 6314ccc71fe7047ad5a1bafc0067c236a442b3cb98c13b163cf596471ce52b2e
title Memory view: surface bd memories kept in the config table
description `bd remember` stores agent memories in the beads `config` table as ordinary key/value rows: the key is `kv.memory.<slug>`, the value is the memory text. Today they are reachable only through the generic table browser, mixed in with the tracker's tuning knobs (`compact_*`, `issue_prefix`, ...), and every memory is squeezed into a single table cell — which is unreadable for the multi-line handoff notes that make up most of them. Give them their own view, registered the same way Beads and Milestones are: a separate `View` implementation whose tab appears next to them for any beads DB.
design Shape it on web/milestones.go, which is the smallest existing companion view: - `web/memory.go`: `memoryView` registered from `init()` via `RegisterView`. `Name() == "memory"`, `Label() == "Memory"`, `Template() == "memory.html"`. - `Applies`: the beads fingerprint (reuse `(&beadsView{}).Applies`, as milestones does) plus a `config` table carrying `key` and `value` columns. `Applies` only sees table shapes, never rows, so a beads DB with no memories still gets the tab and renders an empty state — same contract milestones has. - `Build`: read `config` through `readRowsOptional`, keep rows whose key has the `kv.memory.` prefix, strip it for the display slug, sort by slug. Optional `?q=` substring filter over slug + text, and `?key=<slug>` for a single-memory detail, both parsed from the query values Build already receives. - Values are stored as written, so they carry both real newlines and literal `\n` two-character escapes (agents type them into shell strings). Normalise both into paragraphs before rendering rather than dumping one blob. - `web/templates/memory.html`: same flat todo.sr.ht idiom and inlined `<style>` block as milestones.html, with the `viewtabs` partial and `"Current" "memory"`. - Tests next to `web/milestones_test.go`: fingerprint accept/reject, prefix filtering (a `compact_batch_size` row must not show up), escape handling, filter and detail modes, empty state.
acceptance_criteria A beads DB shows a Memory tab beside Beads and Milestones; it lists every kv.memory.* config row as a readable, multi-paragraph entry keyed by its slug; non-memory config rows never appear; a DB with no memories renders an empty state instead of a broken tab.
notes Owns the revision walk (docs/DESIGN.views.md ch.2.1) now that browse.TableHash exists (97e0f8a): add TableHash to web/deps.go BrowseSession, walk the log newest-first skipping commits whose config table hash is unchanged, cap at 500 commits, render 'older than the last 500 commits' when a key does not resolve. The 'ago' func landed in 6459298 with chrome's unit ladder: it says '2 months ago' where ch.2.2's mockup wants 'written 71 days ago'. For judging staleness days are the informative unit, so this view needs a day-resolution spelling of its own rather than a change to 'ago' (which is shared with the freshness line).
status closed
priority 2
issue_type feature
assignee NULL
estimated_minutes NULL
created_at 2026-08-10T11:01:48Z
created_by Eugene Blikh
owner bigbes@gmail.com
updated_at 2026-08-13T05:53:37Z
closed_at 2026-08-13T05:53:37Z
closed_by_session
external_ref NULL
spec_id
compaction_level 0
compacted_at NULL
compacted_at_commit NULL
original_size NULL
sender
ephemeral 0
wisp_type
pinned 0
is_template 0
mol_type
work_type
source_system
metadata �{}
source_repo
close_reason Landed in 231b776: beads.BuildMemories with the bounded revision walk, the memory View after Milestones, agoDays for day-resolution staleness, stale? at 60 days. The walk was proven to skip rather than read (reads recorded at three refs out of five commits; 501 untouched commits cost one read). Real-data smoke: sourcehut-artifacts 9 memories attributed to distinct commits in 16.5 ms. Follow-up 0190aab replaced the init-order trick with an explicit registration list in views.go.
event_kind
actor
target
payload
await_type
await_id
timeout_ns 0
waiters
hook_bead
role_bead
agent_state
last_activity NULL
role_type
rig
due_at NULL
defer_until NULL
no_history 0
started_at NULL
is_blocked 0
dependencies 4 rows
id 159d7664-c9ff-5503-8242-3d7633189c2a
issue_id sr-ht-dolt-b08
type blocks
created_at 2026-08-12T23:12:59Z
created_by Eugene Blikh
metadata �{}
thread_id
depends_on_issue_id sr-ht-dolt-44n.2
depends_on_wisp_id NULL
depends_on_external NULL
id 1f5dd9d1-f671-59f1-a3df-1acb27bdf38b
issue_id sr-ht-dolt-b08
type parent-child
created_at 2026-08-12T23:12:48Z
created_by Eugene Blikh
metadata �{}
thread_id
depends_on_issue_id sr-ht-dolt-44n
depends_on_wisp_id NULL
depends_on_external NULL
id af40295d-d71d-5be8-bd2c-f43203cd220b
issue_id sr-ht-dolt-0qf.8
type blocks
created_at 2026-08-13T08:46:42Z
created_by Eugene Blikh
metadata �{}
thread_id
depends_on_issue_id sr-ht-dolt-b08
depends_on_wisp_id NULL
depends_on_external NULL
id bdc826cd-af62-5e04-aaa7-3e0e2a43f929
issue_id sr-ht-dolt-b08
type blocks
created_at 2026-08-12T23:12:58Z
created_by Eugene Blikh
metadata �{}
thread_id
depends_on_issue_id sr-ht-dolt-44n.3
depends_on_wisp_id NULL
depends_on_external NULL
events 4 rows
id 019feb55-f7ea-7a60-b82f-87ec2454dee2
issue_id sr-ht-dolt-b08
event_type created
actor Eugene Blikh
old_value
new_value
comment NULL
created_at 2026-08-10T14:01:47Z
id 019ff7a0-8706-7c9e-9c11-d2bb6d66b5b4
issue_id sr-ht-dolt-b08
event_type updated
actor Eugene Blikh
old_value {"id":"sr-ht-dolt-b08","title":"Memory view: surface bd memories kept in the config table","description":"`bd remember` stores agent memories in the beads `config` table as ordinary\nkey/value rows: the key is `kv.memory.\u003cslug\u003e`, the value is the memory text.\nToday they are reachable only through the generic table browser, mixed in with\nthe tracker's tuning knobs (`compact_*`, `issue_prefix`, ...), and every memory\nis squeezed into a single table cell — which is unreadable for the multi-line\nhandoff notes that make up most of them.\n\nGive them their own view, registered the same way Beads and Milestones are: a\nseparate `View` implementation whose tab appears next to them for any beads DB.\n","design":"Shape it on web/milestones.go, which is the smallest existing companion view:\n\n- `web/memory.go`: `memoryView` registered from `init()` via `RegisterView`.\n `Name() == \"memory\"`, `Label() == \"Memory\"`, `Template() == \"memory.html\"`.\n- `Applies`: the beads fingerprint (reuse `(\u0026beadsView{}).Applies`, as\n milestones does) plus a `config` table carrying `key` and `value` columns.\n `Applies` only sees table shapes, never rows, so a beads DB with no memories\n still gets the tab and renders an empty state — same contract milestones has.\n- `Build`: read `config` through `readRowsOptional`, keep rows whose key has the\n `kv.memory.` prefix, strip it for the display slug, sort by slug. Optional\n `?q=` substring filter over slug + text, and `?key=\u003cslug\u003e` for a single-memory\n detail, both parsed from the query values Build already receives.\n- Values are stored as written, so they carry both real newlines and literal\n `\\n` two-character escapes (agents type them into shell strings). Normalise\n both into paragraphs before rendering rather than dumping one blob.\n- `web/templates/memory.html`: same flat todo.sr.ht idiom and inlined\n `\u003cstyle\u003e` block as milestones.html, with the `viewtabs` partial and\n `\"Current\" \"memory\"`.\n- Tests next to `web/milestones_test.go`: fingerprint accept/reject, prefix\n filtering (a `compact_batch_size` row must not show up), escape handling,\n filter and detail modes, empty state.\n","acceptance_criteria":"A beads DB shows a Memory tab beside Beads and Milestones; it lists every kv.memory.* config row as a readable, multi-paragraph entry keyed by its slug; non-memory config rows never appear; a DB with no memories renders an empty state instead of a broken tab.","status":"open","priority":2,"issue_type":"feature","owner":"bigbes@gmail.com","created_at":"2026-08-10T11:01:48Z","created_by":"Eugene Blikh","updated_at":"2026-08-10T11:01:48Z"}
new_value {"notes":"Owns the revision walk (docs/DESIGN.views.md ch.2.1) now that browse.TableHash exists (97e0f8a): add TableHash to web/deps.go BrowseSession (and mcpsrv/ports.go if that seam exists by then), walk the log newest-first skipping commits whose config table hash is unchanged, cap the walk at 500 commits, render 'older than the last 500 commits' when a key does not resolve. browse/ tests are stdlib style, not testify — new browse-side tests live in their own file if any are needed."}
comment NULL
created_at 2026-08-12T23:18:40Z
id 019ff997-b643-7d00-a48f-7bca66a19632
issue_id sr-ht-dolt-b08
event_type updated
actor Eugene Blikh
old_value {"id":"sr-ht-dolt-b08","title":"Memory view: surface bd memories kept in the config table","description":"`bd remember` stores agent memories in the beads `config` table as ordinary\nkey/value rows: the key is `kv.memory.\u003cslug\u003e`, the value is the memory text.\nToday they are reachable only through the generic table browser, mixed in with\nthe tracker's tuning knobs (`compact_*`, `issue_prefix`, ...), and every memory\nis squeezed into a single table cell — which is unreadable for the multi-line\nhandoff notes that make up most of them.\n\nGive them their own view, registered the same way Beads and Milestones are: a\nseparate `View` implementation whose tab appears next to them for any beads DB.\n","design":"Shape it on web/milestones.go, which is the smallest existing companion view:\n\n- `web/memory.go`: `memoryView` registered from `init()` via `RegisterView`.\n `Name() == \"memory\"`, `Label() == \"Memory\"`, `Template() == \"memory.html\"`.\n- `Applies`: the beads fingerprint (reuse `(\u0026beadsView{}).Applies`, as\n milestones does) plus a `config` table carrying `key` and `value` columns.\n `Applies` only sees table shapes, never rows, so a beads DB with no memories\n still gets the tab and renders an empty state — same contract milestones has.\n- `Build`: read `config` through `readRowsOptional`, keep rows whose key has the\n `kv.memory.` prefix, strip it for the display slug, sort by slug. Optional\n `?q=` substring filter over slug + text, and `?key=\u003cslug\u003e` for a single-memory\n detail, both parsed from the query values Build already receives.\n- Values are stored as written, so they carry both real newlines and literal\n `\\n` two-character escapes (agents type them into shell strings). Normalise\n both into paragraphs before rendering rather than dumping one blob.\n- `web/templates/memory.html`: same flat todo.sr.ht idiom and inlined\n `\u003cstyle\u003e` block as milestones.html, with the `viewtabs` partial and\n `\"Current\" \"memory\"`.\n- Tests next to `web/milestones_test.go`: fingerprint accept/reject, prefix\n filtering (a `compact_batch_size` row must not show up), escape handling,\n filter and detail modes, empty state.\n","acceptance_criteria":"A beads DB shows a Memory tab beside Beads and Milestones; it lists every kv.memory.* config row as a readable, multi-paragraph entry keyed by its slug; non-memory config rows never appear; a DB with no memories renders an empty state instead of a broken tab.","notes":"Owns the revision walk (docs/DESIGN.views.md ch.2.1) now that browse.TableHash exists (97e0f8a): add TableHash to web/deps.go BrowseSession (and mcpsrv/ports.go if that seam exists by then), walk the log newest-first skipping commits whose config table hash is unchanged, cap the walk at 500 commits, render 'older than the last 500 commits' when a key does not resolve. browse/ tests are stdlib style, not testify — new browse-side tests live in their own file if any are needed.","status":"open","priority":2,"issue_type":"feature","owner":"bigbes@gmail.com","created_at":"2026-08-10T11:01:48Z","created_by":"Eugene Blikh","updated_at":"2026-08-12T20:18:41Z"}
new_value {"notes":"Owns the revision walk (docs/DESIGN.views.md ch.2.1) now that browse.TableHash exists (97e0f8a): add TableHash to web/deps.go BrowseSession, walk the log newest-first skipping commits whose config table hash is unchanged, cap at 500 commits, render 'older than the last 500 commits' when a key does not resolve.\nThe 'ago' func landed in 6459298 with chrome's unit ladder: it says '2 months ago' where ch.2.2's mockup wants 'written 71 days ago'. For judging staleness days are the informative unit, so this view needs a day-resolution spelling of its own rather than a change to 'ago' (which is shared with the freshness line)."}
comment NULL
created_at 2026-08-13T08:28:17Z
id 019ff9ae-e7f9-7687-bead-7c487abc0047
issue_id sr-ht-dolt-b08
event_type closed
actor Eugene Blikh
old_value
new_value Landed in 231b776: beads.BuildMemories with the bounded revision walk, the memory View after Milestones, agoDays for day-resolution staleness, stale? at 60 days. The walk was proven to skip rather than read (reads recorded at three refs out of five commits; 501 untouched commits cost one read). Real-data smoke: sourcehut-artifacts 9 memories attributed to distinct commits in 16.5 ms. Follow-up 0190aab replaced the init-order trick with an explicit registration list in views.go.
comment NULL
created_at 2026-08-13T08:53:37Z