pact-plugin/skills/pact-handoff-harvest/SKILL.md
HANDOFF discovery, review, save, and cleanup workflow for the PACT secretary. Use when: processing agent HANDOFFs after workflow phases, running session consolidation, or recovering orphaned completed handoffs from prior sessions. Triggers: harvest HANDOFFs, process HANDOFFs, incremental, consolidation, handoff recovery.
npx skillsauth add synaptic-labs-ai/pact-plugin pact-handoff-harvestInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill provides the complete workflow for discovering, reviewing, and saving agent HANDOFFs as institutional knowledge. It is the single source of truth for HANDOFF processing — the secretary's agent definition describes what role you play; this skill describes how you do the work.
Three workflow variants:
Determine which variant to run from the task subject/description: "harvest" or "process HANDOFFs" → Standard Harvest. "incremental" or "remediation" → Incremental Harvest. "consolidation" → Consolidation Harvest.
When reviewing multiple HANDOFFs, read ALL of them before saving any memories. This lets you deduplicate and consolidate across HANDOFFs before committing to pact-memory — producing cleaner entries than saving after each individual HANDOFF.
You have two sources for finding completed agent tasks, in priority order:
~/.claude/pact-sessions/{slug}/{session_id}/session-journal.jsonl — read agent_handoff events via python3 -c "import sys; sys.path.insert(0, '{hooks_dir}'); from shared.session_journal import read_events; import json; [print(json.dumps(e)) for e in read_events('agent_handoff')]". Each event contains {"type": "agent_handoff", "agent": "...", "task_id": "...", "task_subject": "...", "handoff": {...}, "ts": "..."} — full HANDOFF content inline, garbage-collection-proof. Deduplicate: extract unique task_ids only.TaskList (supplementary): Read TaskList for completed tasks owned by agents. Useful as a cross-reference and for catching tasks where the completion hook didn't fire. Note: the platform garbage-collects older task files during long sessions, so TaskList may be incomplete.If none of these sources have completed agent tasks, report "No pending HANDOFFs to review" and complete — this is normal when HANDOFFs were already processed by an earlier trigger (idempotent).
Read your processed task list from your team's section in agent memory (~/.claude/agent-memory/pact-secretary/session_processed_tasks.md). The file is namespaced by team — read only your own ## team={your team_id} section (file-format contract: see Step 8). Skip any task IDs already processed — only review the delta. This enables incremental passes (e.g., after remediation).
For each discovered task, read the HANDOFF using this revision-aware fallback:
metadata (raw JSON; TaskGet is metadata-blind for handoff content). If metadata.revision_number is set and > 1, prefer metadata.handoff over the journal event. The journal agent_handoff event captured the FIRST (rejected) submission only — agent_handoff_emitter.py writes one journal event per task lifetime via an O_EXCL marker. On revision, the team-lead-completion of the revised task does NOT emit a second journal event, so the revised content lives in metadata.handoff only.agent_handoff journal events and revision_number is unset or 1, the journal event's handoff field contains the full HANDOFF content inline — use it directly. This is the most reliable source for first-pass acceptance flows.TaskGet fallback: If both above fail (no journal event AND no metadata.handoff), fall back to TaskGet(taskId).metadata.handoff. May fail for garbage-collected tasks.Pseudocode for the revision-aware branch:
for task_id in unprocessed:
journal_event = next((e for e in journal_events if e.task_id == task_id), None)
task_meta = read_task_metadata(task_id) or {} # raw JSON read; TaskGet is metadata-blind
revision_n = task_meta.get("revision_number", 1)
if revision_n > 1:
# Revised HANDOFF; journal event captured only the first (rejected) submission.
handoff = task_meta.get("handoff")
elif journal_event:
handoff = journal_event.handoff
else:
handoff = task_meta.get("handoff")
# ...process handoff...
Read all HANDOFFs before proceeding to extraction.
Focus on:
Alongside institutional knowledge, snapshot the current workflow state for session recovery. Read TaskList (TaskList is authoritative for current workflow state; session journal is primary for HANDOFF content) and extract:
Save this state snapshot to pact-memory alongside the institutional knowledge entries. This makes you the organizational note-taker — capturing not just what was learned but where the project stands at each phase boundary.
Before every save call, apply this standard operating procedure:
search --query "{topic}" --limit 5update CLI command) rather than creating a new oneupdate merges list fields additively with content-hash dedup, so passing just the new lessons/decisions/entities appends them without clobbering what's already there. Repeated calls are idempotent.update --replace only when a prior conclusion has been superseded and you need to remove the old items from the list. Default update is append-only semantically — it will never delete an existing item.saveThis applies to ALL save operations — HANDOFF review, ad-hoc saves, and consolidation.
Save using the CLI with proper structure:
context: What was being done and whygoal: What was achieveddecisions: Key decisions with rationale and alternatives consideredlessons_learned: Actionable insightsentities: Components, files, services involved (enables graph search)Save the processed task IDs to your team's section in agent memory. Locate (or create) the ## team={your team_id} section in ~/.claude/agent-memory/pact-secretary/session_processed_tasks.md and overwrite that section's task-ID list to set the baseline for subsequent incremental passes. Overwrite only your own team's section — never modify, overwrite, or remove another team's ## team= section. Multiple secretary instances (one per concurrent team) share this single file; each owns exactly its own section.
This file is namespaced by team so that concurrent secretary instances (one per active team, all sharing this single user-scope file) never clobber each other's processed-task baselines. The file-format contract:
File: ~/.claude/agent-memory/pact-secretary/session_processed_tasks.md
---
name: session_processed_tasks
description: Task IDs processed per team for dedup on incremental passes. NAMESPACED by team to avoid cross-secretary collision (single-file user-scope).
type: reference
---
# Per-team processed-tasks log (NAMESPACED — multiple concurrent secretary instances write here)
## team={team_id} ({project}, session {session_id})
{optional one-line session note}
Processed task IDs (this team): {comma-separated IDs}
Last processed (this team): {timestamp}
## team={other_team_id} ({project}, session {session_id})
...
Section semantics:
{team_id} (your spawn pact-XXXXXXXX). The parenthetical ({project}, session {session_id}) is human-readable context.## team={team_id} section. You MUST NOT read, edit, or remove any other team's section.## team={team_id} section does not yet exist, create it (append a new section at the end of the file); never recreate the file from scratch.Report to the team-lead:
SendMessage(to="team-lead",
message="[secretary→team-lead] HANDOFF review complete. Saved N memories from M HANDOFFs.
- {memory summary 1}
- {memory summary 2}
Gaps: {any HANDOFFs that were thin or missing}",
summary="HANDOFF review complete: N memories from M HANDOFFs")
After processing HANDOFFs, gather calibration metrics for the orchestrator's variety scoring feedback loop:
initial_variety_score (stored during variety assessment). If TaskGet fails (garbage-collected), ask the team-lead for the variety score instead.TaskList for blocker count (tasks with "BLOCKER:" in subject). Note: TaskList may be incomplete in long sessions due to garbage collection — report what's available.TaskList for phase rerun count (retry/redo phase tasks)SendMessage(to="team-lead",
message="[secretary→team-lead] Calibration: variety was scored {X}. Blockers: {N}, reruns: {N}. Was actual difficulty higher, lower, or about the same? Any dimensions that surprised you?",
summary="Calibration check: variety {X}")
['orchestration_calibration', '{domain}']Triggered after remediation completes — processes only the delta since the last harvest pass. Fires only when remediation occurred and produced new completed tasks.
## team={your team_id} section of ~/.claude/agent-memory/pact-secretary/session_processed_tasks.md for already-processed task IDsagent_handoff events (primary) and TaskList (supplementary) for completed tasks not in the processed set — these are new completions from remediation.TaskGet## team={your team_id} section (do NOT overwrite — preserves the full session history for your team)update CLI command, not save). Remember: default update is additive merge — pass --replace only when the prior list items need to be discarded, not amended.Triggered during /PACT:wrap-up or /PACT:pause. This is the deep-clean pass — it extends the standard workflow with memory consolidation and pruning.
Check the session journal for agent_handoff events not yet in the processed task set. If unprocessed entries exist, run the Standard Harvest workflow above first (earlier harvest triggers may have been missed). Then continue with consolidation.
Review all memories saved during this session by listing recent pact-memory entries.
## team= sections in ~/.claude/agent-memory/pact-secretary/session_processed_tasks.md: drop any ## team= section older than ~30 days (judge by the section's Last processed timestamp) or whose team is known-complete (the session has wrapped/paused and will not resume). This is safe — the session journal's agent_handoff events are the authoritative dedup source, so a pruned-then-resurrected team re-derives its processed set from its own journal. Prune only stale/complete sections; never touch an active team's section. (Pruning happens only in this deep-clean Consolidation pass — the Standard/Incremental hot paths leave the file untouched apart from your own section.)Sync Working Memory to CLAUDE.md. The auto-sync mechanism handles individual saves, but consolidation may have merged/pruned entries that require a refresh.
Save orchestration retrospective as calibration data (see Standard Harvest Step 10 for CalibrationRecord schema). This captures the session-level view: overall workflow effectiveness, recurring patterns, and calibration for future variety scoring.
Report consolidation results to the team-lead, including:
| Include | Skip | |---------|------| | Architectural decisions with rationale | File locations (agent memory handles this) | | Cross-agent integration points | Framework conventions (agent memory) | | Stakeholder decisions and constraints | Debugging techniques (agent memory) | | Patterns established for this project | Implementation details without broader impact | | Risks, uncertainties, and known issues | Routine changes following existing patterns |
When deciding where knowledge belongs:
Is this knowledge specific to ONE agent's craft/domain?
-> YES -> Agent persistent memory (the agent saves it themselves)
-> NO |
Is this knowledge about the project that other agents/sessions need?
-> YES -> pact-memory (you save via Knowledge Distiller)
-> NO |
Is this a broad session observation or user preference?
-> YES -> Auto-memory (platform handles automatically)
-> NO -> Probably doesn't need saving
HANDOFFs are agent-written summaries — they may omit implicit learnings (failed approaches, nuanced trade-offs). When HANDOFFs are thin, you compensate with investigation.
Direct teammate communication: Message implementing agents directly — not through the team-lead. The team-lead does not need to be in the loop for these exchanges.
SendMessage(to="{agent-name}",
message="[secretary→{agent-name}] Your HANDOFF mentions {decision}. What alternatives did you consider and why were they rejected?",
summary="Elaboration request: {topic}")
File and git analysis: Independently examine source materials:
Lead communication: Only when broader context is needed that neither the HANDOFF nor the implementing agent can provide (e.g., "Why was this feature prioritized?").
For direct save requests from the team-lead outside of workflow HANDOFF review (ad-hoc saves), apply the same institutional knowledge criteria and save-vs-update dedup — save decisions, lessons, and cross-cutting concerns to pact-memory.
This is the Layer 4 fallback for completed handoffs left behind by sessions that ended without wrap-up or where Layer 2 triggers were missed.
session-journal.jsonl in ~/.claude/pact-sessions/*/*/ directories. Exclude the current session's directory (available from the session context file at ~/.claude/pact-sessions/{slug}/{session_id}/pact-session-context.json, or the session dir provided in your dispatch prompt) — that session's data is active, not orphaned.agent_handoff events from the session journal (full HANDOFF inline, read via read_events_from(session_dir, 'agent_handoff')); fall back to TaskGet (may fail for garbage-collected tasks)python3 -c "from pathlib import Path; Path(...).unlink(missing_ok=True)" — not shell rm, to avoid sensitive-file permission prompts)data-ai
Record your teammate identity (name@team) at session start so later hooks can recover your friendly name. Invoke as your first action when your spawn prompt directs it.
testing
Testing strategies, test pyramid guidance, and quality assurance patterns for PACT Test phase. Use when: designing test suites, implementing unit tests, integration tests, E2E tests, performance testing, security testing, or determining test coverage priorities. Triggers on: test design, unit testing, integration testing, E2E testing, test coverage, test pyramid, mocking, fixtures, performance testing, test phase.
data-ai
Command-style teachback protocol for PACT teammates. Invoking this skill directly instructs you to store your teachback in task metadata and idle on awaiting_lead_completion before any implementation work.
development
Clean code principles, error handling patterns, and coding standards for PACT Code phase. Use when: implementing features, refactoring code, reviewing code quality, establishing coding conventions, or handling errors and exceptions. Triggers on: code quality, clean code, refactoring, error handling, logging patterns, naming conventions, code review, code phase.