CtrlK
BlogDocsLog inGet started
Tessl Logo

jbaruch/coding-policy

General-purpose coding policy for Baruch's AI agents

73

Quality

91%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Low

Low-risk findings worth noting

Overview
Quality
Evals
Security
Files

attention.pyskills/herdr-foreman/foreman/

"""Foreman-owned obligations: explicit lifecycle events, independent of Herdr status."""

import copy
import json
import re
from datetime import timezone
from pathlib import Path
from typing import NoReturn

from . import runnable
from .chronology import timestamp
from .errors import StateError, UsageError
from .state import save_state, state_lock

SCHEMA_VERSION = 1
IDENTIFIER = re.compile(r"[A-Za-z0-9][A-Za-z0-9._:-]{0,127}\Z")
KINDS = {"question", "decision", "review", "blocker", "failure", "followup", "update"}
CLOSED = {"resolved", "superseded"}
#: Obligation kinds whose open entry on a task refuses further dispatch on
#: that task (#399). A `decision` resolves only with the user's answer and a
#: `blocker` only with an answer, acknowledgement or verified recovery, so an
#: open one is a question the foreman asked and has not received; dispatching
#: anyway is the third state where work proceeds while the gate is nominally
#: open. `question`, `review`, `failure`, `followup` and `update` never gate.
GATING_KINDS = frozenset({"decision", "blocker"})
COMMANDS = {"attention-record", "attention-update", "attention-progress", "attention-list", "attention-show", "catch-up"}


def canonical_state(path):
    return Path(path).expanduser().resolve()


def storage_path(path):
    return Path(str(canonical_state(path)) + ".attention.json")


def _fail(message) -> NoReturn:
    raise UsageError(message, {})


def _text(value, label, *, limit=8000):
    if not isinstance(value, str) or not value.strip() or len(value) > limit:
        _fail("{} must contain 1–{} characters; record the actual obligation and evidence.".format(label, limit))
    return value


def _id(value):
    if not isinstance(value, str) or not IDENTIFIER.fullmatch(value):
        _fail("Attention ids need 1–128 letters, digits, dots, underscores, colons or hyphens; reuse the original id when retrying.")
    return value


def _utc(value):
    return timestamp(value, "Attention timestamp").astimezone(timezone.utc).isoformat()


def _fields(data, required, optional=()):
    if not isinstance(data, dict) or not set(required) <= set(data) or set(data) - set(required) - set(optional):
        _fail("Attention input requires {} and accepts only optional {}; inspect references/attention.md and retry without changing saved state.".format(
            ", ".join(sorted(required)), ", ".join(sorted(optional)) or "none"))


def _sources(value):
    if not isinstance(value, list) or not value or len(value) > 30:
        _fail("Attention sources must contain 1–30 explicit source references; include the user message, ledger or artifact supporting the entry.")
    for row in value:
        _fields(row, {"schema_version", "kind", "ref"})
        if type(row["schema_version"]) is not int or row["schema_version"] != SCHEMA_VERSION:
            _fail("Attention source schema_version must be 1; preserve unsupported records and update the owner.")
        if not isinstance(row["kind"], str) or row["kind"] not in {"user_message", "task_ledger", "retrospective", "artifact", "other"}:
            _fail("Attention source kind must be user_message, task_ledger, retrospective, artifact or other.")
        _text(row["ref"], "Source reference", limit=2000)
    return copy.deepcopy(value)


def _details(data):
    for key in ("title", "context", "consequence", "resolution_condition"):
        _text(data[key], key, limit=300 if key == "title" else 8000)
    if type(data["priority"]) is not int or not 0 <= data["priority"] <= 100:
        _fail("Attention priority must be a foreman-assigned integer from 0 to 100, with 100 most consequential.")
    if not isinstance(data["options"], list) or len(data["options"]) > 10:
        _fail("Attention options must list at most 10 choices; use [] when choices do not apply.")
    for option in data["options"]:
        _text(option, "Option", limit=2000)
    if data["recommendation"] is not None:
        _text(data["recommendation"], "Recommendation")
    _sources(data["sources"])


def _creation(data):
    _fields(data, {"id", "kind", "title", "context", "consequence", "resolution_condition", "sources"},
            {"task", "priority", "options", "recommendation"})
    result = {"task": None, "priority": 50, "options": [], "recommendation": None, **copy.deepcopy(data)}
    _id(result["id"])
    _text(result["id"], "Obligation id", limit=110)
    if not isinstance(result["kind"], str) or result["kind"] not in KINDS:
        _fail("Attention kind must be question, decision, review, blocker, failure, followup or update.")
    if result["task"] is not None:
        _text(result["task"], "Task", limit=500)
    _details(result)
    return result


def _evidence(value):
    _fields(value, {"schema_version", "kind", "ref", "summary"})
    if type(value["schema_version"]) is not int or value["schema_version"] != SCHEMA_VERSION:
        _fail("Resolution evidence schema_version must be 1; preserve unsupported evidence.")
    if not isinstance(value["kind"], str) or value["kind"] not in {"user_answer", "review_outcome", "delivery", "acknowledgement", "verified_outcome", "source"}:
        _fail("Evidence kind must be user_answer, review_outcome, delivery, acknowledgement, verified_outcome or source.")
    _text(value["ref"], "Evidence reference", limit=2000)
    _text(value["summary"], "Evidence summary")


def _update(data):
    _fields(data, {"event_id", "id", "expected_revision", "action", "reason"}, {"evidence", "until", "replacement", "changes"})
    for key in ("id", "event_id"):
        _id(data[key])
    if type(data["expected_revision"]) is not int or data["expected_revision"] < 1:
        _fail("expected_revision must match the current entry revision; read `{}` before updating stale context.".format(
            runnable.command("attention-show")))
    _text(data["reason"], "Lifecycle reason")
    extras = {"present": {"evidence"}, "resolve": {"evidence"}, "defer": {"until", "evidence"},
              "reopen": {"evidence"}, "supersede": {"replacement", "evidence"}, "amend": {"changes", "evidence"}}
    action = data["action"]
    if not isinstance(action, str) or action not in extras:
        _fail("Attention action must be present, resolve, defer, reopen, supersede or amend; unrelated messages have no lifecycle action.")
    if set(data) - {"event_id", "id", "expected_revision", "action", "reason"} != extras[action]:
        _fail("Attention {} requires only its additional fields: {}.".format(action, ", ".join(sorted(extras[action]))))
    _evidence(data["evidence"])
    result = copy.deepcopy(data)
    if action == "defer":
        result["until"] = _utc(data["until"])
    if action == "supersede":
        _id(data["replacement"])
    return result


def _progress(data):
    _fields(data, {"id", "task", "summary", "assessment", "sources"})
    _id(data["id"])
    _text(data["id"], "Progress id", limit=110)
    _text(data["task"], "Progress task", limit=500)
    _text(data["summary"], "Progress summary")
    if not isinstance(data["assessment"], str) or data["assessment"] not in {"verified", "reported", "unknown"}:
        _fail("Progress assessment must be verified, reported or unknown; Herdr completion labels never prove acceptance.")
    _sources(data["sources"])
    if not any(row["kind"] == "task_ledger" for row in data["sources"]):
        _fail("Progress requires its task_ledger source reference; a cached summary never replaces the acceptance ledger.")
    return copy.deepcopy(data)


def _apply(event, entries, progress):
    """Replay owner events; no wall clock, external reads, or inferred decisions."""
    action, data, at = event["action"], event["data"], event["at"]
    if action == "record":
        value = _creation(data)
        if value["id"] in entries:
            _fail("Duplicate obligation id in history; restore the original attention file.")
        entries[value["id"]] = {"schema_version": SCHEMA_VERSION, **value, "revision": 1, "status": "open",
                                "created_at": at, "updated_at": at, "last_presented_at": None,
                                "deferred_until": None, "resolution": None, "superseded_by": None}
        return
    if action == "progress":
        value = _progress(data)
        if any(row["id"] == value["id"] for row in progress):
            _fail("Duplicate progress id in history; preserve the source and restore the original file.")
        progress.append({"schema_version": SCHEMA_VERSION, **value, "at": at})
        return
    data = _update(data)
    entry = entries.get(data["id"])
    if entry is None or data["expected_revision"] != entry["revision"]:
        _fail("Attention entry is missing or its revision changed; read `{}` and reconcile before submitting a new event id.".format(
            runnable.command("attention-show")))
    action = data["action"]
    if action != "reopen" and entry["status"] in CLOSED:
        _fail("This attention entry is closed; use an evidenced reopen before changing it.")
    if action == "present":
        if data["evidence"]["kind"] != "delivery":
            _fail("Presentation needs delivery evidence identifying the actual user-facing message; displaying a local draft is not delivery.")
        entry["last_presented_at"] = at
    elif action == "resolve":
        allowed = {"question": {"user_answer"}, "decision": {"user_answer"}, "review": {"review_outcome"},
                   "blocker": {"user_answer", "acknowledgement", "verified_outcome"}, "failure": {"user_answer", "acknowledgement", "delivery", "verified_outcome"},
                   "followup": {"delivery"}, "update": {"delivery"}}
        if data["evidence"]["kind"] not in allowed[entry["kind"]]:
            _fail("{} requires {} evidence to resolve; presentation or an unrelated user message leaves it open.".format(entry["kind"], " or ".join(sorted(allowed[entry["kind"]]))))
        entry.update(status="resolved", resolution=copy.deepcopy(data["evidence"]), deferred_until=None)
    elif action == "defer":
        if timestamp(data["until"], "Resurface time") <= timestamp(at, "Deferral time"):
            _fail("Deferral must name a future resurface time; keep already-due obligations open.")
        entry.update(status="deferred", deferred_until=data["until"])
    elif action == "reopen":
        if entry["status"] == "open":
            _fail("Attention entry is already open; record new context with amend instead.")
        entry.update(status="open", deferred_until=None, resolution=None, superseded_by=None)
    elif action == "supersede":
        replacement = entries.get(data["replacement"])
        if replacement is None or replacement["status"] in CLOSED or replacement["id"] == entry["id"]:
            _fail("Record a distinct open replacement obligation before superseding this entry; never discard the question.")
        entry.update(status="superseded", superseded_by=replacement["id"], deferred_until=None)
    else:
        changes = data["changes"]
        fields = {"title", "context", "consequence", "resolution_condition", "sources", "options", "recommendation", "priority"}
        if not isinstance(changes, dict) or not changes or not set(changes) <= fields:
            _fail("Amend needs nonempty changes to title, context, consequence, resolution_condition, sources, options, recommendation or priority; supersede a different obligation.")
        _details({**entry, **changes})
        entry.update(copy.deepcopy(changes))
    entry["updated_at"] = at
    entry["revision"] += 1


def load(path):
    """Read and validate only. Missing means first use; malformed never means empty."""
    target = storage_path(path)
    document = {"schema_version": SCHEMA_VERSION, "state_path": str(canonical_state(path)), "events": []}
    try:
        document = json.loads(target.read_text(encoding="utf-8"))
    except FileNotFoundError:
        if target.is_symlink():
            raise StateError("Attention sidecar is a dangling link; restore its saved target before proceeding.", {}) from None
        return document, {}, []
    except (OSError, UnicodeDecodeError, ValueError) as exc:
        raise StateError("Cannot read attention history {}: {}. Preserve its bytes and restore access or its verified backup.".format(target, exc), {}) from None
    entries, progress, ids = {}, [], set()
    try:
        _fields(document, {"schema_version", "state_path", "events"})
        if (type(document["schema_version"]) is not int or document["schema_version"] != SCHEMA_VERSION
                or document["state_path"] != str(canonical_state(path)) or not isinstance(document["events"], list)):
            _fail("Unsupported attention schema or state identity; preserve the file and update its owner or recover the correct state path.")
        previous = None
        for event in document["events"]:
            _fields(event, {"schema_version", "event_id", "at", "action", "data"})
            if type(event["schema_version"]) is not int or event["schema_version"] != SCHEMA_VERSION:
                _fail("Unsupported attention event schema; update the owner without rewriting history.")
            _id(event["event_id"])
            at = timestamp(event["at"], "Saved attention event")
            if event["event_id"] in ids or (previous is not None and at < previous):
                _fail("Attention events contain duplicates or reversed chronology; restore the original history.")
            if not isinstance(event["action"], str) or event["action"] not in {"record", "update", "progress"}:
                _fail("Unknown attention event action; update the owner before writing.")
            expected_id = (("record:" if event["action"] == "record" else "progress:") + str(event["data"].get("id"))) if isinstance(event["data"], dict) and event["action"] != "update" else None
            if expected_id is not None and event["event_id"] != expected_id:
                _fail("Attention event id disagrees with its obligation; restore the original history.")
            if event["action"] == "update" and (not isinstance(event["data"], dict) or event["data"].get("event_id") != event["event_id"]):
                _fail("Attention lifecycle event identity changed; restore the original history.")
            _apply(event, entries, progress)
            previous = at
            ids.add(event["event_id"])
    except UsageError as exc:
        raise StateError("Attention history is unusable: {} Preserve it; do not replace it with an empty queue.".format(exc.message), {}) from None
    return document, entries, progress


def write(path, action, data, at):
    """Commit one event under the sidecar lock; identical retries never duplicate."""
    parsers = {"record": _creation, "update": _update, "progress": _progress}
    if action not in parsers:
        _fail("Unknown attention write; choose record, update or progress.")
    value = parsers[action](data)
    name = value["event_id"] if action == "update" else action + ":" + value["id"]
    _id(name)
    at = _utc(at)
    with state_lock(storage_path(path)):
        document, entries, progress = load(path)
        prior = next((event for event in document["events"] if event["event_id"] == name), None)
        if prior:
            if prior["action"] != action or prior["data"] != value:
                _fail("Attention event id already records different input; preserve it and use a new id for an intentional change.")
            return {"schema_version": SCHEMA_VERSION, "event": copy.deepcopy(prior), "replayed": True}
        if document["events"] and timestamp(at, "New event") < timestamp(document["events"][-1]["at"], "Latest event"):
            _fail("Attention event predates saved history; use the current checkpoint without rewriting earlier events.")
        event = {"schema_version": SCHEMA_VERSION, "event_id": name, "at": at, "action": action, "data": value}
        _apply(event, entries, progress)
        document["events"].append(event)
        save_state(storage_path(path), document)
    return {"schema_version": SCHEMA_VERSION, "event": event, "replayed": False}


def dispatch_gate(path, task, at):
    """Return the open obligations that refuse dispatch on `task`, oldest first.

    Reads the sidecar at `path` through `load`, so a malformed or unsupported
    history raises `StateError` and refuses dispatch rather than reading as an
    empty queue; missing storage is first use and gates nothing. A checkpoint
    predating the latest saved event is refused, as `attention_view.catch_up`
    refuses it: an earlier `--now` would read a due deferral as not yet due. An entry gates
    when its kind is in `GATING_KINDS`, its `task` equals `task`, and it is open
    or a deferral whose `deferred_until` has passed at `at` (the same
    resurfacing `attention_view.catch_up` reports). A `present` action never
    changes the result. `task` None gates nothing: obligations without a task
    describe no dispatch.
    """
    if task is None:
        return []
    now = timestamp(at, "Dispatch gate checkpoint")
    document, entries, _progress = load(path)
    if document["events"] and timestamp(document["events"][-1]["at"], "Latest attention event") > now:
        _fail("Dispatch checkpoint precedes saved attention events; use the current UTC checkpoint so a deferral cannot be read as not yet due.")
    gating = []
    for entry in entries.values():
        if entry["kind"] not in GATING_KINDS or entry["task"] != task:
            continue
        resurfaced = entry["status"] == "deferred" and timestamp(entry["deferred_until"], "Resurface time") <= now
        if entry["status"] != "open" and not resurfaced:
            continue
        gating.append({"id": entry["id"], "kind": entry["kind"], "title": entry["title"], "priority": entry["priority"],
                       "resolution_condition": entry["resolution_condition"], "resurfaced": resurfaced,
                       "created_at": entry["created_at"], "revision": entry["revision"]})
    gating.sort(key=lambda row: (row["created_at"], row["id"]))
    return gating


def require_dispatch_clear(path, task, at):
    """Raise `UsageError` naming every gating obligation on `task`, or return None."""
    gating = dispatch_gate(path, task, at)
    if not gating:
        return None
    first = gating[0]
    raise UsageError(
        "Dispatch on task {} is gated by unanswered {} {}: {} Resolve it with `{}` and the evidence "
        "its kind requires, or defer it with recorded rationale, then rerun this command.".format(
            task, first["kind"], first["id"], first["resolution_condition"], runnable.command("attention-update")),
        {"task": task, "gating": gating})


def show(path, name):
    document, entries, _progress_rows = load(path)
    if name not in entries:
        _fail("No attention entry matches {}; use `{}` with the same --state path.".format(name, runnable.command("attention-list")))
    return {"schema_version": SCHEMA_VERSION, "entry": entries[name],
            "history": [event for event in document["events"] if event["action"] != "progress" and event["data"]["id"] == name]}


def register_commands(sub, common):
    for command in ("attention-record", "attention-update", "attention-progress"):
        parser = sub.add_parser(command, parents=[common], help="Persist a foreman-owned attention or progress event.")
        parser.add_argument("--record", required=True, help="JSON input file; see references/attention.md.")
        parser.add_argument("--now", help="ISO-8601 checkpoint with timezone.")
    for command in ("attention-list", "catch-up"):
        parser = sub.add_parser(command, parents=[common], help="Read a bounded offline view of saved user-facing obligations.")
        parser.add_argument("--task")
        parser.add_argument("--limit", type=int, default=10)
        parser.add_argument("--offset", type=int, default=0)
        parser.add_argument("--since", help="Filter progress and closed history; never suppress open obligations.")
        parser.add_argument("--include-closed", action="store_true")
        parser.add_argument("--now", help="ISO-8601 checkpoint with timezone.")
    parser = sub.add_parser("attention-show", parents=[common], help="Read one obligation and its complete lifecycle history offline.")
    parser.add_argument("--id", required=True)
    parser.add_argument("--now", help="ISO-8601 checkpoint; history readback itself has no clock-dependent mutation.")


def run_command(args, state_path, now):
    if args.command in {"attention-record", "attention-update", "attention-progress"}:
        try:
            data = json.loads(Path(args.record).expanduser().read_text(encoding="utf-8"))
        except (OSError, UnicodeDecodeError, ValueError) as exc:
            raise UsageError("Cannot read attention input {}: {}. Save valid UTF-8 JSON and retry the same event id.".format(args.record, exc), {}) from None
        return write(state_path, args.command.removeprefix("attention-"), data, getattr(args, "now", None) or now)
    if args.command == "attention-show":
        return show(state_path, args.id)
    from .attention_view import catch_up
    return catch_up(state_path, getattr(args, "now", None) or now, task=args.task, limit=args.limit,
                    offset=args.offset, since=args.since, include_closed=args.include_closed)

skills

herdr-foreman

bounded-run.sh

compose-briefs.sh

config.example.json

foreman-tier-check.py

foreman.sh

label-workspaces.sh

provision-worktree.sh

prune-remote-branches.sh

prune-report-caches.py

prune-worktrees.sh

resolve-gates.sh

resolve-policy-paths.sh

review-package.sh

roster.sh

round-preflight.sh

SKILL.md

start-judge-worker.sh

state-schema.md

sweep-worktrees.sh

verify-authority.sh

wait-report.sh

README.md

tile.json