Skip to main content
Ctrl+K

scrap

  • Tutorials
  • How-to Guides
  • Explanations
  • Reference
  • GitHub
  • PyPI
  • Tutorials
  • How-to Guides
  • Explanations
  • Reference
  • GitHub
  • PyPI

Section Navigation

  • Architectural Decision Records
    • 1. Record architecture decisions
    • 2. Adopt python-copier-template for project structure
    • 3. One process, one SQLite database, one folder of files
    • 4. Originals are kept; everything else is derived, versioned or disposable
    • 5. Capture never waits: client-minted ids, an offline queue, no LLM on the save path
    • 6. A vanilla TypeScript PWA with a size budget and lazy chunks
    • 7. Tailscale Serve is the only way in; no login code
    • 8. Search is SQLite FTS5 with a shared query syntax; embeddings are deferred
    • 9. Claude ingest: Messages API, no tools, one structured call per photo
    • 10. Queue error classes: outages pause, charged failures count, spend is capped
    • 11. Whiteboards become Excalidraw drawings: model skeletons, human scenes, two sanitisers
    • 12. Page kinds with flat fields; due date and priority as typed columns
    • 13. The MCP server is part of the app: streamable HTTP, add-only writes
    • 14. Page text is Markdown, parsed by a library on both sides
    • 15. Images are embedded in the page text; scrap gc is conservative
    • 16. Deployment: rootless podman units for one server, a Helm chart for Kubernetes
    • 17. Import from a Thoth vault goes through Store and is idempotent
    • 18. Single-server installs listen on a Unix socket, reached only through Tailscale Serve
    • 19. Kinds and tags editable over MCP, made safe by metadata revisions
    • 20. Text enrichment: Claude tags, summarises and relates text pages, apart from the text
    • 21. Ingest on a Claude seat: claude -p with a long-lived token
    • 22. Page text editable over MCP, made safe by text revisions
    • 23. Bearer token on /mcp and an identity-header setting
    • 24. A settings pane in the top bar, with theme overrides
    • 25. The trash and a recent-changes feed over MCP
    • 26. Claude appends task boxes to a list of actions
    • 27. Claude’s write-ups of boards, apart from the text
    • 28. Claude-maintained topic pages
    • 29. Store health checks as search filters; outdated write-ups are the owner’s to regenerate
    • 30. Fewer MCP tools: recent, todos and revert_text folded away
    • 30. The trash is purged after N days
    • 31. Search orders results by section on the server
    • 32. Pins are an ordinary page of links
    • 33. Who made a page, and where a text revision came from, are stored
    • 34. Claude can move pages to the trash
    • 35. Files are read locally, for search
    • 36. A todo’s due date, priority and snooze are in a table of their own
    • 37. One baseline schema for 1.0
    • 38. File text is sent to Claude on capture, bounded
    • 39. Generated content keeps only its current version
    • 40. Search greps raw text: a parameter, and a scan
    • 41. MCP clients download files under /mcp
    • 42. MCP clients add SVG diagrams and files to pages
    • 43. Public pages: a static site scrap pushes to
    • 44. Claude’s reading in a fold, and Claude’s own images not read
    • 45. scrap verifies the login proxy’s Keycloak token
    • 46. The database on an emptyDir, replicated with Litestream
  • Architecture
    • Data model and storage
    • Capture, files and backup
    • Job queue and Claude features
    • Search
    • MCP server and access
    • The PWA
    • Deployment and operations
  • The PWA’s design system
  • Claude ingest
  • What Claude is asked, per page
  • Scope and stack
  • Explanations
  • Architectural Decision Records
  • 32. Pins are an ordinary page of links

32. Pins are an ordinary page of links#

Date: 2026-10-26

Status#

Accepted

Context#

Search phase 2 (#314) lets you keep your own searches and pages one tap away under the empty search box. Pins could be a table, a setting or localStorage; each would be a thing to sync, back up, edit and export of its own, and a pin kept on one phone would be missing on another.

Decision#

  • The pins are one page, titled Pinned with the slug pinned: a Markdown list of links (- [People](/search?q=tag:person%20group:letter), - [Contacts](/p/contacts)). The launcher shows them in order. Renaming, reordering and removing a pin is editing the page, which syncs, is revised, backed up, searchable and linkable like any other.

  • POST /api/pinned returns the page, making it once. The slug is the reservation: the page is looked up by it inside one write transaction, a trashed one is brought back, and a page the owner already called pinned is the Pinned page. No migration.

  • A normal page the owner titles “Pinned” gets the slug pinned and so becomes the pin list.

  • Pins link by slug, and a slug never changes when a page is retitled, so a pin survives a rename. The client edits with base_rev and retries a 409 up to three times.

  • Claude does not read the page (should_enrich, the backfill and the related pass skip the slug); Ask Claude still works on it.

  • group:area is a search group: topic pages by area in the order GET /api/topics gives, so the Topics screen and is:topic in Search share one grouping and one order. Topic hits carry area.

Consequences#

A page the owner makes called “Pinned” becomes the pin list. The Pinned page appears in search results like any page. A browser with no Share menu has no Pin to Search row; the page can be edited by hand.

previous

31. Search orders results by section on the server

next

33. Who made a page, and where a text revision came from, are stored

On this page
  • Status
  • Context
  • Decision
  • Consequences
Edit on GitHub
Show Source

Built with the PyData Sphinx Theme 0.23.0.