You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-on design ticket from #5678 — its decomposition sketch names this as a separate design, and the parent's acceptance requires these tickets to be filed and linked. Filed in the 2026-11-04 gap pass (WS-F) so the design work exists and can be prioritised on its own merits; implementation timing is a separate decision, possibly months out.
What this design must settle
Web clipping, quick capture/inbox, tags vs folders vs links, full-text and semantic search, and templates for the knowledge layer.
Context from the parent
The parent is a design-to-make-designs: a competitor feature-matrix programme over the #2048 zettelkasten layer whose deliverable is one follow-on design per cluster and per importer, filed and linked on the parent. The parent issue carries the surrounding decisions this ticket must not re-decide; where this ticket's answer would change a parent decision, record that explicitly rather than silently forking it.
Decision record expected
Close this design with a recorded decision (on this issue or in a doc/ record linked from it): the chosen shape, the alternatives rejected and why, and the invariants implementation must hold. If the design splits further, file the splits and link them here rather than growing this issue.
Relations
Parent: #5678. Programme: epic #2056. Filed by WS-F (2026-11-04 ID design gap & expansion pass).
No blocker, no Drew decision needed to start. Implementation timing being a separate, possibly-months-out decision gates implementation, not this design. The only remaining work is the design itself, so the follow-up enqueued in this pass is the decision-record task for this same issue (standard triage dedupe key, enqueued after this triage completes).
Disposition: triaged; design work proceeds as the follow-up task named in the addendum. Issue #5841 stays open for it.
Decision record — capture & organisation cluster (issue #5841)
Status: DECIDED (design only; implementation timing is a separate decision, per the issue body) Decided by: queue worker (repo-worker-code), lane code-o, task 10497, 2026-11-05 Context inherited, not re-decided: parent issue #5678 (feature-matrix programme over the #2048 zettelkasten layer), programme epic issue #2056, friendly-name references (issue #2047 / #2048), and the read-authority ruling recorded on issue #5678: default public read; resolution order object → user default → server config → public. No decision below changes a parent decision; the one place a change was considered is called out explicitly in §7.
1. Web clipping — a clip is a first-class object with provenance
Chosen shape. Clipping creates a first-class ID object, not a bookmark and not a file blob. A clip object carries: (a) the source URL, (b) an extracted readable-content snapshot (title, text, selected media references), (c) provenance — clipped-at timestamp, clipping identity, source content hash — recorded at capture and immutable afterwards, and (d) the clipper's annotations as separate linked objects, never edits to the snapshot. Re-clipping the same URL surfaces the existing clip (dedupe by URL + content hash) and offers "add new snapshot version" instead of silently duplicating. Fidelity is stated honestly: a clip stores only content the clipper could actually access; paywalled or script-gated pages clip as metadata + whatever was legitimately visible, and the object says so.
Rejected. Bookmark-only (rejected: link rot destroys the corpus; search and AI-over-notes have nothing to work on). Full-page archive as an opaque file attachment (rejected: not searchable, not linkable at passage level, duplicates the attachments cluster #5844's job). Browser-extension-only capture (rejected: capture is an object-model/API capability; an extension, share sheet, or chat command are interchangeable clients of it).
2. Quick capture / inbox — the inbox is a view, not a container
Chosen shape. Capture is a single action with no required fields beyond the content itself (text, link, file, or voice note handed to transcription later): it creates a minimal object stamped with capture time and capture channel. The inbox is a system view — a query over objects in the untriaged state — not a folder, list, or special object that contains things. Triage is progressive enrichment of the object in place (title, links, tags, template application); triaged objects simply leave the view. Nothing is ever "moved out of" the inbox, so an object can be re-surfaced by clearing its triage state. Inbox ageing is surfaced (oldest untriaged first by default); inbox-zero is a user habit, not a system invariant.
Rejected. Inbox as a special folder/container (rejected: creates move semantics and a second home for an object, contradicting §3's no-exclusive-containment rule). Capture-into-daily-note only (rejected: couples capture to the content-model cluster's daily-notes decision on issue #5839 and buries standalone captures inside another object where they cannot be linked, searched, or permissioned individually).
3. Organisation — links primary, tags as facets, no exclusive containment
Chosen shape. Three mechanisms, each doing one job:
Links (including backlinks and friendly-name references) are the primary organisation. This is the zettelkasten model of issue id: design: Zettelkasten layer — multiplayer docs/wiki on ID #2048: an object's place is the web of what it references and what references it.
Tags are flat, multi-valued facet metadata for filtering and saved views. A tag is itself a first-class object, so it can carry a description, be renamed globally, and be merged — a merge preserves the losing tag as an alias that still resolves.
Collections are saved views (a stored query over links/tags/state), not containers. "Folders" exist only as this view idiom for users who think hierarchically; membership is computed, never exclusive, and deleting a collection deletes no content.
Rejected. Folders as primary containment (rejected: single-parent hierarchy forces one true place per object, fights the graph model, and every mature tool in the parent matrix that started folder-first bolted on tags/links later). Nested tag hierarchies in v1 (rejected: hierarchy is expressible via collections and tag-object links without a second tree mechanism; can be revisited with evidence). Typed-folder taxonomies decided per workspace (rejected: no workspace model is decided yet; organisation must work for a single user's corpus first).
4. Search — full-text is canonical, semantic is a ranking layer, authority filters first
Chosen shape. Two layers over one corpus:
Full-text index over object text, extracted clip text, and tag names — the canonical, exact-recall layer, with operators for tag, link neighbourhood, object type, and capture/triage state.
Semantic (embedding) index as an additive ranking/suggestion layer only — it may reorder and expand full-text results and power "related notes", but it is never the store of truth and never the only way to reach an object.
Both indices are derived and rebuildable: source objects are canonical, an index can be deleted and regenerated without data loss, and every result carries its object reference so citations resolve to the object, not the index. Read-authority is enforced before ranking and before snippet generation: a result a reader may not read under the §inherited resolution order does not appear, contribute a snippet, or leak through counts/facets — for semantic results exactly as for full-text. Which embedding provider/model serves the semantic layer is deliberately not decided here; it is an interface this design hands to the AI-over-notes cluster (issue #5842).
Rejected. Semantic-only search (rejected: poor exact recall, opaque failures, cost per query, and the worst leakage surface). Full-text-only forever (rejected: relatedness/discovery is a core zettelkasten behaviour; the layer is additive so this costs the canonical layer nothing). Per-user siloed indices as the authority mechanism (rejected: enforcement belongs in the query path against the resolution order, so one shared index stays consistent with grants changing over time).
5. Templates — ordinary objects, copied on use, no live inheritance
Chosen shape. A template is an ordinary ID object flagged as a template. Instantiating copies its content/structure into a new object that carries an immutable provenance link to the template (and template version) it came from. Named placeholders in the template become prompted/filled fields at instantiation. A template gallery is just a collection (§3) of template objects.
Rejected. Live-inheriting templates, where editing a template mutates its instances (rejected: surprising mutation of other people's multiplayer objects, unresolvable edit conflicts, and no competitor in the parent matrix does this by default). Script-bearing templates in this design (deferred, not rejected outright: automation belongs to the extensibility cluster, issue #5843; a template's placeholders must stay declarative so that door stays open).
6. Invariants an implementation must hold
Capture is one action; no metadata is required beyond the content itself.
The inbox is a view over triage state; no object is ever contained by it.
No exclusive containment anywhere in the cluster: links organise, tags facet, collections compute membership.
Clip snapshots and template provenance are immutable once written; annotations and instances are separate objects that link back.
Search indices are derived and rebuildable; deleting an index loses no user content.
Read-authority filtering precedes ranking, snippets, facets/counts, and any AI use of search results — resolution order object → user default → server config → public, unchanged.
Tags merge without breaking references: the merged-away tag remains as a resolving alias.
Nothing above re-decides issue #5678: the read-authority ruling is inherited verbatim (invariant 6), the object model is issue #2048's, and importer/exporter design stays with the parent's importer tickets. One considered-and-rejected change is recorded explicitly, as the issue requires: making clipped content private by default was considered (clips can capture sensitive pages) and not adopted — it would silently fork the ruled public-read default; instead a clip inherits the normal resolution order, and the clipper may set the object's own read setting at capture time, which the resolution order already honours first.
8. Splits and follow-ups
No further design splits: the cluster is settled as one record. Implementation tickets are not filed by this task — the issue body states implementation timing is a separate decision, possibly months out; when that decision is taken, implementation splits should be cut per section (§1–§5) and linked here. Open interfaces handed to sibling clusters: embedding provider/model → issue #5842 (AI-over-notes); script-bearing templates/automation → issue #5843 (extensibility); clip attachment/media storage details → issue #5844 (attachments & media); daily-note capture targets, if any → issue #5839 (content model).
Agent: queue worker (repo-worker-code), lane code-o
Session / ID: task 10497
Task: decision record for the capture & organisation cluster posted on issue id: design: capture & organisation cluster (from #5678) #5841 (comment 6658702519): clips as first-class objects with immutable provenance; inbox as a view over triage state, not a container; links primary / tags as facets / collections as saved views with no exclusive containment; full-text search canonical with semantic as a ranking-only layer, read-authority filtering before ranking/snippets; templates as ordinary objects copied on instantiation with no live inheritance. Nine implementation invariants stated; parent issue id: design: Knowledge layer feature program — competitor feature matrix, import/export, read-authority #5678's read-authority ruling inherited verbatim, with the one considered change (private-by-default clips) recorded as considered-and-rejected in §7. No implementation code, per the issue's stated timing; implementation splits are cut per-section when the timing decision is taken.
Activity
developing-today commentedon Nov 5, 2026
CODE-1524
dezren39 commentedon Nov 5, 2026
🤖 Agent note · done (triage)
Triage findings (verified fresh 2026-11-05):
Disposition: triaged; design work proceeds as the follow-up task named in the addendum. Issue #5841 stays open for it.
dezren39 commentedon Nov 5, 2026
🤖 Agent note · addendum to task 10244 triage
dezren39 commentedon Nov 5, 2026
🤖 Agent note · picked up
dezren39 commentedon Nov 5, 2026
Decision record — capture & organisation cluster (issue #5841)
Status: DECIDED (design only; implementation timing is a separate decision, per the issue body)
Decided by: queue worker (repo-worker-code), lane code-o, task 10497, 2026-11-05
Context inherited, not re-decided: parent issue #5678 (feature-matrix programme over the #2048 zettelkasten layer), programme epic issue #2056, friendly-name references (issue #2047 / #2048), and the read-authority ruling recorded on issue #5678: default public read; resolution order object → user default → server config → public. No decision below changes a parent decision; the one place a change was considered is called out explicitly in §7.
1. Web clipping — a clip is a first-class object with provenance
Chosen shape. Clipping creates a first-class ID object, not a bookmark and not a file blob. A clip object carries: (a) the source URL, (b) an extracted readable-content snapshot (title, text, selected media references), (c) provenance — clipped-at timestamp, clipping identity, source content hash — recorded at capture and immutable afterwards, and (d) the clipper's annotations as separate linked objects, never edits to the snapshot. Re-clipping the same URL surfaces the existing clip (dedupe by URL + content hash) and offers "add new snapshot version" instead of silently duplicating. Fidelity is stated honestly: a clip stores only content the clipper could actually access; paywalled or script-gated pages clip as metadata + whatever was legitimately visible, and the object says so.
Rejected. Bookmark-only (rejected: link rot destroys the corpus; search and AI-over-notes have nothing to work on). Full-page archive as an opaque file attachment (rejected: not searchable, not linkable at passage level, duplicates the attachments cluster #5844's job). Browser-extension-only capture (rejected: capture is an object-model/API capability; an extension, share sheet, or chat command are interchangeable clients of it).
2. Quick capture / inbox — the inbox is a view, not a container
Chosen shape. Capture is a single action with no required fields beyond the content itself (text, link, file, or voice note handed to transcription later): it creates a minimal object stamped with capture time and capture channel. The inbox is a system view — a query over objects in the untriaged state — not a folder, list, or special object that contains things. Triage is progressive enrichment of the object in place (title, links, tags, template application); triaged objects simply leave the view. Nothing is ever "moved out of" the inbox, so an object can be re-surfaced by clearing its triage state. Inbox ageing is surfaced (oldest untriaged first by default); inbox-zero is a user habit, not a system invariant.
Rejected. Inbox as a special folder/container (rejected: creates move semantics and a second home for an object, contradicting §3's no-exclusive-containment rule). Capture-into-daily-note only (rejected: couples capture to the content-model cluster's daily-notes decision on issue #5839 and buries standalone captures inside another object where they cannot be linked, searched, or permissioned individually).
3. Organisation — links primary, tags as facets, no exclusive containment
Chosen shape. Three mechanisms, each doing one job:
Rejected. Folders as primary containment (rejected: single-parent hierarchy forces one true place per object, fights the graph model, and every mature tool in the parent matrix that started folder-first bolted on tags/links later). Nested tag hierarchies in v1 (rejected: hierarchy is expressible via collections and tag-object links without a second tree mechanism; can be revisited with evidence). Typed-folder taxonomies decided per workspace (rejected: no workspace model is decided yet; organisation must work for a single user's corpus first).
4. Search — full-text is canonical, semantic is a ranking layer, authority filters first
Chosen shape. Two layers over one corpus:
Both indices are derived and rebuildable: source objects are canonical, an index can be deleted and regenerated without data loss, and every result carries its object reference so citations resolve to the object, not the index. Read-authority is enforced before ranking and before snippet generation: a result a reader may not read under the §inherited resolution order does not appear, contribute a snippet, or leak through counts/facets — for semantic results exactly as for full-text. Which embedding provider/model serves the semantic layer is deliberately not decided here; it is an interface this design hands to the AI-over-notes cluster (issue #5842).
Rejected. Semantic-only search (rejected: poor exact recall, opaque failures, cost per query, and the worst leakage surface). Full-text-only forever (rejected: relatedness/discovery is a core zettelkasten behaviour; the layer is additive so this costs the canonical layer nothing). Per-user siloed indices as the authority mechanism (rejected: enforcement belongs in the query path against the resolution order, so one shared index stays consistent with grants changing over time).
5. Templates — ordinary objects, copied on use, no live inheritance
Chosen shape. A template is an ordinary ID object flagged as a template. Instantiating copies its content/structure into a new object that carries an immutable provenance link to the template (and template version) it came from. Named placeholders in the template become prompted/filled fields at instantiation. A template gallery is just a collection (§3) of template objects.
Rejected. Live-inheriting templates, where editing a template mutates its instances (rejected: surprising mutation of other people's multiplayer objects, unresolvable edit conflicts, and no competitor in the parent matrix does this by default). Script-bearing templates in this design (deferred, not rejected outright: automation belongs to the extensibility cluster, issue #5843; a template's placeholders must stay declarative so that door stays open).
6. Invariants an implementation must hold
7. Parent-decision compliance
Nothing above re-decides issue #5678: the read-authority ruling is inherited verbatim (invariant 6), the object model is issue #2048's, and importer/exporter design stays with the parent's importer tickets. One considered-and-rejected change is recorded explicitly, as the issue requires: making clipped content private by default was considered (clips can capture sensitive pages) and not adopted — it would silently fork the ruled public-read default; instead a clip inherits the normal resolution order, and the clipper may set the object's own read setting at capture time, which the resolution order already honours first.
8. Splits and follow-ups
No further design splits: the cluster is settled as one record. Implementation tickets are not filed by this task — the issue body states implementation timing is a separate decision, possibly months out; when that decision is taken, implementation splits should be cut per section (§1–§5) and linked here. Open interfaces handed to sibling clusters: embedding provider/model → issue #5842 (AI-over-notes); script-bearing templates/automation → issue #5843 (extensibility); clip attachment/media storage details → issue #5844 (attachments & media); daily-note capture targets, if any → issue #5839 (content model).
dezren39 commentedon Nov 5, 2026
🤖 Agent note · done