CtrlK
BlogDocsLog inGet started
Tessl Logo
PluginPublic

jbaruch/herdr-policy

Herdr team coordination policy for AI coding agents

Quality

93%

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

provision.pyskills/herdr-foreman/foreman/

"""Git-owned worktree base receipts and automatic brief provenance.

Herdr owns schema 1 in each worktree's private Git directory. Provisioning
records the original base; composition reads without modifying Git or owner state. A later
fetch never changes the original task base. See state-schema.md.
"""

import hashlib
import json
import os
import shlex
import subprocess
import sys
import tempfile
from pathlib import Path

from .errors import ForemanError, UsageError, owner_recovery
from .state import default_state_path, load_state_checked

FIELDS = {"schema_version", "path", "branch", "base_ref", "base_revision",
          "fetched_default_ref", "fetched_default_revision"}


def refuse(kind, message, *, path=None, base_revision=None, **evidence):
    operation = "bash " + shlex.quote(str(Path(__file__).resolve().parents[1] / "provision-worktree.sh"))
    return owner_recovery(UsageError(message, {}), kind, operation,
        "Use the same normal provisioning invocation. The owner fetches recorded commits when available; it must preserve this worktree and original base and stop while identity, commit availability or ancestry remains unproved.",
        path=str(path) if path is not None else None, base_revision=base_revision, **evidence)


def ensure_commit(path, revision, *, fetch=False, worktree=None, base_revision=None):
    selected = worktree or path
    original_base = base_revision or revision
    try:
        resolved = git(path, "rev-parse", "--verify", revision + "^{commit}")
    except UsageError as lookup:
        if not fetch:
            raise refuse("provision_commit_unavailable", "Recorded worktree commit is unavailable.",
                path=selected, base_revision=original_base, commit_revision=revision, lookup=lookup.to_dict()) from lookup
        try:
            git(path, "fetch", "--quiet", "origin", revision)
            resolved = git(path, "rev-parse", "--verify", revision + "^{commit}")
        except UsageError as exc:
            raise refuse("provision_commit_unavailable", "Authorized fetch could not establish the recorded original commit; existing work is preserved.",
                path=selected, base_revision=original_base, commit_revision=revision, cause=exc.to_dict()) from exc
    if resolved != revision:
        raise refuse("provision_commit_unavailable", "Recorded commit did not resolve exactly.", path=selected, base_revision=original_base, commit_revision=revision)


def require_ancestor(path, revision):
    try:
        git(path, "merge-base", "--is-ancestor", revision, "HEAD")
    except UsageError as exc:
        if exc.details.get("recovery", {}).get("evidence", {}).get("git_exit") != 1:
            raise
        raise refuse("provision_ancestry_conflict", "Worktree does not descend from its recorded task base; existing work is preserved.",
            path=path, base_revision=revision) from exc


def git(path, *args):
    result = subprocess.run(["git", "-C", str(path), *args], capture_output=True, text=True, check=False)
    if result.returncode:
        # Git network errors may echo credential-bearing remote URLs. Keep the
        # operation and exit code as evidence, never Git's untrusted stderr.
        raise refuse("provision_git_failed", "Cannot read worktree provenance: git {} failed (exit {}). Git stderr is withheld to protect credentials; restore repository metadata, origin access and recorded commit availability before retrying normal provisioning.".format(
            " ".join(args), result.returncode), path=path, git_args=list(args), git_exit=result.returncode)
    return result.stdout.strip()


def receipt_path(path):
    return Path(git(path, "rev-parse", "--path-format=absolute", "--git-path", "foreman-provision.json"))


def intent_path(shared, path):
    common = Path(git(shared, "rev-parse", "--path-format=absolute", "--git-common-dir"))
    identity = hashlib.sha256(str(Path(path).resolve()).encode()).hexdigest()
    return common / ("foreman-provision-" + identity + ".json")


def persist(location, saved):
    """Replace atomically without sharing or stranding a fixed scratch name."""
    temporary = None
    try:
        with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", dir=location.parent,
                                         prefix=location.name + ".", delete=False) as stream:
            temporary = Path(stream.name)
            stream.write(json.dumps(saved, indent=2) + "\n")
            stream.flush()
            os.fsync(stream.fileno())
        temporary.replace(location)
    except OSError as exc:
        raise refuse("provision_persistence_failed", "Cannot persist worktree base provenance: {}; existing work is preserved.".format(exc), path=saved["path"], base_revision=saved["base_revision"]) from None
    finally:
        if temporary is not None:
            try:
                temporary.unlink(missing_ok=True)
            except OSError as exc:
                print("provision: cannot clean owned scratch {}: {}; normal retries use a new scratch file.".format(temporary, exc), file=sys.stderr)


def prepare(shared, path, branch, base_ref, base_revision, default_ref, default_revision):
    """Persist the original base before any branch or worktree is created."""
    path = str(Path(path).resolve())
    location = intent_path(shared, path)
    saved = None
    if location.exists():
        saved = validate(json.loads(location.read_text(encoding="utf-8")))
    elif Path(path).exists():
        receipt = receipt_path(path)
        # Recover the complete scratch receipt left by older provisioning owners.
        candidate = receipt if receipt.exists() else receipt.with_suffix(".tmp")
        if candidate.exists():
            saved = validate(json.loads(candidate.read_text(encoding="utf-8")))
        else:
            raise refuse("provision_base_unproved", "Existing worktree has no owner-recorded original base; preserve it and select a worktree with its original receipt or recover its supported owner-written receipt before retrying.", path=path)
    if saved is not None:
        if saved["path"] != path or saved["branch"] != branch:
            raise refuse("provision_identity_changed", "Provisioning intent does not match this path and branch; preserve existing work.", path=path)
        for key in ("base_revision", "fetched_default_revision"):
            ensure_commit(shared, saved[key], fetch=True, worktree=path, base_revision=saved["base_revision"])
    else:
        saved = validate({"schema_version": 1, "path": path, "branch": branch,
                          "base_ref": base_ref, "base_revision": base_revision,
                          "fetched_default_ref": default_ref, "fetched_default_revision": default_revision})
    saved.update(fetched_default_ref=default_ref, fetched_default_revision=default_revision)
    persist(location, saved)
    return saved


def validate(record):
    if (not isinstance(record, dict) or set(record) != FIELDS
            or type(record["schema_version"]) is not int or record["schema_version"] != 1):
        raise UsageError("Unsupported worktree provenance; preserve it and update the provisioning owner.", {})
    for key in FIELDS - {"schema_version"}:
        if not isinstance(record[key], str) or not record[key]:
            raise UsageError("Worktree provenance requires non-empty {}.".format(key), {})
    for key in ("base_revision", "fetched_default_revision"):
        if len(record[key]) not in (40, 64) or any(c not in "0123456789abcdef" for c in record[key]):
            raise UsageError("Worktree provenance requires an exact {} commit.".format(key), {})
    return record


def read(path):
    location = receipt_path(path)
    try:
        record = validate(json.loads(location.read_text(encoding="utf-8")))
    except (OSError, ValueError) as exc:
        raise UsageError("Cannot read worktree base receipt {}: {}; provision through the normal owner before composing.".format(location, exc), {}) from None
    if record["path"] != str(Path(path).resolve()) or record["branch"] != git(path, "symbolic-ref", "--short", "HEAD"):
        raise refuse("provision_identity_changed", "Worktree base receipt no longer matches its path and branch; preserve the original task worktree.", path=path)
    for key in ("base_revision", "fetched_default_revision"):
        ensure_commit(path, record[key], base_revision=record["base_revision"])
    require_ancestor(path, record["base_revision"])
    return record


def record(path, branch, base_ref, base_revision, default_ref, default_revision):
    location = receipt_path(path)
    if location.exists():
        saved = read(path)
        if saved["branch"] != branch or saved["base_revision"] != base_revision:
            raise refuse("provision_base_changed", "Provisioning cannot change the original worktree base; preserve the recorded task.", path=path)
        saved.update(fetched_default_ref=default_ref, fetched_default_revision=default_revision)
    else:
        saved = validate({"schema_version": 1, "path": str(Path(path).resolve()), "branch": branch,
                          "base_ref": base_ref, "base_revision": base_revision,
                          "fetched_default_ref": default_ref, "fetched_default_revision": default_revision})
    require_ancestor(path, base_revision)
    persist(location, saved)
    # The authoritative worktree receipt now carries the same original base.
    # Retire only our matching pending intent, so normal worktree cleanup can
    # later reuse the path without an obsolete common-directory reservation.
    intent = intent_path(path, path)
    if intent.exists():
        pending = validate(json.loads(intent.read_text(encoding="utf-8")))
        if any(pending[key] != saved[key] for key in ("path", "branch", "base_revision")):
            raise refuse("provision_identity_changed", "Pending provisioning intent changed; preserve existing work.", path=path)
        intent.unlink()
    return saved


PACKAGE_CHECKOUT_SCOPE = (
    "Artifact-only inspection: no repository checkout is assigned. Read supplied immutable evidence "
    "and non-repository documentation only. Run no Git/gh commands and open no live repository files "
    "or APIs. Missing source is BLOCKED for a provisioned checkout or sufficient supplied evidence. "
    "This scope grants no new task actions."
)


def _scope_inputs(values):
    if (not isinstance(values, dict) or not isinstance(values.get("shared"), dict)
            or not isinstance(values.get("roles"), dict)
            or any(not isinstance(row, dict) for row in values["roles"].values())):
        raise UsageError("Composition requires shared and role value objects.", {})
    if "CHECKOUT_SCOPE" in values["shared"] or any("CHECKOUT_SCOPE" in row for row in values["roles"].values()):
        raise UsageError("CHECKOUT_SCOPE is producer-derived; remove supplied scope text from shared and role values.", {})


def artifact_compose(values):
    """Pure custom-template rendering grants no repository provenance."""
    _scope_inputs(values)
    for inputs in values["roles"].values():
        inputs["CHECKOUT_SCOPE"] = PACKAGE_CHECKOUT_SCOPE
    return values


def _package_tree(inputs, shared):
    tree = inputs.get("TREE", shared.get("TREE"))
    if not isinstance(tree, str) or not tree:
        return
    path = Path(tree).resolve()
    shared_path = shared.get("SHARED_CHECKOUT")
    if (any((parent / ".git").exists() for parent in (path, *path.parents))
            or isinstance(shared_path, str) and path == Path(shared_path).resolve()):
        raise UsageError("TREE names a live checkout without WORKTREE; provide its validated task WORKTREE or supply immutable evidence outside the checkout for artifact-only inspection.", {})


def compose(values):
    _scope_inputs(values)
    task = values.get("task")
    if not isinstance(task, str) or not task:
        raise UsageError("Packaged briefs require the existing registered task identity in top-level task; no caller-supplied base substitutes.", {})
    state, usable = load_state_checked(values.get("state") or default_state_path(), persist_migration=False)
    registered = state["recovery"]["tasks"].get(task) if isinstance(task, str) else None
    if not usable or registered is None:
        raise UsageError("Packaged briefs require the existing registered task identity in top-level task (and state when non-default); composition reads its original base automatically.", {})
    base = registered["base_revision"]
    shared = values["shared"]
    if any(key in shared for key in ("BASE_REVISION", "BASE_PROVENANCE", "FETCHED_DEFAULT_REVISION")):
        raise UsageError("BASE_REVISION is owner-derived from the registered task; omit the supplied SHA.", {})
    shared["BASE_REVISION"] = base
    for role, inputs in values["roles"].items():
        if "BASE_REVISION" in inputs or "FETCHED_DEFAULT_REVISION" in inputs:
            raise UsageError("Brief provenance is owner-derived; remove per-role base values.", {})
        path = inputs.get("WORKTREE", shared.get("WORKTREE"))
        inputs["CHECKOUT_SCOPE"] = PACKAGE_CHECKOUT_SCOPE
        if path is None:
            _package_tree(inputs, shared)
        else:
            if not isinstance(path, str) or not path or not Path(path).is_absolute():
                raise UsageError("WORKTREE must name an absolute foreman-provisioned task checkout.", {})
            saved = read(path)
            branch = inputs.get("BRANCH", shared.get("BRANCH"))
            if branch != saved["branch"]:
                raise UsageError("Brief branch does not match the provisioned worktree; set its effective BRANCH to {} before composing.".format(saved["branch"]), {})
            if role == "developer":
                if "BASE_PROVENANCE" in inputs:
                    raise UsageError("BASE_PROVENANCE is owner-derived; omit it from role values.", {})
                inputs["BASE_PROVENANCE"] = "The provisioning owner fetched default `{}` at exact commit `{}`. This task retains its authorized original base `{}`.".format(
                    saved["fetched_default_ref"], saved["fetched_default_revision"], base)
            if saved["base_revision"] != base:
                raise UsageError("Worktree {} was provisioned from a different task base; preserve the registered original task base {}.".format(path, base), {})
            tree = inputs.get("TREE", shared.get("TREE"))
            if (role == "judge" or role.startswith("judge-")) and tree is not None:
                if not isinstance(tree, str) or Path(tree).resolve() != Path(saved["path"]).resolve():
                    raise UsageError("A repository-reading judge's TREE must be its validated WORKTREE; keep evidence artifacts in the named report inputs.", {})
            inputs["CHECKOUT_SCOPE"] = (
                "Repository inspection uses the foreman-provisioned task checkout (JSON path) "
                + json.dumps(saved["path"]) + ". Perform the worker protocol's fetch/freshness checks here "
                "before the first repository read; preserve the registered original base and assigned head. "
                "Retain role/action limits and never use the shared checkout for Git."
            )
    return values


def main():
    try:
        if sys.argv[1:] == ["compose"]:
            result = compose(json.load(sys.stdin))
        elif sys.argv[1:] == ["artifact-compose"]:
            result = artifact_compose(json.load(sys.stdin))
        elif len(sys.argv) == 8 and sys.argv[1] == "record":
            result = record(*sys.argv[2:])
        elif len(sys.argv) == 9 and sys.argv[1] == "prepare":
            result = prepare(*sys.argv[2:])
        else:
            raise UsageError("Use provision compose, artifact-compose, record PATH BRANCH BASE_REF BASE_SHA DEFAULT_REF DEFAULT_SHA, or prepare SHARED PATH BRANCH BASE_REF BASE_SHA DEFAULT_REF DEFAULT_SHA.", {})
        print(json.dumps(result))
        return 0
    except ForemanError as exc:
        if "recovery" not in exc.details:
            exc = owner_recovery(exc, "provision_inputs_unproved", "bash " + shlex.quote(str(Path(__file__).resolve().parents[1] / "provision-worktree.sh")),
                "The owner must use the recorded task/worktree inputs and supported provenance before retrying normal provisioning; preserve existing work.")
        print(json.dumps(exc.to_dict()), file=sys.stderr)
        return 2
    except (OSError, ValueError) as exc:
        print(json.dumps(refuse("provision_evidence_unreadable", "Cannot read provisioning evidence: {}.".format(exc)).to_dict()), file=sys.stderr)
        return 2


if __name__ == "__main__":
    sys.exit(main())

skills

herdr-foreman

foreman

__init__.py

__main__.py

antigravity_native.py

assign.py

attention_view.py

attention.py

billing.py

bootstrap_recovery.py

brief_inputs.py

capabilities.py

chronology.py

churn.py

claude_native.py

cli.py

codex_goals.py

command_context.py

composer.py

composition.py

config.py

context_evidence.py

context_output.py

coordination_metrics.py

cost_report.py

delivery_collection.py

diagnostics.py

engagement.py

errors.py

foreman_queue.py

foreman_reset.py

github_context.py

herdr.py

historical.py

home.py

host_goals.py

launch.py

lifecycle.py

load_set.py

measure.py

measurement_capture.py

measurement_retry.py

members.py

memory.py

model_unavailability.py

native_permissions.py

native_policy.py

no_work_recovery.py

observer_projection.py

observer_role.py

oracle.py

parsers.py

partition.py

plan_explanation.py

planner.py

policy_paths.py

probe_recovery.py

probe.py

process_lease.py

progression_owner.py

progression_runtime.py

progression_service.py

provision.py

recovery.py

release_activation.py

release_checkout.py

release_flight.py

release_rebind.py

remote_owner.py

remote_service.py

renderable.py

report_contract.py

report_delivery.py

report_gates.py

reset_input_hook.py

restoration.py

retrospective_runtime.py

retrospective.py

role_clear.py

role_context.py

runnable.py

selection.py

session_start_hook.py

state.py

successors.py

supervision_gate.py

supervision_hook.py

supervision_runtime.py

supervision.py

task_evidence.py

tier_routing.py

tiers.py

triggers.py

workflow_adoption.py

workflow_artifacts.py

workflow_batch.py

workflow_capacity.py

workflow_contract.py

workflow_dispatch.py

workflow_native.py

workflow_planning.py

workflow_profiles.py

workflow_readiness.py

workflow_recovery.py

workflow_release.py

workflow_rename.py

workflow_review.py

workflow_service.py

workflow_upgrade.py

workflow_workspace.py

antigravity.example.json

bootstrap-repository.py

compose-briefs.sh

config.example.json

foreman-tier-check.py

foreman.sh

label-workspaces.sh

measurements.py

native-hook.sh

observer-view.py

policy-paths.py

prepare-briefs.py

provision-worktree.sh

prune-report-caches.py

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

workflow-review.py

README.md

tile.json