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:
@@ -15,6 +15,7 @@ import { emptyArtifact, type Artifact, type Fingerprint, type Proposal, type Pro
|
||||
import { resolve, shift, type OffsetRange } from "./anchorer";
|
||||
import { addProposal, proposalBody, removeProposal } from "./proposalModel";
|
||||
import type { AttributionController } from "./attributionController";
|
||||
import type { VersionGuard } from "./versionGuard";
|
||||
|
||||
/** Test-facing snapshot of what is currently rendered for a document. */
|
||||
export interface RenderedProposal {
|
||||
@@ -53,6 +54,7 @@ export class ProposalController implements vscode.Disposable {
|
||||
private readonly store: CoauthorStore,
|
||||
private readonly attribution: AttributionController,
|
||||
private readonly rootDir: string,
|
||||
private readonly guard: VersionGuard,
|
||||
) {
|
||||
// No commentingRangeProvider: humans never open proposal threads by hand —
|
||||
// proposals are born of machine turns only (INV-12 keeps decisions human).
|
||||
@@ -103,6 +105,7 @@ export class ProposalController implements vscode.Disposable {
|
||||
opts?: { turnId?: string; instruction?: string },
|
||||
): Promise<string | undefined> {
|
||||
if (!this.isTracked(document)) return undefined;
|
||||
if (this.guard.isReadOnly(this.docPathOf(document.uri))) return undefined;
|
||||
const docPath = this.docPathOf(document.uri);
|
||||
let proposalId: string | undefined;
|
||||
this.store.update(docPath, (a) => {
|
||||
@@ -137,6 +140,7 @@ export class ProposalController implements vscode.Disposable {
|
||||
}
|
||||
|
||||
private async accept(state: DocState, proposal: Proposal): Promise<boolean> {
|
||||
if (this.guard.isReadOnly(state.docPath)) return false;
|
||||
const document = this.openDoc(state);
|
||||
if (!document) return false;
|
||||
// INV-11: the fingerprint-guard — exact re-resolve at decision time.
|
||||
@@ -167,6 +171,7 @@ export class ProposalController implements vscode.Disposable {
|
||||
}
|
||||
|
||||
private reject(state: DocState, proposal: Proposal): void {
|
||||
if (this.guard.isReadOnly(state.docPath)) return;
|
||||
this.store.update(state.docPath, (a) => removeProposal(a, proposal.id));
|
||||
const document = this.openDoc(state);
|
||||
if (document) this.renderAll(document);
|
||||
|
||||
Reference in New Issue
Block a user