/** * VersionGuard — INV-16's editor face (spec §6.2/§6.4, PUC-4): a sidecar whose * schemaVersion major is newer than this extension understands is READ-ONLY. * Controllers render best-effort but skip every store.update path; the user is * warned ONCE per document. One shared instance (extension.ts) because the * sidecar is co-owned by three controllers — one warning, not three. The * store's update() throw is the backstop; this gate is the UX. */ import * as vscode from "vscode"; import { SCHEMA_VERSION, isNewerMajor } from "./model"; import type { SidecarStore } from "./sidecarStore"; export class VersionGuard { private readonly warned = new Set(); constructor(private readonly store: SidecarStore) {} /** True → skip the write path (and warn once per doc). */ isReadOnly(docPath: string): boolean { const artifact = this.store.load(docPath); if (!artifact || !isNewerMajor(artifact)) return false; if (!this.warned.has(docPath)) { this.warned.add(docPath); void vscode.window.showWarningMessage( `Cowriting: ${docPath}'s coauthoring sidecar is schemaVersion ${artifact.schemaVersion} — newer than this extension understands (${SCHEMA_VERSION}). Showing what it can; writing nothing (INV-16). Upgrade the extension to edit the record.`, ); } return true; } /** Test-facing: did the newer-major warning fire for this doc? */ wasWarned(docPath: string): boolean { return this.warned.has(docPath); } }