From dc76d1ea4ca49d6987215bfc70ee66e1fbb7dbc6 Mon Sep 17 00:00:00 2001
From: Youzini-afk <13153778771cx@gmail.com>
Date: Tue, 28 Apr 2026 17:48:34 +0800
Subject: [PATCH] feat(authority): add consistency repair actions
---
index.js | 97 +++++++++++++++++++++++++++++++++
tests/authority-consistency.mjs | 1 +
ui/panel.js | 31 +++++++++++
3 files changed, 129 insertions(+)
diff --git a/index.js b/index.js
index 24295cd..de2973a 100644
--- a/index.js
+++ b/index.js
@@ -2840,6 +2840,96 @@ async function restoreAuthorityCheckpointFromBlob(options = {}) {
}
}
+async function writeAuthorityCheckpointFromCurrentGraph(options = {}) {
+ const settings = getSettings();
+ const { capability } = getAuthorityRuntimeSnapshot(settings);
+ const updatedAt = new Date().toISOString();
+ const chatId = normalizeChatIdCandidate(
+ options.chatId || getCurrentChatId() || graphPersistenceState.chatId || currentGraph?.chatId,
+ );
+ if (!chatId) {
+ return {
+ success: false,
+ error: "missing-chat-id",
+ };
+ }
+ if (!capability.blobReady || !shouldUseAuthorityBlobCheckpoint()) {
+ return {
+ success: false,
+ error: "Authority Blob unavailable",
+ };
+ }
+
+ ensureCurrentGraphRuntimeState();
+ if (!currentGraph) {
+ return {
+ success: false,
+ error: "Authority runtime graph unavailable",
+ };
+ }
+
+ const revision = Math.max(
+ 1,
+ Number(options.revision || 0),
+ Number(currentGraph?.meta?.revision || 0),
+ Number(getGraphPersistedRevision(currentGraph) || 0),
+ Number(graphPersistenceState.revision || 0),
+ );
+ const integrity =
+ normalizeChatIdCandidate(options.integrity) ||
+ normalizeChatIdCandidate(getGraphPersistenceMeta(currentGraph)?.integrity) ||
+ getChatMetadataIntegrity(getContext()) ||
+ graphPersistenceState.metadataIntegrity;
+ const reason = String(options.reason || "manual-authority-checkpoint");
+ const checkpoint = buildLukerGraphCheckpointV2(currentGraph, {
+ revision,
+ chatId,
+ integrity,
+ reason,
+ storageTier: "authority-sql-primary",
+ persistedAt: updatedAt,
+ });
+ if (!checkpoint) {
+ return {
+ success: false,
+ error: "Authority checkpoint payload unavailable",
+ };
+ }
+
+ const writeResult = await writeAuthorityLukerCheckpointBlob(checkpoint, {
+ chatId,
+ reason,
+ signal: options.signal,
+ });
+ if (!writeResult?.ok) {
+ return {
+ success: false,
+ error:
+ writeResult?.error?.message ||
+ writeResult?.reason ||
+ "authority-blob-checkpoint-write-failed",
+ };
+ }
+
+ const auditResult = await runAuthorityConsistencyAudit({
+ chatId,
+ collectionId:
+ normalizeChatIdCandidate(options.collectionId) ||
+ normalizeChatIdCandidate(currentGraph?.vectorIndexState?.collectionId) ||
+ buildVectorCollectionId(chatId),
+ }).catch(() => null);
+ return {
+ success: true,
+ result: {
+ path: writeResult.path,
+ revision,
+ checkpointRevision: Number(checkpoint.revision || revision || 0),
+ auditSummary: auditResult?.audit?.summary || null,
+ auditActions: auditResult?.audit?.actions || [],
+ },
+ };
+}
+
async function submitAuthorityVectorRebuildJob({
config = null,
range = null,
@@ -21404,6 +21494,12 @@ async function onRunAuthorityConsistencyAudit() {
});
}
+async function onWriteAuthorityCheckpoint() {
+ return await writeAuthorityCheckpointFromCurrentGraph({
+ reason: "panel-authority-checkpoint-write",
+ });
+}
+
async function onRestoreAuthorityCheckpoint() {
return await restoreAuthorityCheckpointFromBlob({
reason: "panel-authority-checkpoint-restore",
@@ -21996,6 +22092,7 @@ async function onCompactLukerSidecar() {
requeueAuthorityJob: async (jobId) => await requeueAuthorityJob(jobId),
refreshAuthorityJobs: onRefreshAuthorityJobs,
runAuthorityConsistencyAudit: onRunAuthorityConsistencyAudit,
+ writeAuthorityCheckpoint: onWriteAuthorityCheckpoint,
restoreAuthorityCheckpoint: onRestoreAuthorityCheckpoint,
captureAuthorityPerformanceBaseline: onCaptureAuthorityPerformanceBaseline,
reembedDirect: onReembedDirect,
diff --git a/tests/authority-consistency.mjs b/tests/authority-consistency.mjs
index 64f3569..982d1e9 100644
--- a/tests/authority-consistency.mjs
+++ b/tests/authority-consistency.mjs
@@ -145,5 +145,6 @@ assert.equal(auditDrift.summary.level, "warning");
assert.ok(auditDrift.issues.some((issue) => issue.code === "sql-runtime-revision-drift"));
assert.ok(auditDrift.issues.some((issue) => issue.code === "vector-dirty"));
assert.ok(auditDrift.actions.includes("rebuild-authority-trivium"));
+assert.ok(auditDrift.actions.includes("write-authority-checkpoint"));
console.log("authority-consistency tests passed");
diff --git a/ui/panel.js b/ui/panel.js
index b688bb2..8278ff6 100644
--- a/ui/panel.js
+++ b/ui/panel.js
@@ -3248,13 +3248,27 @@ function _refreshTaskPersistence() {
["诊断包时间", authorityBundleUpdatedLabel],
["诊断包原因", ps.authorityDiagnosticsBundleReason || "—"],
];
+ const authorityAuditActions = Array.isArray(ps.authorityConsistencyAudit?.actions)
+ ? ps.authorityConsistencyAudit.actions.map((value) => String(value || "").trim()).filter(Boolean)
+ : [];
+ const showAuthorityCheckpointWriteAction =
+ authorityAuditActions.includes("write-authority-checkpoint") ||
+ (!ps.authorityBlobCheckpointPath && ps.authorityBlobReady);
+ const showAuthorityTriviumRebuildAction =
+ authorityAuditActions.includes("rebuild-authority-trivium");
const authorityActionButtons = [
typeof _actionHandlers.runAuthorityConsistencyAudit === "function"
? ``
: "",
+ showAuthorityCheckpointWriteAction && typeof _actionHandlers.writeAuthorityCheckpoint === "function"
+ ? ``
+ : "",
typeof _actionHandlers.restoreAuthorityCheckpoint === "function"
? ``
: "",
+ showAuthorityTriviumRebuildAction && typeof _actionHandlers.rebuildVectorIndex === "function"
+ ? ``
+ : "",
typeof _actionHandlers.captureAuthorityPerformanceBaseline === "function"
? ``
: "",
@@ -3321,6 +3335,15 @@ function _refreshTaskPersistence() {
} else {
toastr.warning(`Authority 审计失败:${result?.error || "unknown"}`, "ST-BME");
}
+ } else if (action === "checkpoint") {
+ if (typeof _actionHandlers.writeAuthorityCheckpoint !== "function") return;
+ toastr.info("Authority Checkpoint 写入中…", "ST-BME", { timeOut: 2000 });
+ const result = await _actionHandlers.writeAuthorityCheckpoint();
+ if (result?.success) {
+ toastr.success(`Authority Checkpoint 已写入:rev ${Number(result?.result?.checkpointRevision || result?.result?.revision || 0) || "?"}`, "ST-BME");
+ } else {
+ toastr.warning(`Authority Checkpoint 写入失败:${result?.error || "unknown"}`, "ST-BME");
+ }
} else if (action === "restore") {
if (typeof _actionHandlers.restoreAuthorityCheckpoint !== "function") return;
toastr.info("Authority Checkpoint 恢复中…", "ST-BME", { timeOut: 2000 });
@@ -3330,6 +3353,10 @@ function _refreshTaskPersistence() {
} else {
toastr.warning(`Authority Checkpoint 恢复失败:${result?.error || "unknown"}`, "ST-BME");
}
+ } else if (action === "rebuild-trivium") {
+ if (typeof _actionHandlers.rebuildVectorIndex !== "function") return;
+ await _actionHandlers.rebuildVectorIndex();
+ return;
} else if (action === "baseline") {
if (typeof _actionHandlers.captureAuthorityPerformanceBaseline !== "function") return;
const result = await _actionHandlers.captureAuthorityPerformanceBaseline();
@@ -3349,6 +3376,10 @@ function _refreshTaskPersistence() {
toastr.error(
action === "restore"
? `Authority Checkpoint 恢复失败: ${error?.message || error}`
+ : action === "checkpoint"
+ ? `Authority Checkpoint 写入失败: ${error?.message || error}`
+ : action === "rebuild-trivium"
+ ? `Authority Trivium 重建失败: ${error?.message || error}`
: action === "baseline"
? `Authority Perf Baseline 捕获失败: ${error?.message || error}`
: `Authority 审计失败: ${error?.message || error}`,