feat: VersionGuard — newer-major sidecars are read-only with one warning (F5 SLICE-2, INV-16/PUC-4, #14)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* 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 { CoauthorStore } from "./store";
|
||||
|
||||
export class VersionGuard {
|
||||
private readonly warned = new Set<string>();
|
||||
|
||||
constructor(private readonly store: CoauthorStore) {}
|
||||
|
||||
/** 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user