<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Tech — NT² Blog</title>
    <link>https://nt2-blog-staging.eavatar.workers.dev/categories/tech</link>
    <atom:link href="https://nt2-blog-staging.eavatar.workers.dev/categories/tech/feed.xml" rel="self" type="application/rss+xml" />
    <description>Engineering deep dives into the architecture and implementation behind NT² Vault.</description>
    <language>en</language>
    <lastBuildDate>Thu, 24 Dec 2026 00:00:00 GMT</lastBuildDate>
    <item>
      <title>Nearby control plane, WebRTC bulk plane</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/control-plane-nearby-bulk-plane-webrtc</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/control-plane-nearby-bulk-plane-webrtc</guid>
      <pubDate>Thu, 24 Dec 2026 00:00:00 GMT</pubDate>
      <description>A proximity session has a budget. Contact invites and share manifests fit. PDF scans usually do not—so attachments leave on a bulk plane after SDP exchange, not stuffed into every control frame.</description>
      <author>NT²</author>
      <category>share</category>
      <category>cryptography</category>
      <category>privacy</category>
      <category>web</category>
      <category>webrtc</category>
    </item>
    <item>
      <title>Bootstrap QR stays off the web</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/bootstrap-qr-stays-off-the-web</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/bootstrap-qr-stays-off-the-web</guid>
      <pubDate>Sun, 20 Dec 2026 00:00:00 GMT</pubDate>
      <description>If a proximity bootstrap can live in an ordinary https link, the authenticator has already toured browser history, referrers, and OS camera → URL launch paths.</description>
      <author>NT²</author>
      <category>share</category>
      <category>cryptography</category>
      <category>privacy</category>
      <category>security</category>
      <category>web</category>
    </item>
    <item>
      <title>A proximity session is not a peer connection</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/proximity-session-is-not-a-peer-connection</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/proximity-session-is-not-a-peer-connection</guid>
      <pubDate>Thu, 17 Dec 2026 00:00:00 GMT</pubDate>
      <description>Connecting beside someone is a short-lived session. Recognizing them as a vault contact—and accepting a share into your vault—are still separate acts.</description>
      <author>NT²</author>
      <category>share</category>
      <category>contacts</category>
      <category>cryptography</category>
      <category>zero-knowledge</category>
      <category>privacy</category>
      <category>web</category>
    </item>
    <item>
      <title>Share file, deep link, and machine-handoff passphrase</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/share-file-link-and-machine-handoff-passphrase</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/share-file-link-and-machine-handoff-passphrase</guid>
      <pubDate>Sun, 13 Dec 2026 00:00:00 GMT</pubDate>
      <description>Ciphertext and the secret that opens it should not travel as one convenient email. NT² splits carriers—file or link—from OOB passphrase delivery, and treats Strong as machine-handoff.</description>
      <author>NT²</author>
      <category>share</category>
      <category>cryptography</category>
      <category>security</category>
      <category>privacy</category>
      <category>zero-knowledge</category>
      <category>deep-links</category>
    </item>
    <item>
      <title>Delayed legacy release is not password recovery</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/delayed-legacy-release-not-password-recovery</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/delayed-legacy-release-not-password-recovery</guid>
      <pubDate>Thu, 10 Dec 2026 00:00:00 GMT</pubDate>
      <description>Estate and emergency access tempt products to hold a second key “just in case.” NT² refuses that oracle. Legacy is a sealed package on a delay—not a support console unlock.</description>
      <author>NT²</author>
      <category>share</category>
      <category>recovery</category>
      <category>security</category>
      <category>zero-knowledge</category>
      <category>privacy</category>
      <category>legacy</category>
    </item>
    <item>
      <title>Revoke what you already sent</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/outbox-revoke-what-you-already-sent</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/outbox-revoke-what-you-already-sent</guid>
      <pubDate>Sun, 06 Dec 2026 00:00:00 GMT</pubDate>
      <description>After a share leaves your vault, “did they open it?” and “can I kill it?” are sender questions. The answers live in a local outbox—not a cloud mailbox of readable mail.</description>
      <author>NT²</author>
      <category>share</category>
      <category>architecture</category>
      <category>privacy</category>
      <category>zero-knowledge</category>
      <category>edge</category>
      <category>local-first</category>
    </item>
    <item>
      <title>A peer connection is not a phone contact</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/peer-connection-is-not-a-phone-contact</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/peer-connection-is-not-a-phone-contact</guid>
      <pubDate>Thu, 03 Dec 2026 00:00:00 GMT</pubDate>
      <description>Sharing to “someone in Contacts” only works if the row holds encryption material for that vault—not a phone number you hope matches the right person.</description>
      <author>NT²</author>
      <category>share</category>
      <category>contacts</category>
      <category>identity</category>
      <category>cryptography</category>
      <category>zero-knowledge</category>
      <category>privacy</category>
    </item>
    <item>
      <title>Four surfaces, one field set</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/four-surfaces-one-field-set</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/four-surfaces-one-field-set</guid>
      <pubDate>Sun, 29 Nov 2026 00:00:00 GMT</pubDate>
      <description>If “form fields,” “share fields,” and “expiry fields” are three schemas, they will drift—and someone will see more than you meant. One active field set keeps every surface honest.</description>
      <author>NT²</author>
      <category>structured-vault</category>
      <category>semantic-fields</category>
      <category>sharing</category>
      <category>selective-disclosure</category>
      <category>category-templates</category>
    </item>
    <item>
      <title>Searchable metadata, sealed field values</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/searchable-metadata-sealed-field-values</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/searchable-metadata-sealed-field-values</guid>
      <pubDate>Thu, 26 Nov 2026 00:00:00 GMT</pubDate>
      <description>A vault that cannot find a title is unusable. A vault that full-text indexes every password on a server is not a vault. The boundary is projected metadata versus sealed field values.</description>
      <author>NT²</author>
      <category>structured-vault</category>
      <category>cbf</category>
      <category>fts5</category>
      <category>zero-knowledge</category>
      <category>local-first</category>
      <category>search</category>
    </item>
    <item>
      <title>Compose domains from one type system</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/compose-domains-from-one-type-system</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/compose-domains-from-one-type-system</guid>
      <pubDate>Sun, 22 Nov 2026 00:00:00 GMT</pubDate>
      <description>A medical pack and an IT pack should not each reinvent “expiry date.” Domains grow by composing a shared semantic catalog into category templates—then enabling the packs you need.</description>
      <author>NT²</author>
      <category>structured-vault</category>
      <category>category-templates</category>
      <category>field-packs</category>
      <category>semantic-fields</category>
      <category>local-first</category>
    </item>
    <item>
      <title>Semantic columns, not form widgets</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/semantic-columns-not-form-widgets</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/semantic-columns-not-form-widgets</guid>
      <pubDate>Thu, 19 Nov 2026 00:00:00 GMT</pubDate>
      <description>A password field is not “a secret text box on this screen.” It is a semantic column type the whole vault understands—masking, health, share defaults, and wire shape included.</description>
      <author>NT²</author>
      <category>structured-vault</category>
      <category>semantic-fields</category>
      <category>category-templates</category>
      <category>field-registry</category>
      <category>local-first</category>
    </item>
    <item>
      <title>Slots, not a blank page</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/slots-not-a-blank-page</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/slots-not-a-blank-page</guid>
      <pubDate>Sun, 15 Nov 2026 00:00:00 GMT</pubDate>
      <description>A passport, a bank account, an API key, and a seed phrase are not the same kind of text. A vault that treats them as one blank page will always ask you to remember the structure yourself.</description>
      <author>NT²</author>
      <category>structured-vault</category>
      <category>category-templates</category>
      <category>local-first</category>
      <category>document-model</category>
      <category>zero-knowledge</category>
    </item>
    <item>
      <title>Replica batch under the hood — packet shapes</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/replica-batch-under-the-hood</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/replica-batch-under-the-hood</guid>
      <pubDate>Thu, 12 Nov 2026 00:00:00 GMT</pubDate>
      <description>Blind sync is easier to trust when you can picture the packet. The edge sees shapes, sizes, and progress—not titles, notes, or a searchable attic of your secrets.</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>sync</category>
      <category>privacy</category>
      <category>zero-knowledge</category>
      <category>edge</category>
      <category>local-first</category>
      <category>durable-objects</category>
      <category>r2</category>
    </item>
    <item>
      <title>Threat model, 2026: browsers and extensions</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/threat-model-2026-browser-and-extensions</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/threat-model-2026-browser-and-extensions</guid>
      <pubDate>Sun, 08 Nov 2026 00:00:00 GMT</pubDate>
      <description>Threat models age with browsers. This 2026 refresh keeps the residual risks named—XSS, unlocked theft, hostile extensions, origin supply chain—and checks which defenses still hold when the client world moves.</description>
      <author>NT²</author>
      <category>security</category>
      <category>threat-model</category>
      <category>browsers</category>
      <category>extensions</category>
      <category>web-crypto</category>
      <category>xss</category>
      <category>zero-knowledge</category>
      <category>local-first</category>
    </item>
    <item>
      <title>Benchmarks from a 10k-item OPFS vault</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/benchmarks-from-a-10k-item-opfs-vault</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/benchmarks-from-a-10k-item-opfs-vault</guid>
      <pubDate>Thu, 05 Nov 2026 00:00:00 GMT</pubDate>
      <description>A large local vault is not proven by a slogan. It is proven by measuring the paths people actually use—first page after unlock, debounced search, FTS versus filter queries—and by being honest about what those numbers do not mean.</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>local-first</category>
      <category>sqlite</category>
      <category>opfs</category>
      <category>performance</category>
      <category>benchmarks</category>
      <category>fts5</category>
      <category>pwa</category>
    </item>
    <item>
      <title>Offline-capable is not sync later if lucky</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/offline-is-the-happy-path</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/offline-is-the-happy-path</guid>
      <pubDate>Sun, 01 Nov 2026 00:00:00 GMT</pubDate>
      <description>Many apps call themselves offline-capable when they mean a read-only cache and a queue that hopes the tower returns. A local-first vault puts full CRUD on the device first. Sync is an optional second path.</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>local-first</category>
      <category>offline</category>
      <category>pwa</category>
      <category>sync</category>
      <category>privacy</category>
      <category>zero-knowledge</category>
    </item>
    <item>
      <title>XSS steals sessions elsewhere; here keys are non-extractable</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/threat-model-xss-device-theft</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/threat-model-xss-device-theft</guid>
      <pubDate>Thu, 29 Oct 2026 00:00:00 GMT</pubDate>
      <description>A vault that advertises invincibility is selling theater. NT² names the residual risks—XSS while unlocked, a stolen unlocked device, a hostile extension—and designs so those failures do not also become password oracles or exportable key dumps.</description>
      <author>NT²</author>
      <category>security</category>
      <category>threat-model</category>
      <category>web-crypto</category>
      <category>xss</category>
      <category>zero-knowledge</category>
      <category>local-first</category>
      <category>crypto</category>
    </item>
    <item>
      <title>Shared crypto packages get a 100% coverage floor</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/hundred-percent-coverage-on-crypto-packages</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/hundred-percent-coverage-on-crypto-packages</guid>
      <pubDate>Sun, 25 Oct 2026 00:00:00 GMT</pubDate>
      <description>Specs bound scope. Security veto owns residual risk. Coverage floors own a narrower job: no uncovered line in the shared packages that seal, wrap, and describe vault facts—because agents will otherwise ship “done” with a hole.</description>
      <author>NT²</author>
      <category>ai-agents</category>
      <category>testing</category>
      <category>coverage</category>
      <category>crypto</category>
      <category>human-in-the-loop</category>
      <category>product-development</category>
      <category>engineering</category>
    </item>
    <item>
      <title>Security veto is a role, not a vibe</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/security-veto-in-the-agent-loop</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/security-veto-in-the-agent-loop</guid>
      <pubDate>Thu, 22 Oct 2026 00:00:00 GMT</pubDate>
      <description>Agents can draft patches and greenlights. They cannot own the decision that a vault still refuses password escrow, extractable keys, or a “helpful” recovery desk. Security veto is a role with authority—not a mood in chat.</description>
      <author>NT²</author>
      <category>ai-agents</category>
      <category>security</category>
      <category>human-in-the-loop</category>
      <category>crypto</category>
      <category>secure-sdlc</category>
      <category>product-development</category>
      <category>engineering</category>
    </item>
    <item>
      <title>Specs before agents write code</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/spec-driven-development-for-agents</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/spec-driven-development-for-agents</guid>
      <pubDate>Sun, 18 Oct 2026 00:00:00 GMT</pubDate>
      <description>An agent that codes from a vague prompt will invent a product. An agent that codes from a written contract will ship the slice you approved—or stop where the contract ends.</description>
      <author>NT²</author>
      <category>ai-agents</category>
      <category>spec-driven-development</category>
      <category>human-in-the-loop</category>
      <category>product-development</category>
      <category>security</category>
      <category>engineering</category>
    </item>
    <item>
      <title>What the Workers are allowed to see</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/what-the-workers-are-allowed-to-see</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/what-the-workers-are-allowed-to-see</guid>
      <pubDate>Thu, 15 Oct 2026 00:00:00 GMT</pubDate>
      <description>Zero-knowledge is not a slogan about HTTPS. It is a permission list for the edge: what Workers may store, route, and bill for—and what they are never allowed to learn.</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>cloudflare</category>
      <category>workers</category>
      <category>edge</category>
      <category>zero-knowledge</category>
      <category>privacy</category>
      <category>sync</category>
      <category>security</category>
    </item>
    <item>
      <title>.nt2backup as a sovereignty format</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/nt2backup-as-portable-sovereignty</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/nt2backup-as-portable-sovereignty</guid>
      <pubDate>Sat, 10 Oct 2026 00:00:00 GMT</pubDate>
      <description>Local-first only means ownership if you can leave with an encrypted snapshot the cloud never had to hold. .nt2backup is that snapshot: portable vault profile sections and sealed payloads in a file you control.</description>
      <author>NT²</author>
      <category>backup</category>
      <category>local-first</category>
      <category>zero-knowledge</category>
      <category>architecture</category>
      <category>escape-hatch</category>
      <category>portability</category>
      <category>encryption</category>
    </item>
    <item>
      <title>Same vault UI in browser, PWA, and desktop shells</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/one-web-ui-three-shells</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/one-web-ui-three-shells</guid>
      <pubDate>Wed, 07 Oct 2026 00:00:00 GMT</pubDate>
      <description>Unlock, list, search, and settings should not fork into three products. NT² Vault keeps one vault UI and lets each shell own only what the platform must own: how durable files live on that device.</description>
      <author>NT²</author>
      <category>pwa</category>
      <category>tauri</category>
      <category>webview</category>
      <category>opfs</category>
      <category>local-first</category>
      <category>attachments</category>
      <category>sqlite</category>
      <category>cross-platform</category>
    </item>
    <item>
      <title>Vault profile is section KV, not one mega-row</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/vault-meta-as-section-kv</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/vault-meta-as-section-kv</guid>
      <pubDate>Sat, 03 Oct 2026 00:00:00 GMT</pubDate>
      <description>Salt, Key DID public material, sync cursors, and onboarding prefs are not one fat SQL row. They live as named vault profile sections—so backup, sync, and unlock can each touch only what they need.</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>sqlite</category>
      <category>vault-meta</category>
      <category>local-first</category>
      <category>backup</category>
      <category>sync</category>
      <category>zero-knowledge</category>
      <category>pwa</category>
    </item>
    <item>
      <title>Schema v60 and incremental migration</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/incremental-vault-schema-migration</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/incremental-vault-schema-migration</guid>
      <pubDate>Wed, 30 Sep 2026 00:00:00 GMT</pubDate>
      <description>A local vault is a real SQLite database on your device. When the product ships schema v60, launch-era vaults must upgrade in place—not force a wipe because the CREATE statement changed in the source tree.</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>sqlite</category>
      <category>schema-migration</category>
      <category>local-first</category>
      <category>opfs</category>
      <category>pwa</category>
      <category>data-durability</category>
    </item>
    <item>
      <title>Wrong password must fail closed</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/password-verifier-fail-closed</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/password-verifier-fail-closed</guid>
      <pubDate>Sat, 26 Sep 2026 00:00:00 GMT</pubDate>
      <description>Unlock is not a best-effort decrypt of everything you own. NT² checks a small local verifier first. Wrong password fails closed: the vault stays locked, and the UI stays honest.</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>crypto</category>
      <category>security</category>
      <category>local-first</category>
      <category>zero-knowledge</category>
      <category>web-crypto</category>
      <category>aes-gcm</category>
      <category>unlock</category>
    </item>
    <item>
      <title>CBF is how structured fields leave RAM</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/cbf-payload-blobs-at-rest</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/cbf-payload-blobs-at-rest</guid>
      <pubDate>Wed, 23 Sep 2026 00:00:00 GMT</pubDate>
      <description>A credential is a map of fields while you edit it. The moment those fields must survive a lock, a restart, or a replica, they need a portable ciphertext shape—not a JSON dump waiting for the next reader.</description>
      <author>NT²</author>
      <category>cryptography</category>
      <category>aes-gcm</category>
      <category>cbf</category>
      <category>local-first</category>
      <category>zero-knowledge</category>
      <category>envelope-encryption</category>
      <category>security</category>
    </item>
    <item>
      <title>Auto-lock is a memory hygiene problem</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/crypto-keys-must-not-survive-refresh</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/crypto-keys-must-not-survive-refresh</guid>
      <pubDate>Sat, 19 Sep 2026 00:00:00 GMT</pubDate>
      <description>Encryption at rest is incomplete if the decrypted key handle outlives the unlocked session. NT² treats auto-lock as memory hygiene: non-extractable CryptoKeys, in-memory only, cleared on idle, refresh, and tab close.</description>
      <author>NT²</author>
      <category>web-crypto</category>
      <category>security</category>
      <category>crypto</category>
      <category>session</category>
      <category>auto-lock</category>
      <category>local-first</category>
      <category>pwa</category>
      <category>zero-knowledge</category>
    </item>
    <item>
      <title>SQLite in a Web Worker is not optional</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/sqlite-in-a-web-worker</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/sqlite-in-a-web-worker</guid>
      <pubDate>Wed, 16 Sep 2026 00:00:00 GMT</pubDate>
      <description>A local-first vault needs a real relational engine on device. Putting that engine on the UI thread makes every page query compete with paint and input. NT² Vault runs SQLite in a Web Worker, behind typed messages and a single lock chain, so the list can stay responsive while the database stays honest.</description>
      <author>NT²</author>
      <category>web-worker</category>
      <category>sqlite</category>
      <category>wasm</category>
      <category>wa-sqlite</category>
      <category>opfs</category>
      <category>local-first</category>
      <category>pwa</category>
      <category>concurrency</category>
    </item>
    <item>
      <title>Selective SSI — not a general DIDComm wallet</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/selective-ssi-not-a-did-wallet</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/selective-ssi-not-a-did-wallet</guid>
      <pubDate>Sat, 12 Sep 2026 00:00:00 GMT</pubDate>
      <description>Self-sovereign identity is useful when you take the parts that fit a zero-knowledge vault—and refuse the parts that turn the product into a general DID wallet.</description>
      <author>NT²</author>
      <category>identity</category>
      <category>did</category>
      <category>share</category>
      <category>architecture</category>
      <category>privacy</category>
      <category>zero-knowledge</category>
      <category>security</category>
      <category>cryptography</category>
    </item>
    <item>
      <title>Relay indexes ciphertext; Inbox stays local</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/blind-share-relay-local-inbox</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/blind-share-relay-local-inbox</guid>
      <pubDate>Wed, 09 Sep 2026 00:00:00 GMT</pubDate>
      <description>A cloud can help deliver sealed packages without becoming the place where pending shares live as readable mail. Relay indexes ciphertext. Inbox stays on the device.</description>
      <author>NT²</author>
      <category>share</category>
      <category>inbox</category>
      <category>architecture</category>
      <category>privacy</category>
      <category>zero-knowledge</category>
      <category>edge</category>
      <category>local-first</category>
    </item>
    <item>
      <title>Share passphrase ≠ master password</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/share-passphrase-is-not-master-password</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/share-passphrase-is-not-master-password</guid>
      <pubDate>Sat, 05 Sep 2026 00:00:00 GMT</pubDate>
      <description>A share that opens with the same secret that unlocks the vault is not a handoff. It is a remote unlock of everything. NT² keeps those boundaries apart.</description>
      <author>NT²</author>
      <category>share</category>
      <category>cryptography</category>
      <category>security</category>
      <category>privacy</category>
      <category>zero-knowledge</category>
      <category>aes-gcm</category>
      <category>identity</category>
    </item>
    <item>
      <title>Challenge–response, not bearer email</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/key-did-challenge-response-auth</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/key-did-challenge-response-auth</guid>
      <pubDate>Wed, 02 Sep 2026 00:00:00 GMT</pubDate>
      <description>Cloud services often treat an email inbox as the root of an account. An encrypted vault needs a different proof: control of a signing key, shown by answering a one-time challenge.</description>
      <author>NT²</author>
      <category>authentication</category>
      <category>identity</category>
      <category>cryptography</category>
      <category>did</category>
      <category>security</category>
      <category>privacy</category>
      <category>cloud</category>
      <category>zero-knowledge</category>
    </item>
    <item>
      <title>One unlocked vault per tab — by design</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/single-writer-multi-tab-vault</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/single-writer-multi-tab-vault</guid>
      <pubDate>Sat, 29 Aug 2026 00:00:00 GMT</pubDate>
      <description>Opening the same vault in two browser tabs is normal. Letting both tabs write the same on-device SQLite file is not. NT² Vault elects one Writer and keeps every other unlocked tab as a follower.</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>multi-tab</category>
      <category>local-first</category>
      <category>pwa</category>
      <category>sqlite</category>
      <category>broadcastchannel</category>
      <category>web-locks</category>
      <category>concurrency</category>
    </item>
    <item>
      <title>Metadata in SQLite, ciphertext in BlobStore</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/attachment-ciphertext-outside-sqlite</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/attachment-ciphertext-outside-sqlite</guid>
      <pubDate>Wed, 26 Aug 2026 00:00:00 GMT</pubDate>
      <description>A vault needs to know which files belong to which items, how large they are, and how to unwrap their keys. It does not need those encrypted bytes sitting inside the relational database that answers those questions.</description>
      <author>NT²</author>
      <category>attachments</category>
      <category>sqlite</category>
      <category>blobstore</category>
      <category>opfs</category>
      <category>envelope-encryption</category>
      <category>local-first</category>
      <category>aes-gcm</category>
      <category>chunking</category>
    </item>
    <item>
      <title>FTS5 for titles; table scan when filters win</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/fts5-vs-table-scan-in-the-vault</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/fts5-vs-table-scan-in-the-vault</guid>
      <pubDate>Sat, 22 Aug 2026 00:00:00 GMT</pubDate>
      <description>Local search is not one query shape. Free-text wants a full-text index on titles and search text. Category, trash, archive, and similar filters want ordinary table predicates. The product switches strategy so the UI never has to ship the whole vault into memory to feel searchable.</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>local-first</category>
      <category>sqlite</category>
      <category>fts5</category>
      <category>search</category>
      <category>performance</category>
      <category>pwa</category>
    </item>
    <item>
      <title>Never load the whole vault into Svelte state</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/paged-list-not-full-table-load</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/paged-list-not-full-table-load</guid>
      <pubDate>Wed, 19 Aug 2026 00:00:00 GMT</pubDate>
      <description>A local vault can hold thousands of structured items without becoming a giant in-memory array. The durable store stays in SQLite. The UI holds only a paged window of lightweight list rows, rendered through a virtual list.</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>local-first</category>
      <category>sqlite</category>
      <category>svelte</category>
      <category>performance</category>
      <category>virtual-list</category>
      <category>pagination</category>
      <category>pwa</category>
    </item>
    <item>
      <title>The account database must not become a password oracle</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/no-password-oracle-in-d1</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/no-password-oracle-in-d1</guid>
      <pubDate>Sat, 15 Aug 2026 00:00:00 GMT</pubDate>
      <description>An account table can contain no plaintext vault items and still create a dangerous password-testing surface. We removed the columns that could turn a database copy into an offline guessing or recovery system.</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>security</category>
      <category>privacy</category>
      <category>zero-knowledge</category>
      <category>edge</category>
      <category>cloudflare</category>
      <category>d1</category>
      <category>authentication</category>
    </item>
    <item>
      <title>One sync hub for one vault identity</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/vault-durable-object-per-key-did</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/vault-durable-object-per-key-did</guid>
      <pubDate>Wed, 12 Aug 2026 00:00:00 GMT</pubDate>
      <description>A vault does not need to enter a shared plaintext mailbox to sync. Its public cryptographic identity can name a dedicated edge coordinator that notifies replicas and points them to encrypted frames it cannot open.</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>sync</category>
      <category>privacy</category>
      <category>durable-objects</category>
      <category>key-did</category>
      <category>edge</category>
    </item>
    <item>
      <title>No password reset, by design</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/no-password-reset-by-design</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/no-password-reset-by-design</guid>
      <pubDate>Sat, 08 Aug 2026 00:00:00 GMT</pubDate>
      <description>“Contact support to reset your password” sounds reassuring. For an encrypted vault, it also reveals who ultimately controls access. NT² chooses a harder promise: recovery material stays with you, not our help desk.</description>
      <author>NT²</author>
      <category>security</category>
      <category>recovery</category>
      <category>zero-knowledge</category>
      <category>trust</category>
      <category>local-first</category>
    </item>
    <item>
      <title>Blind replica sync on the edge</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/blind-replica-sync-on-the-edge</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/blind-replica-sync-on-the-edge</guid>
      <pubDate>Wed, 05 Aug 2026 00:00:00 GMT</pubDate>
      <description>Sync does not have to turn a local vault into a cloud database. The edge can identify an account, store opaque replica frames, and deliver updates without learning what those updates contain.</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>sync</category>
      <category>privacy</category>
      <category>local-first</category>
      <category>zero-knowledge</category>
      <category>edge</category>
    </item>
    <item>
      <title>Why our vault SQLite database lives in OPFS, not IndexedDB</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/opfs-not-indexeddb-for-vault-sqlite</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/opfs-not-indexeddb-for-vault-sqlite</guid>
      <pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate>
      <description>SQLite wants a file. A privacy vault wants durable relational storage that stays fast as its item count, indexes, and encrypted attachments grow. Putting a SQLite virtual file system on IndexedDB can bridge those worlds, but it makes the bridge part of every database operation. For NT² Vault, the browser vault file belongs in the Origin Private File System.</description>
      <author>NT²</author>
      <category>opfs</category>
      <category>indexeddb</category>
      <category>sqlite</category>
      <category>wasm</category>
      <category>wa-sqlite</category>
      <category>local-first</category>
      <category>pwa</category>
      <category>browser-storage</category>
    </item>
    <item>
      <title>Unlocking a local vault is not logging in to the cloud</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/unlock-local-auth-cloud</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/unlock-local-auth-cloud</guid>
      <pubDate>Wed, 29 Jul 2026 00:00:00 GMT</pubDate>
      <description>One screen can make two security events look like a single login. We keep them separate because opening encrypted data and proving an identity to a server are different jobs with different risks.</description>
      <author>NT²</author>
      <category>authentication</category>
      <category>local-first</category>
      <category>privacy</category>
      <category>security</category>
      <category>cryptography</category>
      <category>cloud</category>
    </item>
    <item>
      <title>One key per object: envelope encryption inside NT² Vault</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/envelope-encryption-cek-per-object</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/envelope-encryption-cek-per-object</guid>
      <pubDate>Sat, 25 Jul 2026 00:00:00 GMT</pubDate>
      <description>A vault can encrypt everything with one key and still claim that its data is encrypted. We wanted a more useful boundary: each item and attachment gets its own content encryption key, while the vault key protects those keys.</description>
      <author>NT²</author>
      <category>envelope-encryption</category>
      <category>aes-gcm</category>
      <category>cryptography</category>
      <category>local-first</category>
      <category>attachments</category>
      <category>opfs</category>
      <category>security</category>
    </item>
    <item>
      <title>The KDF salt stays on your device</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/kdf-salt-stays-on-device</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/kdf-salt-stays-on-device</guid>
      <pubDate>Thu, 23 Jul 2026 00:00:00 GMT</pubDate>
      <description>A salt is not a secret. Still, where it lives changes who can assemble a password-guessing system. NT² keeps the KDF salt and password verifier with the local vault, so unlocking begins and ends on the device.</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>crypto</category>
      <category>security</category>
      <category>local-first</category>
      <category>zero-knowledge</category>
      <category>web-crypto</category>
      <category>pbkdf2</category>
      <category>key-derivation</category>
    </item>
    <item>
      <title>How one person builds and operates NT² Vault with AI agents</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/one-person-ai-coding-agent-product-lifecycle</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/one-person-ai-coding-agent-product-lifecycle</guid>
      <pubDate>Mon, 20 Jul 2026 00:00:00 GMT</pubDate>
      <description>The useful question is not whether an AI agent can write code. It is how to give agents enough context and autonomy to move quickly while keeping product decisions, security boundaries, releases, and customer-facing actions under explicit human control.</description>
      <author>NT²</author>
      <category>ai-agents</category>
      <category>human-in-the-loop</category>
      <category>spec-driven-development</category>
      <category>tdd</category>
      <category>devops</category>
      <category>security</category>
      <category>product-development</category>
    </item>
    <item>
      <title>Why host a heavy server when a PWA can do everything locally? Built a zero-server privacy vault.</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/why-pwa-local-first-zero-server-vault</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/why-pwa-local-first-zero-server-vault</guid>
      <pubDate>Thu, 09 Jul 2026 00:00:00 GMT</pubDate>
      <description>In the era of massive cloud-first applications, we often overlook a powerful alternative: the Progressive Web App (PWA). Why maintain a heavy, expensive, and potentially vulnerable server infrastructure when the modern browser is capable of running a full-featured, secure, and high-performance application entirely on the user&apos;s device?</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>pwa</category>
      <category>privacy</category>
      <category>security</category>
      <category>local-first</category>
      <category>zero-knowledge</category>
      <category>web-crypto</category>
      <category>sqlite</category>
      <category>wasm</category>
      <category>opfs</category>
    </item>
    <item>
      <title>Threshold Vault and Key DID: identity without handing over the keys</title>
      <link>https://nt2-blog-staging.eavatar.workers.dev/threshold-vault-key-did-self-sovereign-identity</link>
      <guid isPermaLink="true">https://nt2-blog-staging.eavatar.workers.dev/threshold-vault-key-did-self-sovereign-identity</guid>
      <pubDate>Tue, 30 Jun 2026 00:00:00 GMT</pubDate>
      <description>Self-sovereign identity sounds abstract. In NT², the practical version is simpler: your vault can prove itself, recover without a help desk, and share under your control while NT² stays blind.</description>
      <author>NT²</author>
      <category>trust</category>
      <category>identity</category>
    </item>
  </channel>
</rss>