feat: gate FK review on the accepted revision blob (P5)
This commit is contained in:
@@ -244,23 +244,9 @@ export class WorkspacePreprocessingService {
|
||||
if (request.reviewed_candidates_digest !== reviewedCandidatesDigest || typeof request.annotations_digest !== "string") {
|
||||
return baseResult(runtime, "schema check", "failed", "annotation_invalid", { runId });
|
||||
}
|
||||
const annotationsDigest = request.annotations_digest;
|
||||
const review = state.writeFkReview(runId, {
|
||||
reviewedCandidatesDigest,
|
||||
annotationsDigest,
|
||||
workspaceRevision: runtime.workspaceRevision,
|
||||
});
|
||||
const job = state.readJob(runId);
|
||||
if (!job.completedStages.includes("fk_review")) {
|
||||
job.reviewDigest = review.digest;
|
||||
job.completedStages.push("fk_review");
|
||||
state.writeJob(job);
|
||||
}
|
||||
return baseResult(runtime, "schema check", "succeeded", "ok", {
|
||||
runId,
|
||||
completedStages: [...job.completedStages],
|
||||
artifactIdentities: [{ kind: "fk_review", digest: review.digest }],
|
||||
});
|
||||
// P5 supersedes the host-file FK review: schema check is read-only validation and never
|
||||
// records a review. Only `schema accept` records a human review for the curated Git blob.
|
||||
return baseResult(runtime, "schema check", "succeeded", "ok", { runId });
|
||||
}
|
||||
|
||||
async acceptSchema(options: { workspaceId: string; runId: string; yes?: boolean }): Promise<WorkspaceOperationResult> {
|
||||
@@ -392,10 +378,12 @@ export class WorkspacePreprocessingService {
|
||||
}
|
||||
const candidate = this.state(scope.runtime.workspaceId).readFkCandidates(scope.job.runId);
|
||||
if (candidate && !scope.job.completedStages.includes("fk_review")) {
|
||||
// The candidate content digest is authoritative: a human review accepted for ANY run
|
||||
// carrying the exact same candidate digest counts as the review checkpoint for this run.
|
||||
// P5: continuation requires a review accepted for this candidate whose accepted blob digest
|
||||
// equals the current revision's synced annotations. A revision change (or a missing curated
|
||||
// blob) therefore records a new review checkpoint instead of silently reusing the old one.
|
||||
const accepted = this.findAcceptedReviewForDigest(scope.runtime.workspaceId, candidate.digest);
|
||||
if (!accepted) {
|
||||
const currentDigest = this.currentAnnotationsDigest(scope.runtime);
|
||||
if (accepted === undefined || currentDigest === undefined || accepted.annotationsDigest !== currentDigest) {
|
||||
return baseResult(scope.runtime, "preprocess run", "blocked", "manual_review_required", {
|
||||
runId: scope.job.runId,
|
||||
childRuns: { ...scope.job.childRuns },
|
||||
@@ -562,6 +550,10 @@ export class WorkspacePreprocessingService {
|
||||
}
|
||||
}
|
||||
|
||||
private currentAnnotationsDigest(runtime: ActiveRuntime): string | undefined {
|
||||
return readAnnotationsSync(this.deps.dataRoot, runtime.workspaceId, runtime.workspaceRevision)?.contentDigest;
|
||||
}
|
||||
|
||||
private findAcceptedReviewForDigest(
|
||||
workspaceId: string,
|
||||
digestValue: string,
|
||||
|
||||
Reference in New Issue
Block a user