-
-
Shelfmark’s native macOS workspace combines saved links, Exact and Related search, private sync status, and resource details.
-
Generated and manual tags become browsable Topics, while source domains provide another direct route back into the library.
-
Related search ranks saved resources using local semantic similarity and displays truthful relevance.
Inspiration
I gather information constantly: notes, bookmarks, “read it later” lists, and far too many browser tabs. The problem is that saving something does not mean I can find it again. Weeks later, I may remember the idea, but not the title of the page, the website, or the words it used.
What I wanted was a private library that remembers meaning rather than only filenames and URLs. But semantic search is only useful when the library understands what was saved. A link alone is not enough. The application needs to inspect the page, extract useful text, summarize it, and identify its topics before that knowledge becomes searchable.
Shelfmark grew from that personal need: save something quickly now, then rediscover it later using the fragment of meaning I still remember.
What it does
Shelfmark is a native macOS and iOS application for building a private, searchable library of web resources. Adding an item requires only a URL. Shelfmark stores the link first, so capture does not depend on a successful network request. It then fetches public page information within explicit size limits, extracts useful text, and creates a short local summary and generated topical tags. User-written titles, notes, and tags always remain separate and authoritative.
Saved resources can be explored as a list or through shelves built from topics, sources, and relationships between topics. Exact search finds known words and shows truthful match evidence. Related search uses Apple’s local Natural Language sentence embeddings to find resources by meaning. The authoritative library uses SwiftData with a private CloudKit database. Semantic indexes remain derived and device-local. V1 does not send saved content to a remote semantic provider or require an AI account.
How we built it
Shelfmark is built with Swift, SwiftUI, SwiftData, private CloudKit, and Apple’s Natural Language framework. Shared product logic is kept outside SwiftUI and concrete persistence code through a lightweight Engine, Data adapter, and presentation structure.
Before OpenAI Build Week, the repository already contained an experimental resource model, file-backed JSON storage, parsing utilities, and several advanced review workflows. It was technically substantial, but it was not yet the focused product I wanted to use. The main interface was dense, semantic search was still future work, and the private synchronized library had not replaced local file storage.
During Build Week, I turned those foundations into the current application. That included private CloudKit persistence, migration, bounded enrichment, the List and Shelves experience, local semantic search, durable device-local vector snapshots, local summaries and generated tags, GitHub README extraction, topic relationships, and recovery for interrupted analysis.
I used Spec Kit to define each feature before implementation. Codex helped turn those specifications into bounded work packages, managed implementation worktrees, reviewed diffs, and ran focused builds and tests through Apple’s Xcode MCP integration.
I remained responsible for the product and architecture decisions. For example, I rejected Core Spotlight as the primary semantic engine after our evidence showed that it did not meet the related-search quality gate. I selected Apple’s Natural Language embeddings instead, chose a fixed-English policy for v1, kept remote LLM integration out of the first release, and prioritized reliable capture and visible product usability.
GPT-5.6 was particularly useful while hardening the content-understanding workflow. It helped reason through and implement bounded readable versus analysis text, one-minute attempt leases, stale-generation rejection, interruption recovery, and a digest proving that generated tags came from the displayed summary. These changes fixed resources that could otherwise remain stuck on “Updating summary” after an interrupted run.
Challenges we ran into
The largest challenge was reducing complexity rather than adding more of it. The repository began with many useful technical experiments, but the first hands-on test drive showed that they were obscuring the basic journey of saving and finding a link.
Semantic search also required experimentation. Core Spotlight was attractive because it is native, but its related results did not satisfy our evidence gate. Apple’s Natural Language sentence embeddings produced the stronger local result, although language detection initially rejected short queries. For v1, I made indexing and queries consistently use the English model while retaining that policy as provenance for future migration.
Web extraction presented another practical problem. Some pages exceeded the original limits, and simply increasing those limits would still discard everything at the next boundary. Shelfmark now preserves a useful bounded prefix, records whether extraction was complete or partial, and keeps separate limits for readable display text and richer analysis input.
We also encountered cancellation races, analysis attempts left running after process interruption, stale deliveries, Xcode automation contention, and macOS presentation crashes. Focused tests and explicit lifecycle contracts helped turn those failures into reproducible cases instead of intermittent behavior.
Accomplishments that we're proud of
I am proud that Shelfmark now demonstrates the complete journey that originally motivated it: capture a real webpage, retain useful page content, generate a local summary and topics, and retrieve it later using meaning rather than its exact title. Capture is independent from enrichment, so a temporary network or analysis failure does not lose the resource. Derived information carries provenance and becomes stale when its source changes. Generated tags remain separate from manual tags and can be dismissed. Interrupted work is recoverable, and late results from obsolete attempts cannot overwrite current information. I am also proud that the application remains private by default. Its semantic provider is local, its derived index is disposable, and its synchronized authoritative data stays in the user’s private CloudKit database. Finally, the project is not just a prototype screen. The macOS and iOS applications build successfully, the strongest workflows have focused deterministic coverage, and the previously stuck live resources recovered with real summaries and tags.
What we learned
The biggest lesson was that a working product journey is more valuable than a large collection of technically interesting features. Test-driving the application repeatedly changed the roadmap. I also learned that semantic systems need strict truthfulness boundaries. A similarity score is not confidence, a generated explanation is not match evidence, and derived data should not become authoritative merely because it is useful. Codex was most effective when I gave it narrow specifications, explicit ownership boundaries, and measurable review gates. GPT-5.6 could explore implementation details and concurrency cases quickly, while I retained control of product scope, architecture, acceptance decisions, and integration.
What's next for Shelfmark: A private semantic library for the web
The next step is visual and interaction refinement based on the tracked interface explorations, followed by broader release validation across macOS, iPhone, and iPad.
After that, I want to add dedicated extraction strategies for more resource types, improve multilingual semantic retrieval, and explore richer local organization. Optional Codex or remote-model processing may become a later provider, but only behind the same privacy, provenance, and replaceability boundaries.
The long-term goal is simple: Shelfmark should become the private memory for the useful things I encounter online, even when I can no longer remember what they were called.

Log in or sign up for Devpost to join the conversation.