Skip to content

Invariants & ADR Catalog

Markdown Comments

This document formalizes the 14 Core System Invariants and key Architectural Decision Records (ADRs) governing the Markdown Comments codebase.


Part I: The 14 System Invariants

System invariants are non-negotiable correctness rules enforced across all monorepo packages. They are cataloged under quality/invariants/ and validated in CI.

Invariant IDTitleScopeEnforcement Mechanism
INV-OAUTH-ONLYOAuth Only AuthenticationChrome, Safari, IDEStatic analysis, ESLint AST rules, integration tests
INV-FAST-FORWARD-RETRYFast-Forward Concurrent Push RetryShared, StorageUnit tests asserting exponential backoff on 409 Conflict
INV-ZERO-CLIENT-SECRETSZero Client SecretsAll client bundlesAST bundle scanning, pre-commit secret leak tests
INV-ZERO-CUSTOMER-DATAZero Customer Data in TelemetryTelemetry, SharedSchema verification and automated payload PII scrub tests
INV-TELEMETRY-KILLSWITCHImmediate Telemetry KillswitchTelemetryTests asserting zero network dispatch when disabled
INV-VISUAL-PARITYCross-Platform Visual ParityVS Code, Browser, Obsidian, StarlightPlaywright visual regression tests and design token assertions
INV-XSS-SANITIZEDStrict Markdown/HTML SanitizationPreview Webview, WebExtensionsDOMPurify / sanitizeHtml AST assertions
INV-QUOTA-DEFENSEGitHub API Rate Limit DefenseShared Git APIConditional ETag caching and Tree SHA reuse tests
INV-IN-PLACE-PREVIEWIn-Place Preview DOM MutationVS Code Webview PreviewPlaywright E2E asserting zero document DOM refresh
INV-MUTATION-GUARDMutationObserver Equality GuardVS Code Preview Scriptstests/vscode-preview-infinite-loop.test.ts
INV-BASE-TREE-SHABase Tree SHA ResolutionShared Git Ref Backendtests/gitRefBackend.test.ts checking tree.sha usage
INV-AUTH-PERSISTENCEMulti-Tier Auth & GlobalState PersistenceVS Code Auth Managertests/vscode-github-auth-persistence.test.ts
INV-MODAL-CONFIRMATIONIn-Preview Modal Deletion ConfirmationVS Code Webview DOMtests/e2e/vscode-real-repo-sequential-delete.spec.ts
INV-SILENT-BG-REFRESHSilent Background SynchronizationBackground Pollingtests/refreshBackgroundSync.test.ts

Invariant Details

1. INV-OAUTH-ONLY (No PATs)

Browser extensions and IDE integrations must never prompt for, store, or persist raw GitHub Personal Access Tokens (PATs). All authentication must flow through OAuth Device Authorization (RFC 8628) or IDE native session providers (vscode.authentication.getSession).

2. INV-FAST-FORWARD-RETRY

Concurrent writes to refs/md-comments/data must never overwrite remote changes forcefully. When a push conflict (409 Conflict) occurs, the engine performs a three-way merge against the latest remote commit using jittered exponential backoff.

3. INV-ZERO-CLIENT-SECRETS

Client-side packages (vscode-extension, chrome-extension, obsidian-plugin, starlight-plugin) must never bundle client secrets or privileged credentials. Telemetry and OAuth endpoints utilize public client IDs or the dedicated proxy in infrastructure/.

4. INV-ZERO-CUSTOMER-DATA

Telemetry payloads must never contain raw Markdown document contents, comment text, author names, email addresses, or repository file paths. Only anonymized action counts, latency timings, and sanitized error categories are permitted.

5. INV-TELEMETRY-KILLSWITCH

When telemetry.enabled is false or the global environment killswitch is tripped, all telemetry collection and network dispatches must immediately cease without delay or caching.

6. INV-VISUAL-PARITY

The visual presentation of comment cards, badges, gutter markers, and sidebar drawers must maintain 100% typographic and aesthetic parity across VS Code, Chrome, Obsidian, and Starlight.

7. INV-XSS-SANITIZED

Rendered comment Markdown and user inputs must pass through strict DOM sanitization before being inserted into any webview or browser DOM tree, preventing script execution and HTML attribute injection.

8. INV-QUOTA-DEFENSE

All interactions with GitHub REST APIs must utilize conditional requests (If-None-Match with ETags) and reuse cached tree SHAs to prevent consuming GitHub API hourly rate limits.

9. INV-IN-PLACE-PREVIEW

Native preview comments, replies, edits, reactions, and deletions must update in-place in the preview DOM without reloading the markdown document DOM. Full document refreshes cause blank screen flashes, scroll position jumps, and tab resets.

10. INV-MUTATION-GUARD

DOM badge counter listeners and MutationObservers must verify that element.textContent !== newContent prior to mutating DOM nodes. Unconditional assignments cause recursive MutationObserver loops that saturate CPU cores at 100%.

11. INV-BASE-TREE-SHA

When constructing new Git trees via GitHub Git Data API (POST /git/trees), the base_tree parameter must be the 40-character SHA of a Git Tree object (commitData.tree.sha), retrieved via GET /git/commits/:sha. Supplying a Commit object SHA triggers an unrecoverable 422 Unprocessable Entity error.

12. INV-AUTH-PERSISTENCE

VS Code authentication state must persist across window reloads and restarts via context.globalState. State modifications must fire reactive onDidChangeAuthState events to update webview indicators and action permissions.

13. INV-MODAL-CONFIRMATION

Destructive user actions within native preview webviews (e.g., deleting threads or replies) must display an accessible in-preview modal confirmation dialog. Native OS modal prompts block the thread and cause event propagation bugs.

14. INV-SILENT-BG-REFRESH

Background comment refresh loops and polling routines must execute silently. Extensions must never display toast notifications, steal window focus, or interrupt active typing during routine background syncs.


Part II: Architectural Decision Records (ADRs)

ADR-001: Orphan Git Reference (refs/md-comments/data) for Comment Storage

  • Status: Accepted
  • Context: Storing comments directly inside Markdown files pollutes documents with proprietary HTML tags or anchor markers. Storing comments in an external cloud database introduces single points of failure, privacy risks, and vendor lock-in.
  • Decision: Persist comments outside source branches using an orphan Git reference named refs/md-comments/data. Comments are stored as YAML documents keyed by document path and thread ID.
  • Consequences:
    • Positive: Source Markdown remains 100% clean. Comment history is versioned, distributed, and decentralized via existing Git workflows.
    • Negative: Requires implementing Git Data API serialization and three-way merging for concurrent push resolution.

ADR-002: FNV-1a Hash Anchoring with Context-Aware Fuzzy Fallback

  • Status: Accepted
  • Context: Line numbers alone are unstable anchors because document edits shift lines up and down.
  • Decision: Compute a deterministic 32-bit FNV-1a hash of normalized selected text along with a 3-line leading and trailing context window. When document modifications occur, apply a cascading fuzzy search (Exact Hash $\to$ Normalized Whitespace $\to$ Contextual Levenshtein Search).
  • Consequences:
    • Positive: High resilience against minor upstream document changes without losing comment attachments.
    • Negative: Substantial document rewrites require explicit author re-anchoring.

ADR-003: Zero-PAT RFC 8628 OAuth Device Flow Architecture

  • Status: Accepted
  • Context: Traditional browser extensions frequently require users to generate and paste GitHub Personal Access Tokens (PATs), which pose severe security risks and poor user experience.
  • Decision: Adopt RFC 8628 OAuth Device Authorization Flow (INV-OAUTH-ONLY). Users authorize via standard GitHub one-time code prompts. Tokens are stored securely in browser storage or IDE secrets without exposing secrets to client bundles.
  • Consequences:
    • Positive: Zero friction for users, zero leaked PATs, aligned with modern GitHub security recommendations.
    • Negative: Requires polling GitHub token endpoint during the authorization handshake.

ADR-004: In-Place DOM Surgery & Synchronous Early Hooking in Webview Preview

  • Status: Accepted
  • Context: In VS Code native Markdown preview, updating comments by re-rendering the document causes white screen flickering, loses scroll position, resets video/iframe state, and drops user focus. Furthermore, extension scripts executing after document load cannot intercept early events.
  • Decision: Implement a synchronous bootstrap hook (earlyHook.js) that immediately caches acquireVsCodeApi() and polyfills window.poster. Update preview comments using targeted in-place DOM patching (preview-webview.js) guarded by MutationObserver equality checks (INV-IN-PLACE-PREVIEW, INV-MUTATION-GUARD).
  • Consequences:
    • Positive: Instantaneous optimistic UI reactions, zero scroll jump, zero blank screen flicker, zero infinite loop CPU pegging.
    • Negative: Requires maintaining precise DOM element selectors and in-situ modal markup.

ADR-005: Zero-Secret Telemetry Proxy Architecture

  • Status: Accepted
  • Context: Collecting diagnostic and performance telemetry must never leak customer intellectual property or expose private cloud credentials.
  • Decision: Deploy a stateless proxy (infrastructure/) that scrubs all PII, document text, and file paths (INV-ZERO-CUSTOMER-DATA), authenticating against OpenTelemetry ingestion backends using server-side secrets while clients operate without embedded secrets (INV-ZERO-CLIENT-SECRETS).
  • Consequences:
    • Positive: Guarantees client privacy and prevents credential extraction from client distribution bundles.
    • Negative: Incurs a minor network hop for telemetry transport.