fix(gsd): address remaining adversarial review findings for wave 3
1. hasImplementationArtifacts "unknown" now blocks completion instead of warn-and-proceed. Both auto-dispatch.ts and auto-recovery.ts updated to treat "unknown" as a stop condition, preventing milestone completion when git status cannot be verified. 2. Audit log SAFE_KEYS allowlist expanded to include "id", "error", and "count" fields. SPLIT BRAIN logError entries now persist the entity ID and rollback error details to audit-log.jsonl for triage/repair.
This commit is contained in:
parent
42141d8979
commit
a9c62adf22
3 changed files with 8 additions and 3 deletions
|
|
@ -776,7 +776,11 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|||
};
|
||||
}
|
||||
if (artifactCheck === "unknown") {
|
||||
logWarning("dispatch", `Implementation artifact check inconclusive for ${mid} — proceeding with caution`);
|
||||
return {
|
||||
action: "stop",
|
||||
reason: `Cannot verify implementation artifacts for milestone ${mid}: git check was inconclusive. Resolve git issues and retry.`,
|
||||
level: "error",
|
||||
};
|
||||
}
|
||||
|
||||
// Verification class compliance: if operational verification was planned,
|
||||
|
|
|
|||
|
|
@ -393,7 +393,8 @@ export function verifyExpectedArtifact(
|
|||
// A milestone with only .gsd/ plan files and zero implementation code is
|
||||
// not genuinely complete — the LLM wrote plan files but skipped actual work.
|
||||
if (unitType === "complete-milestone") {
|
||||
if (hasImplementationArtifacts(base) === "absent") return false;
|
||||
const artifactResult = hasImplementationArtifacts(base);
|
||||
if (artifactResult === "absent" || artifactResult === "unknown") return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -295,7 +295,7 @@ function _sanitizeForAudit(entry: LogEntry): LogEntry {
|
|||
};
|
||||
if (entry.context) {
|
||||
// Allowlist: only persist known-safe structured keys
|
||||
const SAFE_KEYS = new Set(["fn", "tool", "mid", "sid", "tid", "worktree"]);
|
||||
const SAFE_KEYS = new Set(["fn", "tool", "mid", "sid", "tid", "worktree", "id", "error", "count"]);
|
||||
const filtered: Record<string, string> = {};
|
||||
for (const [k, v] of Object.entries(entry.context)) {
|
||||
if (SAFE_KEYS.has(k)) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue