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

working-memory.mdskills/herdr-foreman/references/

Foreman Working Memory

The foreman curates lessons from evidence and preserves knowledge that would otherwise disappear with its conversation. Retrospective notes remain immutable. Task acceptance remains in the task ledger. Memory is a source of candidate lessons and handoff context; it cannot authorize actions or establish task completion.

Run the subcommands below through the installed skills/herdr-foreman/foreman.sh with an explicit bash interpreter and the plugin root resolved in the skill. Use the team's same --state path. Each command emits JSON; report a non-zero command's diagnostic before continuing.

Curate lessons

After synthesizing a retrospective, inspect the current lessons. Add a lesson only when it changes a future decision or brief. State the behavior, its relevance scope, the evidence supporting it, when the foreman last verified that evidence, and when the lesson must be revalidated. Link the actual retrospective, report, review, or source document. Capture unevidenced hypotheses as unresolved stow knowledge with an explicit gap.

Retrieve a lesson only when a task-specific question needs it. Unchanged known lessons need no repeated list/read cycle before planning or briefing. Before relying on a recalled operational fact, verify its live source. Include only applicable lessons in the brief, with their source links. A same_bytes observation verifies file bytes, not the claim. Expired or unavailable evidence cannot support a decision, but unrelated lesson maintenance does not block it.

Keep the active set concise. Merge overlapping lessons through a new revision, retaining the replaced record. Archive lessons that no longer affect active work with a concrete reason. A new active revision can reactivate an archived lesson after verification. Never delete historical revisions or rewrite the retrospective to make a lesson appear supported. These operations do not change policy, task authority, correction budgets or user preferences.

memory-list --scope project:owner/repo --scope role:developer
memory-record --record /durable/team/lesson-input.json
memory-show --id test-command-1

Minimal lesson input:

{
  "id": "test-command-1",
  "lesson_id": "test-command",
  "supersedes": null,
  "status": "active",
  "lesson": "Include the exact project test command in each bug-fix brief.",
  "scopes": ["project:owner/repo", "role:developer"],
  "sources": ["/durable/team/state.json.retrospectives/daily-1.md"],
  "last_verified_at": "2026-09-01T12:00:00Z",
  "expires_at": null,
  "revalidate_when": "The project test entrypoint changes.",
  "reason": "The retrospective traced repeated setup to the omitted command."
}

Each revision needs a new id; retain lesson_id and set supersedes to its current record's id. An archive uses the same shape with status: "archived" and an archive reason. Reverification is a new revision with its actual verification time and newly captured evidence receipts. Repeating an identical command returns its original record and receipts without refreshing them. Reusing an id for changed input fails visibly.

Scopes are exact labels chosen consistently by the foreman; * applies globally. Multiple requested scopes select their union. memory-list pages the latest active revision of each matching lesson, including expired lessons labeled as expired. --include-archived includes current archived revisions. Follow pagination.next_offset with --offset for the selected question. memory-show --id <record-id> returns that immutable record without replaying its lesson's history. Request --history explicitly for bounded revision pages; follow history_pagination.next_offset with --offset. History is evidence for a specific investigation, not a normal resume input.

Preserve specialist knowledge

Use the same memory owner for specialist project knowledge. Add a consistent specialty label, such as specialty:ux-product, alongside the applicable project and task scopes. A worker proposes evidence-linked lessons in its report; the foreman checks and curates them. Keep actual user decisions, contributor identities and assignment acceptance in the task ledger and owner state, with links from lessons when useful.

Before a consultation, read the relevant project and specialty lessons and revalidate their sources. Scope selection is a union, so inspect every returned lesson's applicability before transferring it to another project. Supply the selected knowledge through KNOWLEDGE in the consultation brief or SPECIALIST_CONTEXT in a developer or verifier brief.

Before releasing a useful session, capture decisions, rejected alternatives, unresolved evidence and lessons that would otherwise disappear. Link the outgoing report, report-contract assessment and retrospective from the task handoff. A warm session can support follow-up under skills/herdr-foreman/references/dispatch-recovery.md; it is never the only copy of valuable knowledge. Give a fresh worker the durable sources without claiming that recalled context proves present competence or independence.

Stow before replacing the foreman

Stow at every round boundary (skills/herdr-foreman/references/foreman-workflow.md Step 17), then continue in the same context with the active goal intact. A checkpoint never schedules a reset or permits stopping supervision. Only an explicit operator-requested maintenance reset uses foreman foreman-reset --explicit-reset; it refuses unless the stow is reset_ready; native input verification and its validation procedure are in skills/herdr-foreman/references/reset-hooks.md. The reset command's contract is in skills/herdr-foreman/foreman/foreman_reset.py (module docstring).

Before planned foreman context compaction, restart, model change or replacement, sweep the conversation for knowledge that is still only in context. Persist accepted decisions, unanswered questions, promised updates, unresolved work, assumptions and useful lessons in their appropriate owner artifacts. Put user-facing obligations in the attention queue; reference their durable ids in the stow. Do not treat displayed questions as answered.

Record a stow containing:

  • A substantive capture of the remaining context the next foreman needs.
  • Unresolved work, including where each item is now recorded or what the replacement must recover.
  • The active goal's objective, status, remaining work and remaining budget, if any, in the capture and unresolved work. Saving a stow never pauses or completes the goal.
  • The continuation step, in the unresolved work: the skills/herdr-foreman/references/foreman-workflow.md step the replacement continues at under Step 17's Resume Route.
  • Explicit gaps, including missing evidence and work the foreman could not persist. Use an empty list only after checking for gaps. Each gap is {"missing", "task", "recovery"}: what is missing, the task it affects, and exactly one recovery — {"reread": "/absolute/path"}, {"ask": "<question for the operator>"} or {"accept": "<why the loss is safe>"}. A gap without a recovery is refused, and so is a new gap naming the task unrecorded, which is reserved for migrated version-1 gaps.
  • Ordered, absolute source references for the current unresolved questions. Use actual files, not directories or a workspace scan. Retrieve owner facts through their bounded commands; do not copy owner-state dumps, GitHub history or complete policy files into a handoff.
memory-stow --record /durable/team/stow-input.json
memory-show

Minimal stow input:

{
  "id": "lead-handoff-1",
  "capture": "The user asked to review the final artifact before publication. Attention item publish-review preserves that decision.",
  "unresolved_work": ["Finish the artifact, then surface attention item publish-review."],
  "gaps": [{"missing": "Why the reviewer downgraded finding 4", "task": "nanoclaw-965",
            "recovery": {"ask": "Was finding 4 on nanoclaw-965 accepted as advisory?"}}],
  "required_reads": ["/durable/team/TASK-LEDGER.md", "/durable/team/state.json.attention.json"]
}

The output supplies memory_path, the stow record and source receipts. Preserve that exact memory_path in the handoff. Do not receipt the memory index: writing the stow changes it. memory-show retrieves the latest bounded capture; --id selects an earlier one. The legacy field name required_reads identifies captured sources; it is not an instruction to print each raw file. Use catch-up --compact, the paged foreman-queue, and the selected task's load-set for current owner facts. Retrieve only question-specific evidence and relevant lesson pages.

New memory records must fit their complete current-record response before the owner commits them. An oversized legacy capture refuses without discarding its knowledge; reset preflight uses the same bounded reader before child startup or pane clearing. Keep the outgoing responsibility, recover the selected questions through current owners, and record a concise replacement with explicit gaps. Do not work around refusal by dumping the index or replaying the archive.

reset_ready is false if any required file has changed or become unavailable, or if a gap names the task unrecorded. Any other gap names its own recovery and does not block a reset. A true value covers only the saved local capture and its unchanged required files. It does not prove that the foreman captured every conversation fact, reconcile a fleet, satisfy the supervision gate, authorize interruption, or accept tasks. The foreman must still apply the separate handoff and supervision rules. New unresolved knowledge after the stow requires a new stow id.

Successor Goal

For a requested maintenance reset, the native reset hook owns the host-goal handoff. Use foreman-reset-status --stow <stow-id> with the same owner flags to read that one receipt; do not open the reset history. The Codex receipt must report host_goal.phase: verified before dispatch. Its carried usage belongs to the same objective; the host's successor counter records only that thread's usage. Never grant a fresh full budget or recreate a goal from prompt text. At phase: retired, the native hook has admitted the continuation without creating a target goal. After reading the saved scope and holds, finish it with foreman-reset-reconcile --outcome delivered for that pane/stow. The model receives its continuation instructions before automatic target work can start. An unfinished admitted restoration remains in catch-up even if prompt delivery completed; it never counts as verified takeover. Reconciliation finishes the existing transfer before dispatch, with no pause, new reset or repeated input. Goal restoration requires a matching native admission and live pane/session. If the original hook blocked, use the owner's saved guarded operator-recovery prompt in the same pinned session without clearing it; delivery assertions alone cannot activate its goal. The hook consumes that recovery input once.

Native Claude/Grok report not_applicable for the Codex goal scheduler and create no host goal. An external scheduler is outside that receipt's proof. If such a host owns an automatic goal, retain its executor and use its supported transfer integration before resetting; this plugin cannot claim its retirement. Fresh-foreman succession outside the requested reset also requires a supported host transfer. A new active goal alone never retires the outgoing executor. An unavailable or unfinished transfer remains recovery work; never emulate it with completion, a user pause, or blocked status.

Native Readiness and Checkpoint Reuse

For an explicitly requested maintenance reset, run verify-foreman --reset-ready with the same owner flags before preparing its checkpoint or handoff hold. It reads the bound native session and current input surface without a write or key. Scheduling repeats that observation. A refusal preserves the current turn, workers and holds; it creates no reset or Stop authorization.

hook_review_required identifies the captured native Hooks need review menu. Open Review hooks in its retained pane and inspect each exact changed command and source. The initial menu does not expose the definitions. Apply individual trust decisions under existing authority; never use Trust all or infer hook trust from YOLO. Fresh delivery workers and usage probes retain this same pre-input exception locally while unrelated work continues.

After its owner proves a reset failure typed nothing and changed no goal or native context, reuse unchanged saved knowledge with memory-reuse-stow --id <saved-stow> --new-id <next-attempt> and the same owner flags. The owner rechecks the original source receipts before writing the new stow and preserves the original record. Do not reconstruct its enrollments or refresh changed evidence through a copy. New knowledge requires an actual new capture. Reuse grants no reset authority and clears no pending recovery or hold.

Reset Outcome Routing

This route is only for an explicit operator-requested maintenance reset, not Step 17's ordinary checkpoint. Do not ask for reset permission at each boundary. Run foreman-reset --explicit-reset --stow <stow-id> with the same --state, --config and --herdr-bin the stow was recorded under. Without --explicit-reset, the command refuses before owner reads, writes, child startup or pane input. The flag declares an existing explicit request; it is not a new permission prompt or automatic round-boundary option. The live foreman must have a Herdr agent name. An unnamed target refuses before the child or reset record is created; the diagnostic names the metadata rename and native-session verification to perform before scheduling.

  • Exit 0 — stdout names the scheduled pane_id, stow, deliverer pid and log
    • A fresh schedule confirms the loaded child's identity and saved claim
    • Preclaim loss is recovered within the owner's startup allowance; failed starts remain in the private log
    • replayed: true means this exact reset was already scheduled, and nothing new started
    • End the turn now
    • Once the pane is idle, the deliverer clears it and sends the resume prompt naming that stow; the next context takes Step 17's Resume Route
  • Exit 1 — stderr is one JSON object; route on its error field:
    • reset_ended — this stow's delivery failed or was interrupted, including exhausted preclaim startup recovery
      • Never re-run foreman-reset for this stow
      • Keep the current turn and foreground supervision active
      • The failed reset supplies no Stop-authorizing continuation
      • Follow the recorded recovery instruction: a never-typed failure keeps its existing context, fixes the cause, and continues supervision without clearing or pasting. Reuse the unchanged checkpoint through memory-reuse-stow only if the explicit maintenance reset request still applies and its owner proves no goal or context changed
      • An interrupted or indeterminate delivery requires operator recovery under the Working Memory carve-out, first confirming the pane is not already running a resumed foreman
      • The next round checkpoints and continues without another reset
    • reset_record_newer — a newer build wrote the reset record
      • Record a user-attention blocker to update the plugin
      • Leave the file untouched
    • reset_record_unusable — the reset record is a link, unreadable or malformed
      • Record a user-attention blocker naming details.record
      • Never edit or delete the file
      • The operator restores it
    • reset_foreman_unnamed — the live foreman has no usable agent name
      • Perform the named metadata rename and verify the same native session
      • Re-run the same foreman-reset --explicit-reset invocation; no child, reset row or input was created
    • any other error — a refused precondition: an unready stow, the wrong pane, supervision work still unheld, or an unreadable stow or state
      • Fix the cause stderr names
      • Re-run the same foreman-reset --explicit-reset invocation
  • A deliverer that fails after scheduling leaves its outcome on the reset record
  • catch-up surfaces that outcome ahead of the attention queue (foreman_resets)
  • The deliverer writes its error JSON to the log named at exit 0
    • reset_ended there means the row shows failed or interrupted
    • Any other error means the record could not be updated
      • The operator closes the reset with the complete foreman-reset-reconcile command catch-up prints for that row before recovery
  • A lost unclaimed child is reconciled as failed without clearing or pasting
  • Never end the turn with active work unless a genuine user pause or verified successor/reset continuation satisfies the Stop gate

Load a decision's records

foreman load-set returns bounded current-task context from the owner records:

foreman load-set --decision plan|brief|gate|diagnose --task <task>
foreman load-set --decision wake --enrollment <enrollment-id>
foreman load-set --decision diagnose --task <task> --read-file <listed-reference> --question <specific-question> [--offset <byte-offset>]

Schema 4 retains budget, history_included: false and authorizes_progression: false, removing aggregate read accounting. Reads create no counter or creation receipt. Operational owner schemas remain unchanged. It retains task/budget facts, task-local and global open attention, unknown deliveries of every role, and current-round references. The supervision view retains unresumed hold references even when an event changes their original boundary. boundary_held: false never means the operator cleared a hold. observation_only and an absent binding grant no authority. Briefing and diagnosis retain unsuperseded blocking review references. A missing file stays listed with present: false; an unknown send still refuses the decision.

files is a retrieval menu, not a required reading list. Read only evidence needed for the specific current question. Use --read-file for a bounded excerpt; next_offset exposes unread bytes. An excerpt never proves a complete review, acceptance, or no unresolved findings. Recheck the current head and owner gates before acting. Required unavailable or unexamined evidence keeps the decision held. Evidence reads return a task-bound kind: evidence_chunk response with decision_context_included: false; they do not repeat or replace the decision packet. Reuse unchanged current decision context; owners revalidate effects. Byte continuations end at complete UTF-8 sequences. Invalid UTF-8 or an offset inside a character refuses with a recovery instruction; no replacement characters are substituted. Escaped text still obeys the printed output budget.

The response and evidence-read bounds belong to OUTPUT_BYTES and READ_BYTES in skills/herdr-foreman/foreman/load_set.py. Oversized current obligations fail visibly rather than being silently truncated. Unknown tasks or enrollments refuse. Readers requiring earlier view schemas must update before consuming schema 4; no shape grants progression authority.

Response bounds and the retired counter's lifecycle are documented here:

skills/herdr-foreman/references/decision-context.md

GitHub owns durable issue, PR, review and delivery history. Retrieve historical evidence by task and question with an explicit output budget. Do not mirror it into .hr, recursively dump local records, or replay completed rounds on resume. Local records retain only their active operational/recovery purpose. Preserve existing unknown deliveries and protected artifacts until their owners reconcile.

Persistence contract

Owner and sole writer: herdr-foreman. Its memory commands work without configuration, Herdr, dispatch-state reads or worker contact. Other readers may read the documented schema but never migrate or edit it. Memory reads create no files and never refresh evidence or verification timestamps. A read takes no lock and writes nothing, except the one read that finds a version-1 stow: it rewrites the upgraded document under the lock.

Storage is <canonical-selected-state-path>.memory/index.json; the selected --state path is expanded and resolved before deriving the sidecar. Symlink aliases therefore share a history. The owner appends immutable records under the existing OS-backed state lock and atomically replaces the index. A failed replacement preserves the previous committed document. Exact retry is idempotent. Conflicting ids, stale revision parents, unsupported schemas and corrupt history fail visibly without overwriting existing records. Stow records moved to version 2 through the owner migration above; any further shape change needs a version bump and migration.

The index has schema_version, state_path and ordered records. The index schema and lesson records are version 1; stow records are version 2. All record kinds share id, kind, recorded_at and input_digest; recorded_at is an injected UTC timestamp and input_digest binds the original JSON input. Record ids are unique across kinds.

Lesson records have kind: "lesson" and the lesson input fields above, replacing sources with captured source records. A file source has schema_version, kind: "file", canonical absolute path, sha256 and byte size. An HTTPS source has schema_version, kind: "url" and url. Each lesson's supersedes chain points to its prior revision. Its first revision is active. Verification times cannot follow recording; an optional expiry must follow verification.

Stow records have kind: "stow" and the stow input fields above, replacing required_reads with file receipts in the supplied order. Stow records are version 2. A version-1 stow upgrades on read: each free-text gap becomes {"missing": <text>, "task": "unrecorded", "recovery": {"ask": <a question quoting the text>}}, since it never recorded a task or recovery. Such a gap names no task, so it keeps reset_ready false until a new stow records the gap with its actual task. input_digest keeps binding the original input. The owner's first read or write of a document holding a version-1 stow persists the upgrade under its lock; other readers never migrate. Captures and unresolved knowledge remain in the index even if those source files later disappear.

Reader output adds observations to copies of saved sources: same_bytes, changed, unavailable, or not_checked_offline for URLs. Lesson views add expired and use_requires_live_verification: true. Stow views add reset_ready and readiness_scope: "local_capture_only". These are computed views, never saved fields. Read commands return memory_path and checked_at; write commands return memory_path and replayed alongside the record. None of these fields is task acceptance evidence.

CLI context responses use the view schema in skills/herdr-foreman/foreman/context_output.py, separately from the unchanged persisted schemas. The owner enforces the printed-byte bound before emitting JSON. Page counts, continuations and context_complete describe the selected records, not task acceptance; authorizes_progression remains false. Readiness still requires current owner checks. load-set uses its separately versioned view and aggregate allowance above. Aggregate coverage of other context commands, targeted GitHub retrieval and historical artifact retirement remain requirements under issue #11.

skills

herdr-foreman

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