This commit is contained in:
solrza-dev 2026-08-14 15:42:29 +02:00 committed by GitHub
commit e9fdd13cf0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 34 additions and 4 deletions

View File

@ -38,7 +38,12 @@ def _fmt_pending_list(subsystem: str) -> str:
for r in records:
origin = r.get("origin", "foreground")
tag = " [auto]" if origin == "background_review" else ""
lines.append(f" {r['id']}{tag} {r.get('summary', '')}")
badge = ""
v = r.get("validation")
if v and v != "ok":
reason = v[len("blocked: "):] if v.startswith("blocked: ") else v
badge = " \u26a0\ufe0f BLOCKED: %s" % reason[:70]
lines.append(f" {r['id']}{tag}{badge} {r.get('summary', '')}")
where = "/{s} approve <id>".format(s=subsystem)
lines.append("")
lines.append(f"Apply: {where} Reject: /{subsystem} reject <id>")

View File

@ -1459,10 +1459,29 @@ def _apply_skill_write_gate(action, name, **payload_kwargs):
old_string=payload_kwargs.get("old_string") or "",
new_string=payload_kwargs.get("new_string") or "",
)
record = wa.stage_write(wa.SKILLS, payload, summary=gist, origin=wa.current_origin())
# Pre-validate creates at staging time so a record that can never be
# applied (frontmatter description over SKILL_PROMPT_DESC_LIMIT, missing
# name, missing frontmatter, etc.) is flagged immediately instead of
# failing later at /skills approve — the exact trap that left 26 blocked
# creates in the backlog. The record is STILL staged (nothing is lost);
# the blocker is recorded, shown in /skills pending, and echoed in the
# response so the agent can fix the description before approving.
validation = "ok"
if action == "create":
try:
err = _validate_frontmatter(payload.get("content") or "", new_skill=True)
if err:
validation = "blocked: " + err.splitlines()[0]
except Exception:
validation = "ok" # fail open: never block staging on validator bugs
record = wa.stage_write(
wa.SKILLS, payload, summary=gist, origin=wa.current_origin(),
validation=validation,
)
return json.dumps(
{"success": True, "staged": True, "pending_id": record["id"],
"gist": gist, "message": decision.message},
"gist": gist, "message": decision.message,
"validation": validation},
ensure_ascii=False,
)

View File

@ -112,7 +112,7 @@ def _pending_dir(subsystem: str) -> Path:
def stage_write(subsystem: str, payload: Dict[str, Any],
*, summary: str, origin: str) -> Dict[str, Any]:
*, summary: str, origin: str, validation: str = "ok") -> Dict[str, Any]:
"""Persist a pending write and return a short record describing it.
Args:
@ -124,6 +124,11 @@ def stage_write(subsystem: str, payload: Dict[str, Any],
For skills this is the LLM/heuristic gist; for memory it can be the
entry text itself.
origin: ``foreground`` or ``background_review`` — recorded for audit.
validation: pre-computed apply-time check result for the staged write.
``"ok"`` (default) means it will apply; anything else is a short
``"blocked: <reason>"`` flag surfaced in pending lists so a record
that can never be applied is visible before approval. Recorded for
audit; never used to refuse staging (a staged write is never lost).
Returns a dict with ``id`` and metadata. Best-effort: on disk failure it
logs and still returns a record (the write is simply lost, which is the
@ -136,6 +141,7 @@ def stage_write(subsystem: str, payload: Dict[str, Any],
"action": payload.get("action", ""),
"summary": (summary or "").strip(),
"origin": origin or "foreground",
"validation": validation,
"created_at": time.time(),
"payload": payload,
}