- RFC: markl.Id format specification (referenced by hyphence RFC 0001)
- explore using sigil as continuation operator in v14 fixed stream index
- explore using content offsets instead of signatures in v14 fixed stream index
- run performance tests on packfiles
- run performance tests on v14 fixed stream index
- verify encryption support in packfiles
- add support for n / m sapir recovery for piv encryption
- Remove the
strings.Contains(typeString, "/")fallback intext_parser2.readType(india/object_metadata_fmt_hyphence/text_parser2.go). Old checked-out zettel files used! <path>for blob references; new format uses@ <path>. Once all workspaces have been re-checked-out, this shim can be deleted.
Error reporting for all 4 bugs landed in 420a114d0 (rich error types,
-continue-on-error flag, error logfile). Bug 1 root cause fixed separately.
-
Bug 1 — cross-pubkey merge crash. Fixed:
importLeafnow skipsMergeCheckedOutwhenparentNegotiatoris nil (always for imports). -
Bug 2 — batch dedup drops distinct objects. Resolved: TAI-exclusion in dedup key is intentional (same content = same object regardless of timestamp).
ErrDedupedreporting is the correct behavior. -
Bug 3 — blobless type definitions silently dropped. Type-genre objects with null blob/pubkey/sig enter
importLeaf, get signed byFinalizeAndSignOverwrite, but produce no stored output. Now detected early asErrBloblessTypeSkipped. Root-cause handling subsumed by two-phase import (see below). -
Bug 4 — ObjectId+TAI collisions (10,731 in production). Different objects share ObjectId+TAI from sub-second writes in source repo. Now detected as
ErrObjectIdTaiCollisionwhen blob digests differ. Root-cause handling subsumed by two-phase import (see below).
- Add a flag or config option to
der importto exclude tags matching a regex pattern. Example: a past migration misinterpreted repo pubkey/sig metadata as tags, producing tags like-repo-public_key-v1-gayur0wh5y...toml-type-v1on 19 type objects (e.g.!aax,!pdf,!md-snippet). These should have been omitted during import. A--exclude-tagsregex filter would prevent similar data pollution. The MCP type index currently works around this by skipping tags starting with-repointype_index.go.
- FDR: Redesign
der importas a two-phase pipeline: (1) plan+validate the inventory list (topographic ordering, blobless type detection, TAI collision detection, dedup summary), then (2) review+commit. Topographic processing ensures types are imported before objects that reference them. The planning phase surfaces all issues (bugs 2-4) upfront instead of mid-stream.
- FDR: replace filesystem diff3 merge with semantic diffing using the type system. Current merge in
MakeMergedTransactedchecks out objects to temp files and runs diff3 on text-rendered representations. This requires filesystem checkouts even for objects with no workspace presence, and conflates two checkout concepts: workspace (PWD) and temp (merge resolution). Semantic diffing would operate on the in-memory object model directly, eliminating the filesystem dependency.store_fsandenv_workspaceneed types to discriminate between workspace and temp checkouts until this lands.
-
stream_index/page_reader_probe.go:86panics withunexpected EOFwhen a probe page file is shorter than the cursor'sContentLength. Should return an error instead of panicking sofsckcan report it and continue.
-
go mod tidyfails resolvingcode.linenisgreat.com/dodder/go/src/bravo/ohioandcode.linenisgreat.com/dodder/go/src/bravo/ui— fixed by updating chrest upstream
- WASM interface for repo/domain ops (blob store, config) — store_fs currently gets these from env_repo.Env
- WASM-compatible replacement for
exec.CommandinRunMergeTool(store_fs/merge.go) — interactive merge tool invocation - WASM-compatible replacement for
files.OpenFilesinOpenFiles.Run(store_fs/open_files.go) — opens files in user's editor - WASM-compatible replacement for
os.Stdin/Stdout/StderrinRunMergeTool(store_fs/merge.go) — terminal I/O for interactive merge
- FDR: evaluate making
delta/objectsmetadata fields private after full gob removal - Evaluate removing
hotel/log_remote_inventory_listsentirely — verdict: keep for now. Actively used bytango/remote_http/{client,server_repo}for deduplicating inventory list transfers. Thev0.go:20TODO ("not really used") is stale; it IS used but only by those 2 modules. Removal would require either dropping dedup (accepting duplicate transfers) or inlining the logic. Low priority — gob serialization in this package is a better target for eventual cleanup.
- add instruction: ALWAYS use
just test*recipes; NEVER run bats/go-test/fixture-generation directly - add instruction: BATS fixture tests use
get_fixture_type_sigfor signatures; fresh-store tests use--regexp - add instruction: NEVER call
errors.Iswhen err might be EOF; useerrors.IsEOF()guard first - add instruction: when bumping store version, do NOT remove old version's codec/gob support
- add instruction: document "lock" dual meaning — content locks (metadata) vs filesystem mutex (LockSmith)
- add instruction: trailing whitespace matters in dodder output; use
xxdto debug invisible mismatches
- Wire blob-stores list from konfig into BlobStoreEnv ordering (replace alphabetical sort in setupStores)
- FDR: Unify Tags and References into single ContainedObjects collection
- Use doddish.Scanner to distinguish tags from references in OpTagSeparator parser instead of strings.Contains("/") heuristic
-
addMarklIdAbbreviatedinobject_metadata_box_builderabbreviates the fullmarkl.Id.String()(which includes the format HRP, e.g.,blake2b256-...). The format ID portion should not be abbreviated — only the digest payload after the HRP should go through the tridex. Render aspurposeId@formatId-abbreviatedDigest.
- Extend
store_abbr.InMemoryIndexto support ad-hoc persistence (write/read to a path without requiringenv_repo.Env). In-memory is sufficient for the import plan; persistence would allow caching abbreviation indexes across runs.
- Incorporate object references into the import_plan dependency graph, not just type references. References can point to any object or blob (blob references may not yet be implemented). Currently only type→dependent edges are sorted; objects referencing other objects are not ordered.
- refactor env_ui into lib and add huh / lipgloss to it
- Implement
BlobForeignDigestAdderfor inventory archive stores. Idea: use symlinks in the embedded loose blob directory pointing to packed blob entries, soHasBlob(foreignDigest)resolves via the loose store fallback. Requires solving the read path (symlink target is a packfile, not a single blob file). Seedocs/plans/2026-02-23-sync-cross-hash-design.md.
- FDR: purse-first framework integration for madder MCP server
- Once purse-first install_mcp branch lands: add install-mcp command to madder using
app.InstallMCP()from go-mcp - purse-first: support HTTP/SSE MCP servers in
App.InstallMCP()(currently stdio-only)
- Fix query executor to only consult workspace store when
.(CWD) sigil is in the query — currentlybuild_state.build()passes all values toworkspaceStore.GetObjectIdsForString()even for repo-only sigils like:z. The MCP bridge works around this withIgnoreWorkspace: truebut the executor itself should be fixed.
- Rename
store_fstoworkspace_fs - Rename
store_browsertoworkspace_browser - Add
workspace_agentfor MCPs
- Explore exposing a
dodder://instructionsordodder://agentsresource that provides context about the box format grammar, resource hierarchy, and query patterns. Could be served from a CLAUDE.md or AGENTS.md file in the repo. Consider whether this should exist at the server level (currentInstructionsfield), as a static resource, or at each level of the resource hierarchy (e.g.dodder://types/instructions).
- FDR: Write an RFC for the box format used by dodder's output. The format is a compact one-line-per-object representation:
[<type> <@blob-id> <object-id>] <description> %<tag>.... Currently the grammar is implicit in the formatter code (box_format.BoxTransacted). An RFC would make it consumable by external tools and agents. Include variants: with/without time prefix, with/without color, archive mode.
-
dodder_queryMCP tool returns MCP protocol validation errors when the query matches a single object (e.g.["!md-snippet"]). The error isinvalid_uniononcontent[0]— the content block doesn't match any of the expected MCP types (text, image, audio, resource_link, resource). Reproduce: calldodder_type_queryordodder_querywith a query that returns exactly one result, or calldodder_querywith["!md-snippet"]. ThemakeBridgeHandlerinserver.gowraps output inprotocol.TextContentV1()which should be correct — investigate whether the JSON output for single objects is malformed or whether the issue is in the go-mcp library's content block serialization.
-
findWorkspaceFilewalks up from BATS temp dir and finds.dodder-workspacein the worktree whenTMPDIRpoints into the worktree (e.g.,.tmp/), causingstatusto succeed when the test expects failure (no workspace in fixture). Fix: setTMPDIR="/tmp"in justfile BATS recipes
- FDR: MCP tools (
dodder_query,dodder_show) return newline-delimited JSON. Agents can't parse this natively — they split lines and parse each one, or resort to python. Switch to streaming JSON arrays using ajson.Encoderpattern (liketango/remote_http) that emits[, per-object JSON,,,]without buffering the full result set into memory. This would make tool output directly usable as structured data.
-
dodder_showwith a type ID like!mdreturns ALL objects of that type (potentially 100K+ chars), same problem thatdodder_queryhad before thelimitparameter was added. Options: (1) addlimittododder_show, (2) makedodder_showonly return the single object matching the exact ID (using:t/:e/:zgenre sigils internally), or (3) split into separate "show one object" vs "list matching objects" tools with clearer semantics.
- Add
dodder://types/<id>/blob/formatsendpoint mirroring the object blob format discovery. Types have their own type (e.g.!toml-type-v1) which defines formatters. Currently onlydodder://objects/<id>/blob/formatsis implemented (intango/mcp_dodder/resources.go). ThereadTypeBlobFormattedhandler already callsformat-blobfor rendering but has no corresponding format listing endpoint.
- The
dodder_showtool only exposes 4 formats in its enum:["log", "text", "json", "organize"]. The CLI supports 60+ formats (seesierra/local_working_copy/format.goformattersmap). Consider making the enum dynamic or expanding it to include commonly useful formats likebox,json-with-blob_string,tags,description,object-id. Thedodder_querytool already includesboxandjson-with-blob_string.
-
formatErrorDetailanddescribeErrorintango/mcp_dodder/server.gowere added during development for debugging multi-error unwrapping andErrorTreestack frames. Review whether these are still needed or if the standard error formatting is sufficient. They add ~50 lines of error inspection code.
-
dagnabit -dry-runreports 5 packages in wrong tiers (as of 2026-03-15):charlie/filesystem_ops→_/,charlie/zettel_id_log→delta/,charlie/zettel_id_provider→echo/,romeo/import_plan→india/,lib/charlie/fd→lib/delta/fd. Rundagnabit(no flags) from thego/directory to auto-move, or usejust codemod-go-move_package <src> <dst>individually.
Completed in this branch: dead code removal (server_repo.go, commented-out
functions, unreachable routes), stub standardization to
panic(errors.Err501NotImplemented), blob digest validation (client sends
@ <digest> in hyphence metadata, server verifies via BlobTeeWriter), HTTP
trailer response body signing (X-Dodder-Repo-Sig), repool warning sweep.
Remaining:
- BATS integration test for digest mismatch rejection (push with tampered
blob, assert server rejects with digest error). See
server_working_copy.go:writeInventoryListLocalWorkingCopyfor the validation path. - TOFU prompt for unknown public keys (
round_tripper_wrapped_signer.go:77) - extract signing into agnostic middleware (
round_tripper_wrapped_signer.go:27) - context-based error handling: replace error returns with context cancellation in server.go (5 TODOs at lines 44, 60, 163, 330, 357)
- streaming performance: avoid buffering inventory lists in server.go (lines 758, 789, 792, 851)
- local/remote version negotiation (
client.go:215) - server_mcp.go repool false positive: restructure goto/ParseTypedBlob control flow so analyzer can verify repool coverage
- add
checkto root justfile default recipe (default: build check test) once all warnings are resolved - fix 20 remaining repool "not called on all paths" warnings (markl/hash.go, papa/store, sierra/local_working_copy/format_type.go, oscar/store_config/persist.go, india/stream_index*, india/sku_fmt, tango/remote_http/server_mcp.go)
- fix 2 unreachable code warnings in go vet (bravo/ids/main.go, lib/delta/files/chflags_linux.go, lib/delta/heap/private.go)
- fix 3 seqerror warnings in oscar/store_config (accessors.go, tag.go)
- upgrade Go from 1.25.7 to 1.25.8 to resolve 2 stdlib vulnerabilities (GO-2026-4602, GO-2026-4601)
- feat: user-config-wide repo definition that exists outside of repos (needed for
/<repo-id>remote selection) - split
initintoinit(XDG) andinit-cwd; remove-repo_idfrom init entirely