Claude-Mind: Skill for Claude Code

.claude/skills/agent-completion-report/SKILL.md

agent-completion-report is a skill for Claude Code from zkysar1/Claude-Mind. It costs 112 tokens per session (15,390 once invoked), scanned A, original, MIT.

A report that summarizes what an agent has completed or changed since a chosen status point, including goals, knowledge updates, findings, and resolved hypotheses.

In plain words
What is it for?
Use it when you need a status update, dashboard, recap, or record of completed and in-progress work.
Why use it?
It gives a concise view of progress without requiring someone to inspect every working file or event.

Skill for Claude Code

Written for Claude Code: user-invocable in frontmatter.

This is zkysar1/Claude-Mind's own configuration. It tells Claude Code how to work on Claude-Mind itself, so it is not a mod to install elsewhere. Copy it as a starting point and replace the rules that are about this project. Everything Claude-Mind configures →

Needs its repository: it runs a file that does not travel with it, so clone the repository first. The line is Bash: bash core/scripts/journal-read.sh --recent 10.

Reuse

Borrowing it

Nothing to install: this file belongs to zkysar1/Claude-Mind. Take a copy, put it at the same path in your own repository, and replace the rules that are about this project with yours.

Copy the file
curl -O https://raw.githubusercontent.com/zkysar1/Claude-Mind/main/.claude/skills/agent-completion-report/SKILL.md
Clone the repo
git clone --depth 1 https://github.com/zkysar1/Claude-Mind

Made for: Claude Code.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for agent-completion-report

README.md
[![agentmods](https://agentmods.dev/badge/skills/zkysar1/claude-mind/agent-completion-report/github.svg)](https://agentmods.dev/skills/zkysar1/claude-mind/agent-completion-report)
Your own site
<a href="https://agentmods.dev/skills/zkysar1/claude-mind/agent-completion-report"><img src="https://agentmods.dev/badge/skills/zkysar1/claude-mind/agent-completion-report/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for agent-completion-report

Your own site · 80×15
<a href="https://agentmods.dev/skills/zkysar1/claude-mind/agent-completion-report"><img src="https://agentmods.dev/badge/skills/zkysar1/claude-mind/agent-completion-report.svg" alt="Reviewed on agentmods" width="80" height="20"></a>
Per session 112 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 15,390 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe. Third-party audits
  • NVIDIA SkillSpector pass 7 Sept 2026
How audits are shown
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00112 $0.15390
Opus 5 $0.00056 $0.07695
Sonnet 5 $0.00022 $0.03078
Haiku 4.5 $0.00011 $0.01539

Measured today against content hash 3671bfa31d19, method: parsed. Prices are Anthropic first-party input rates as of 2026-09-08, from the pricing page.

Security

Grade A, and why

agent-completion-report scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured today.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

.claude/skills/agent-completion-report/SKILL.md · 902 lines

How it starts

The opening of the file, as written. The whole thing — 902 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Agent Completion Report

Displays a delta summary of what changed since the last status report.

Valid from ANY state. User-invocable AND agent-callable. Writes the single latest-pointer file agents/<agent>/COMPLETION-REPORT.md (its git history is the permanent archive — there is no timestamped reports/ archive; that directory was abolished by the file-model normalization).

Step 0: Load ConventionsBash: load-conventions.sh with each name from the conventions: front matter. Read only the paths returned (files not yet in context). If output is empty, all conventions already loaded — proceed to next step.

Phase 1: Determine Report Window

1. Determine "since" timestamp (first match wins):
   a. If --since argument provided: use that timestamp
   b. Read agents/<agent>/session/last-report-timestamp → use if present
   c. Read agents/<agent>/session/handoff.yaml → use session_start if present
   d. If none found:
      since = null → show lifetime totals only, skip deltas
      Label report as "Lifetime" instead of delta window

1.5. Positive-state audit (verify-before-assuming.md Positive File-State Claims):
   Any narrative reference in the generated report to a specific framework file
   (`handoff.yaml`, `aspirations.jsonl`, `self.md`, `program.md`, etc.) that
   describes its current state or contents MUST be preceded by an in-turn Read
   of that file. Do not narrate from prior-session memory or from the
   aspirations-compact index — read the actual file before stating what it says.
   Recommended probe at report-generation time, for each referenced file:
   ```bash
   py core/scripts/positive-state-gate.py --claim "<narrative sentence>" --evidence "<concatenated Read outputs from this turn>"

Exit 1 = re-read the file and re-state the claim from fresh evidence.


## Phase 2: Gather Delta Data

All data comes from framework scripts — no direct JSONL reads.

  1. Journal entries since last report Bash: bash core/scripts/journal-read.sh --recent 10 → Filter entries where date >= since date → Extract goals_completed, goals_attempted, key_events

  2. Aspirations completed since last report Bash: bash core/scripts/aspirations-read.sh --archive → Filter where completed_at >= since date → Count and list titles

    ⚠ THIS IS A WINDOW COUNT AND ONLY A WINDOW COUNT. When since is null (the

    "Lifetime" branch at step 0) the filter goes vacuous and this degrades into a

    RECORD ENUMERATION over archive ∪ live — which no longer reaches the lifetime

    population. The 2026-08-14T12:56 metric-neutral eviction moved 5,003 terminal

    goal records out of the live world queue into each aspiration's

    archived_census, and the evictor DELIBERATELY does not re-append them to the

    archive store (its docstring says why), so they survive only in .history blobs.

    Measured cc-08 2026-08-15 (g-001-04): enumeration over archive(370 asps) +

    live(30 world, 1 agent) = 2,679 completed, against 7,084 done of 9,854 from the

    census-folded --summary at step 3 — a 4,405-goal gap, all of it invisible here.

    RULE: take LIFETIME totals from step 3's --summary, which folds the census;

    keep this enumeration for the WINDOW count, where it stays exact. Window safety

    was verified separately: of the 4,972 goals present in the 08-14T12:53 .history

    blob but absent from BOTH live and archive, ZERO have completed_at >=

    2026-08-13T20:25:22. Lifetime figures are NOT comparable across the 2026-08-14

    boundary by either method — say that, rather than reporting a drop.

  3. Active aspirations progress Bash: bash core/scripts/aspirations-read.sh --summary

3b. Goal details for completed goals From the compact aspirations data (step 8) and archive data (step 2), resolve each goal ID from goals_completed into {id, title, aspiration_id, aspiration_title}. Group by aspiration. This provides the detailed goal listing for Phase 3.

3c. Knowledge-debt closures in the report window From the same completed-goal set as 3b, collect goals where closes_knowledge_debt is a non-empty list. For each, record {goal_id, title, closes_knowledge_debt}. Aggregate:

  • debt_closure_events = count of such goals
  • debt_closure_node_keys = unique union of node_keys closed
  • debt_closure_sample = up to 3 {goal_id, title, node_keys} entries This surfaces the semantic override firings from aspirations-execute Phase 4-post ("DEBT-CLOSURE OVERRIDE") without requiring log scanning.
  1. Hypotheses resolved since last report

    BOTH stages are REQUIRED — a record can be archived within the report

    window, so a resolved-only fetch UNDERCOUNTS any multi-day report while

    staying exact for a same-session one. That split is why this site is the

    least visible of the four and survived longest. Measured 2026-08-04T03:33

    (bravo, hostname cc-05, uname -r 6.8.0-136-generic): of the scoreable

    records in each trailing window, --stage resolved alone sees 100% at 2d

    but only 75.9% at 7d and 29.8% at 30d — i.e. a week-long report silently

    drops a quarter of its own subject matter. (g-115-4866.)

    ⚠ THOSE PERCENTAGES HAVE DECAYED — RE-MEASURE, DO NOT QUOTE THEM. Two

    independent measurements on 2026-08-15, hours apart on different boxes,

    each carrying its denominator (guard-3542 — a coverage rate over a moving n

    is meaningless without it):

    bravo, cc-05, 6.8.0-137-generic, 216.1h window: 47 of 199 = 23.6% at 9d.

    Store split at that instant: 50 resolved vs 1,127 archived.

    alpha, cc-08, 6.8.0-137-generic, 48.5h window: 22 of 35 = 62.9% at 2d.

    Store split at that instant: 34 resolved vs 1,148 archived.

    THE SECOND ONE IS THE LOAD-BEARING DATAPOINT, and it breaks the model the

    rest of this comment implies. The 2026-08-04 row reads coverage as a

    function of WINDOW WIDTH (100% at 2d, degrading to 29.8% at 30d), which

    invites the reading that a short report is safe. It is not: the 2-DAY

    figure itself fell 100% -> 62.9% in eleven days. A same-session report is

    the ONLY case still near-exact, and even that is not guaranteed to hold.

    So the resolved stage is not a time window with a fixed width; its

    effective lookback is set by ARCHIVAL CADENCE, and that cadence keeps

    tightening (2026-08-04: 86 resolved over ~4.5d; 2026-08-15: 50 then 34,

    both over ~2.3d or less, at a HIGHER resolution rate).

    RE-MEASURED 2026-08-18 (echo, cc-03, 6.8.0-137-generic, 15.35h report

    window). Store split at that instant: 49 resolved vs 1,204 archived.

    same-day (2026-08-18): 6 of 6 = 100%

    spanning 08-17 (~39h): 27 of 38 = 71.1%

    lifetime: 47 of 811 = 5.8%

    THE 2-DAY FIGURE WENT BACK UP — 62.9% (08-15) -> ~71% (08-18). So the

    decay narrated above is NOT monotonic, and reading it as a trend line is

    the wrong model: it oscillates with archival cadence. Do not "correct" the

    08-15 row toward this one; both are true readings of a quantity that moves

    in both directions, which is exactly why the instruction is to re-measure

    rather than to quote.

    AND DISCOUNT THE 100% (guard-2303 — check the instrument's resolution

    before reporting a change-detection result): outcome_date is DATE-ONLY,

    so a same-DAY window and the field's granularity are the same size. A

    same-day 100% is partly the instrument saying "I cannot resolve inside

    this window", not purely the store being complete. The 71.1% row spans two

    calendar days and is the more informative one.

    SERIES — each entry (date, window, resolved-stage coverage, denominator).

    APPEND YOUR READING HERE; do not add another dated paragraph. Five had

    accumulated by 2026-08-21 and the sixth would have cost more to read than

    the number is worth (learning-philosophy.md rule 5):

    08-04 2d 100% (n≈?) · 08-15 2d 62.9% (n=35) · 08-18 39h 71.1% (n=38)

    08-19 79.6h 73.5% (n=68) · 08-21 20.2h 81.1% (n=37, split 44/1261)

    08-21 9.7h 65.0% (n=20, split 48/1262) <- SECOND 08-21 reading, ~8h later

    08-21 9.5h 75.0% (n=28, split 56/1262) <- THIRD 08-21 reading, ~2h later

    08-22 25h(date-floored) 100% (n=22, split 60/1262)

    08-22 15.2h(date-floored 16.2h) 100% (n=14, split 62/1278)

    08-24 32.5h(date-floored 48.8h) 86.2% (n=29, split 73/1279) <- 3 CALENDAR DAYS

    08-24 34.8h(date-floored 48.8h) 87.5% (n=32, split 76/1279) <- SAME DAY, ~13min later, DIFFERENT BOX

    08-24 63.3h(date-floored 83.9h) 83.3% (n=66, split 78/1279)

    08-25 13.3h(date-floored 25.3h) 63.0% (n=27, split 40/1335) <- BACKLOG DRAINED 78->40, COVERAGE FELL WITH IT

    08-29 49.4h(date-floored 3 calendar days) 90.3% (n=31, split 50/1397)

    08-30 99.94h(date-floored 5 calendar days) 93.3% (n=60, split 58/1397) <- WIDEST WINDOW AND HIGHEST NON-100%, TOGETHER

    08-31 102.5h 48.7% (n=39, split 22/1554) <- WIDER THAN 08-30 AND HALF ITS COVERAGE, ONE DAY LATER

    08-31 29.9h(date-floored 46.8h) 100% (n=14, split 22/1554) <- SAME BOX-DAY, IDENTICAL STORE SPLIT, NARROWER WINDOW

    09-02 27.85h(date-floored 2 calendar days) 100% (n=16, split 24/1577) <- NEAR-EXACT REPLICATION OF THE ROW ABOVE, 2 DAYS LATER

    09-02 21.2h(date-floored 37.2h) 100% (n=16, split 24/1577) <- SMALLEST BACKLOG SINCE 08-31 (24), STILL 100% ON A ~1-DAY WINDOW; consistent with the 08-31 narrow row, not with the wide one

    09-02 9.76h(date-floored 1 calendar day) 100% (n=20, split 31/1577) <- THIRD 09-02 READING. Backlog GREW 24->31 and coverage HELD at 100%; the within-window backlog model predicts UP and 100% is the ceiling, so this row is SATURATED and tests nothing. Same-day window, so guard-2303 discounts it too. Recorded for the denominator, not as evidence.

    09-05 28.06h(date-floored 2 calendar days) 100% (n=21, split 57/1588) <- FOURTH consecutive 100%. Backlog GREW 31->57 (largest since 08-24's 78) and coverage HELD at the ceiling, which the within-window backlog model already predicts -- so this row is SATURATED and tests nothing, exactly like the 09-02 row above. Window spans 2 calendar days, so guard-2303's date-floor discount does NOT excuse it. Recorded for the denominator.

    09-07 21.5h(date-floored 2 calendar days) 100% (n=7, split 35/1619) <- FIFTH consecutive 100%, and the FIRST row where the backlog DRAINED (57->35) without coverage falling with it. Both prior drains fell (08-25 78->40 -> 63.0%; 08-31 58->22 -> 48.7%), so this is counter-evidence to the within-window backlog model -- but n=7 is the SMALLEST denominator in the series and one archival sweep moves it tens of points. Recorded for the denominator, NOT as a refutation.

    THE 08-30/08-31 PAIR IS THE CLEANEST WIDTH-CONTROLLED TEST IN THIS SERIES AND IT

    SETTLES THE ARGUMENT: 99.94h -> 93.3%, then 102.5h -> 48.7% ONE DAY LATER. The

    window got WIDER and coverage HALVED, so width cannot be the driver in either

    direction (08-30 already falsified 'wider drives coverage down'; this falsifies

    the converse too). The resolved backlog drained 58 -> 22 across that same day and

    coverage tracked it down -- the identical signature as the 08-25 row. Backlog is

    the driver; width is noise. Note also this window's outcome mix, which no prior

    row records: 159 in-window records but only 39 SCOREABLE (26 CONFIRMED, 13

    CORRECTED) against 113 EXPIRED + 7 UNRESOLVABLE. Compute coverage over SCOREABLE

    only or the row is not comparable to any other -- an all-records count here would

    have reported 12.6% and silently entered a different quantity into the series.

    THE 08-30 ROW FALSIFIES THE WIDTH HALF OF THAT MODEL. It is the WIDEST window

    in the series (99.94h, 1.6x the prior widest) and scored the HIGHEST non-100%

    (93.3%) -- so "a window wide enough to cross the horizon pulls in archived rows

    and drives coverage DOWN" is not a law. Only 4 of its 60 in-window records had

    reached the archived stage at all, against a 58-deep resolved backlog. Backlog,

    not width, is what the series keeps measuring.

    THE THIRD 08-24 ROW REFINES THE BACKLOG MODEL THE OTHER TWO PROPOSED, and it is the

    only row that can: it carries the HIGHEST backlog yet recorded (78 resolved) and still

    scored the LOWEST of the three, because its window is ~1.7x wider and reaches back past

    the archival horizon into days already swept. So backlog is not the sole driver either.

    Reconcile them this way: WITHIN a fixed window, coverage tracks the backlog (the 13-min

    pair proves that); ACROSS window widths, a window wide enough to cross the horizon pulls

    in archived rows and drives coverage DOWN regardless of backlog. Both effects are real at

    different scales, and neither licenses quoting a row — which is what the series already says.

    THE TWO 08-24 ROWS CONFIRM THE DRIVER DIRECTLY, and they are the cleanest pair in

    the series for it: 13 minutes apart, DIFFERENT BOXES (cc-0x, then foxtrot on

    LAPTOP-3IOFCNEO / WSL2 6.18.33.2), near-identical window width, and coverage ROSE

    86.2% -> 87.5% while the resolved stage grew 73 -> 76 against an unchanged 1279

    archived. Coverage tracked the BACKLOG, not the window and not the box. If window

    width or box identity set coverage, these two would not move together like that.

    THE FIRST 08-24 ROW IS THE HIGHEST NON-100% READING BEFORE IT AND IT IS NOT A

    DATE-FLOOR ARTIFACT: it spans three calendar days, so guard-2303 does not

    explain it. It is high because the RESOLVED STAGE WAS BACKED UP -- 73 resolved

    against 44-62 in every prior row -- i.e. coverage rose because ARCHIVAL fell

    behind, not because the instrument improved. Same driver, opposite direction

    from the 08-15 low. Nothing here predicts your run; measure your own.

    THE TWO 08-22 ROWS ARE BOTH 100% AND NEITHER MEANS THE INSTRUMENT IMPROVED: both

    windows are SAME-DAY, and outcome_date is date-only, so the floor swallows the

    whole window and the field cannot resolve inside it (guard-2303). The second row

    scored 100% on a window 10h NARROWER than the first — read together with the

    08-21 trio, that is a fourth demonstration that width is not the driver.

    THE THREE 08-21 ROWS ARE THE CHEAPEST PROOF OF THE INSTRUCTION BELOW: same day,

    same box. 81.1% (20.2h) -> 65.0% (9.7h) -> 75.0% (9.5h). If window width set

    coverage, the two NARROW rows would agree — they are 0.2h apart and they differ

    by TEN POINTS, while the WIDEST row scored highest of all three. The store

    barely moved across the whole day (44/1261 -> 48/1262 -> 56/1262). Archival

    cadence is the only driver, so no row predicts any other.

    READ THE SERIES, NEVER A ROW. It is not monotonic and not a function of

    window width — a 3.3-DAY window (73.5%) beat a 2-DAY one (62.9%), and a

    20.2h window beat both. Only archival cadence sets it, so a NARROW window

    buys you nothing and no row here predicts your run.

    The instruction is unchanged and is now stronger: read BOTH stages. What

    changes is that no fixed percentage here can be trusted as guidance — the

    number is a snapshot of a moving quantity (guard-390: an artifact

    describing external state must cite what keeps it current; nothing does

    here). COMPUTE the coverage in your own run — you already hold both

    populations — and correct this comment in passing when it has moved again.

    Bash: bash core/scripts/pipeline-read.sh --stage resolved Bash: bash core/scripts/pipeline-read.sh --stage archived → Filter the UNION where outcome_date >= since date → Count confirmed vs corrected

  2. Overall pipeline accuracy Bash: bash core/scripts/pipeline-read.sh --accuracy

  3. Knowledge tree stats Bash: bash core/scripts/tree-read.sh --stats

  4. Guardrails / reasoning bank / pattern signatures counts Bash: bash core/scripts/guardrails-read.sh --count Bash: bash core/scripts/reasoning-bank-read.sh --count Bash: bash core/scripts/pattern-signatures-read.sh --count → Each returns {"count": N} — a RECORD count. 56 bytes for all three. They feed exactly one line of the report (## Knowledge); the CONTENT of these stores is never used here.

    WAS --summary + "Count lines from each" until 2026-08-29 (g-115-6742):

    2,106,400 bytes loaded at EVERY /stop to produce three integers, two of

    them WRONG. Counting summary LINES is not a record count, and it errs in

    BOTH directions at once — which is why it read as a small single-store

    defect for ten days instead of a defect in all three:

    +N a field carrying an embedded newline emits a continuation line

    (3 guardrails today; rule[:80] in reasoning_bank.py truncates

    but does not strip \n — corroborated by guardrail-manifest.sh

    --stats, which independently reports "3 wrapped-text ... folded")

    -1 NONE of the three outputs ends with a trailing newline, and

    wc -l counts NEWLINES — so every store undercounts by 1

    Measured 2026-08-29 (alpha, cc-07): guardrails 5194 real lines / 5191

    records, where wc -l said 5193 because the two errors partially

    cancelled; reasoning-bank and pattern-signatures were BOTH off by -1,

    though the goal that filed this had recorded them as delta 0.

    Do NOT reintroduce a line count. --summary still exists if the CONTENT

    is ever genuinely needed; this section has never needed it.

  5. Pending questions + user goals Bash: bash core/scripts/pending-questions-read.sh --status pending → JSON array of pending entries. This reader is shape-tolerant (flattens the dict-wrapper / list-with-wrapper / bare / mixed on-disk shapes via the same _load_questions logic the sweep sibling uses, rb-1786). Do NOT hand-roll a naive top-level status == "pending" scan of the raw YAML — it silently SKIPS entries nested inside a {questions: [...]} wrapper (g-115-3039). Bash: bash core/scripts/load-aspirations-compact.sh → IF path returned: Read it (compact data has IDs, titles, statuses, participants — no descriptions/verification) Filter goals with participants containing "user"

    ⚠ AND NO completed_date — ON ANY RECORD, INCLUDING THE COMPLETED ONES. So a

    window-scoped completion count computed from this index returns 0 regardless of

    actual activity, and the 0 reads as a quiet fleet rather than as a missing field

    (rb-245 class). Measured cc-08 2026-08-17: 2,685 goals / 23 aspirations, 694 at

    status=completed, and a one-record schema probe of a completed goal shows only

    title/status/priority/category/participants/skill/discovered_by/filed_by_agent/

    work_class/id/started — no completion timestamp of any kind, while

    aspirations-read.sh --summary reported asp-115 alone at 4,422 done. Use this

    index for IDENTITY and STATUS only; take every dated or counted figure from the

    full store.

  6. Blocked goals analysis Bash: bash core/scripts/goal-selector.sh blocked → Parse JSON → store as blocked_data → blocked_data.bottlenecks = root bottlenecks with downstream counts → blocked_data.summary.total_blocked, blocked_data.summary.bottleneck_count

  7. Message board activity since last report For each channel in [general, findings, coordination, decisions]: IF since is not null: Calculate hours = ceil((now_epoch - since_epoch) / 3600) Bash: bash core/scripts/board-read.sh --channel --since {hours}h --json ELSE (lifetime): Bash: bash core/scripts/board-read.sh --channel --json → The output is JSONL — one object per LINE, NOT a JSON array. A whole-stream json.load raises JSONDecodeError("Extra data: line 2 column 1"). Parse line-by-line: [json.loads(l) for l in out.splitlines() if l.strip().startswith("{")] → A bare except around that parse is FORBIDDEN. It launders the raise into 0, and the report then states the board was silent — a claim about fleet coordination health. Measured 2026-08-03 (foxtrot): general 23 / findings 248 / coordination 436 / decisions 13 = 720 messages reported as 0. The 2026-08-02 report hit the identical zero and correctly diagnosed it in its NARRATIVE, and the next run reproduced it unchanged — because the narrative is not what the next agent executes; this file is. That is why the fix belongs here and not in another report. → POSITIVE-CONTROL a zero before believing it (guard-2421). This defect is self-concealing: an empty board is a plausible reading, so nothing prompts a second look. If a channel returns 0, re-read it at a wide window (--since 720h) or check for a known post-id. Cheapest check first: if you already hold a prior measurement that contradicts the empty, believe the prior one and re-read. → store messages per channel → Skip channels that output "is empty or does not exist" Cap: max 10 most recent messages per channel. If more exist, note: "... and {N} earlier messages" Store as board_messages = {channel: [messages], ...} (Any channel with zero messages is omitted from output)

  8. System Health Metrics

    Structural health indicators surfaced for meta-awareness

    11a. Decompose candidates (tree nodes exceeding growth threshold)

    Bash: bash core/scripts/tree-read.sh --decompose-candidates → Parse output as JSON → decompose_candidate_count = len(result)

    11b. Encoding drift (from session signals if available)

    Bash: bash core/scripts/wm-read.sh loop_state --json → Extract goals_since_last_tree_update from loop_state.signals (if exists) → If WM has no loop_state (between sessions): encoding_drift = "N/A (between sessions)"

    11c. Reflection ROI (from meta/reflection-strategy.yaml)

    Bash: meta-read.sh reflection-strategy.yaml → If file exists: extract roi_history (last 5 entries) → If file missing: reflection_roi = "not initialized"

    11d. Routine-to-productive ratio (from loop_state if available)

    → If loop_state exists: routine_ratio = loop_state.signals.routine_count_total / loop_state.goals_completed → Else: routine_ratio = "N/A"

    11e. Knowledge debt items (aggregate + per-entry detail)

    Bash: bash core/scripts/wm-read.sh knowledge_debt --json → knowledge_debt_count = count of items (0 if empty/null) → knowledge_debt_high = count where priority == "HIGH" → knowledge_debt_oldest_age_days = max(now - item.created) across items, or 0 if empty → knowledge_debt_entries = up to 5 items sorted by sessions_deferred DESC then age DESC, each as {node_key, priority, source_goal, age_days, sessions_deferred}

    11f. Hypothesis pipeline flow

    Uses pipeline counts already gathered in step 4/5

    Bash: bash core/scripts/pipeline-read.sh --stage active → time_gated = count hypotheses where formed_date + horizon window > now → flowing = total active - time_gated

  9. Outcome Delta (Tranche C — rb-390)

    Reads the outcome-metrics snapshot populated by the outcome-observation

    hook in aspirations-state-update Step 8.12 (Pattern B hook slot — see

    core/config/conventions/domain-hooks.md). Fail-open: missing snapshot

    means outcome_delta_available = false and the section shows

    "no outcome signal configured" — never an error.

    goals_completed_count = len(goals_completed) # from step 1 (list of ids) Bash: source core/scripts/_paths.sh && test -f "$WORLD_DIR/outcome-metrics.yaml" && echo "exists" IF exists: Read "$WORLD_DIR/outcome-metrics.yaml" → outcome_now = parsed YAML outcome_delta_available = true # Prior snapshot: saved alongside the report-timestamp marker so the # delta is computed against the last completion report, not the live # file (which the outcome-observation hook mutates every goal). IF agents//session/last-outcome-snapshot.yaml exists: Read it → outcome_prior = parsed YAML # BASELINE-CORRESPONDENCE ASSERTION (g-001-04, 2026-08-24). The delta # window is defined by last-report-timestamp; the baseline it diffs # against is this file. NOTHING guarantees they correspond, and when # they do not the report states a delta over the WRONG interval while # looking completely normal. Two independent ways they decorrelate: # (1) a prior run wrote the timestamp and skipped this snapshot — # Phase 4 step 3's || true makes a skip, a failed cp and a # success byte-identical after the fact; # (2) sync-tier split: last-report-timestamp is sync_tier # continuity (crosses machines) while this file is # machine_local (does not) — session-manifest.yaml:397/896. # A multi-box agent reporting from box B diffs against box B's # last LOCAL snapshot, not against its own last report. # MEASURED 2026-08-24 (foxtrot, LAPTOP-3IOFCNEO): baseline # updated_at 2026-08-21T03:16:14 / mtime Aug 21 03:53 against a # last-report-timestamp of 2026-08-22T16:53:06 — a 3-DAY baseline # presented as a 35-hour delta. Cause was (1), proven by three # same-directory Phase-5/5.5 siblings (fleet-digest.md/.html, # digest-notes.md) all written 2026-08-22 16:55:08-09 on this box # while this file was not touched. baseline_age_note = None # GATE ON THE SNAPSHOT'S MTIME, NOT ITS updated_at — corrected # 2026-08-24 (echo, cc-03) on this assertion's FIRST live run, which # is what exposed it. updated_at records when the COLLECTOR last # wrote world/outcome-metrics.yaml; the snapshot is COPIED from that # file at report time, so updated_at is necessarily EARLIER than the # report timestamp on every healthy run and updated_at < since # fires ALWAYS. Measured here: updated_at 2026-08-21T20:00:07 against # since 2026-08-21T20:23:35 — a 23m28s collector interval rendered as # a window violation worth 0.6% of a 63.3h window. An assertion that # fires on every healthy run trains its reader to skip it, which is # precisely how the real 3-day case below would get missed. # MTIME is the right signal because it records when the snapshot was # TAKEN. It matched since to the second here (20:23:35.714 vs # 20:23:35), and it still catches the foxtrot failure case # decisively (mtime Aug 21 03:53 vs since 2026-08-22T16:53 = 37h). # Writers enumerated before trusting an mtime (guard-1504, rb-190): # session-manifest.yaml:898 names exactly ONE writer # (agent-completion-report Phase 4) at sync_tier machine_local, so no # sync layer and no background writer can move it. If that ever gains # a second writer, this gate is void — re-enumerate before trusting it. snapshot_mtime = mtime of agents//session/last-outcome-snapshot.yaml IF since is not null AND snapshot_mtime is more than 60s BEFORE since: # The snapshot was not taken at the last report: a prior run wrote # the timestamp and skipped the copy. The delta spans MORE than the # report window, so every "moved" is over-stated. baseline_age_note = ("baseline snapshot was TAKEN {t} but the report " "window starts {s} — a prior run wrote the timestamp and skipped " "the snapshot, so this delta spans {d} extra hours and " "OVER-STATES movement").format(...) # updated_at remains useful as SECONDARY colour (how stale the metrics # themselves were at snapshot time). Report it; never gate on it. # Do NOT suppress the section and do NOT silently widen the window: # print baseline_age_note verbatim in the Outcome Delta section # (guard-2841 — a silently-dropped row is indistinguishable from a # source that was never read). ELSE: outcome_prior = {} # first report — deltas appear as "initial" baseline_age_note = None # Compute per-source deltas. Each source contributes exactly these # four keys (consumer contract — do not omit any): # available: bool — was the source present in outcome_now? # moved: bool — did any observable field change value vs prior? # substantive: bool — is that move a real event rather than a # COLLECTION ARTIFACT? (guard-2306) # delta_summary: str — one-line human description for the report # substantive exists because "it moved" has two indistinguishable # causes: something genuinely happened, or the measured population # EMPTIED / REFILLED / the collector changed shape — which alters every # field at once. Set substantive = false when the move is an artifact of # collection rather than of the product. The discriminator is the # DENOMINATOR (same one guard-2049 uses for the mirror case): # - the source's own denominator (runs_total, row count, sample size) # crossed zero in EITHER direction — 2->0 or 0->6 alike; a window # that empties and a window that refills are both the collector # talking, not the product; # - every observed field changed at once and at least one landed on # zero / null / empty; # - the source's shape changed (fields appeared or disappeared). # BOTH DIRECTIONS ARE MEASURED, do not treat this as the empty case # only: ci 2->0 suppressed the warning on 2026-08-01 (g-001-04 run 74, # 23 goals) and ci 0->6 suppressed it again on 2026-08-06 (alpha, cc-04, # 55.8h window). # KEEP delta_summary HONEST EITHER WAY: still say the field changed, and # say why it does not count — a suppressed number that is never printed # is how this defect stayed invisible for three reproductions. # Never error if a key is missing from outcome_prior or outcome_now — # the source shape is domain-specific and may change. # Sources nest under the top-level sources: key in outcome-metrics.yaml # (header written by outcome-metrics-collect.sh). A top-level .get("git") # returns {} for BOTH sides, every source reads moved=false, and the # divergence warning fires FALSELY on any >=5-goal window (observed # 2026-07-16 g-001-04 run — caught by reading the raw file before trusting # the empty delta). prior_src = outcome_prior.get("sources", {}) or {} now_src = outcome_now.get("sources", {}) or {} git_delta = compute_source_delta(prior_src.get("git", {}), now_src.get("git", {})) ci_delta = compute_source_delta(prior_src.get("ci", {}), now_src.get("ci", {})) operator_delta = compute_source_delta(prior_src.get("operator", {}), now_src.get("operator", {})) # Process-vs-outcome divergence flag: # IF goals_completed_count >= 5 AND no source moved → divergence. # This is the exact signal that caught "77 goals done and nothing # material moved." Magic number 5 is the minimum window under which # divergence is noise not signal. any_outcome_moved = any( d.get("moved") for d in [git_delta, ci_delta, operator_delta] ) # Gate on SUBSTANTIVE movement, never on bare moved — a collection # artifact reads moved=true and satisfies-away the very warning that # exists to catch "lots of work, nothing happened" (guard-2306). any_substantive_move = any( d.get("substantive") for d in [git_delta, ci_delta, operator_delta] ) # AND require at least one source to have been READ. This is the OTHER # direction, and it must be checked in the same edit or the fix simply # swings the bug back: g-115-2394 fixed a variant where every source # read {} on both sides, so nothing could ever move and divergence fired # FALSELY on every >=5-goal window. "Could not measure" is not the same # claim as "nothing happened", and only available separates them. any_source_available = any( d.get("available") for d in [git_delta, ci_delta, operator_delta] ) divergence = ( goals_completed_count >= 5 and any_source_available and not any_substantive_move ) ELSE: outcome_delta_available = false divergence = false

  10. Recurring-goal lifetime substantive-hit data (FW-5/R1 -- g-317-16)

    Feeds the "Contribution" recognition section (Phase 3), which frames

    recurring/sweep goals that returned routine THIS window. g-317-02 shipped a

    lifetime substantive-hit tally WRITTEN by recurring-close.sh onto each

    recurring goal record:

    substantive_runs = denominator, advances on EVERY close

    substantive_hits = numerator, GENUINE-deep closes only (a forced

    anti-drift flip is NOT a real catch, so it is excluded)

    last_substantive_at = date of the most recent genuine catch

    The slim aspirations-compact index (step 8) does NOT carry these fields, so

    gather them from the goal records for the recurring goals completed this

    window (the set the report already lists).

    substantive_data = {} # goal_id -> {hits, runs, last, rate} FOR EACH goal_id in goals_completed (from step 1) that is recurring: # Resolve aspiration_id via step 3b's goal_id -> aspiration mapping. Bash: bash core/scripts/aspirations-read.sh --source {source} --id {aspiration_id} → find the goal by goal_id; read substantive_hits / substantive_runs / last_substantive_at. Default 0 / 0 / null when the fields are ABSENT (legacy goals, or goals never closed via recurring-close.sh since the g-317-02 writer shipped -- the expected early-data case). runs = int(substantive_runs or 0); hits = int(substantive_hits or 0) rate = round(hits / runs, 3) if runs > 0 else None substantive_data[goal_id] = {"hits": hits, "runs": runs, "last": last_substantive_at, "rate": rate}

    ALTERNATIVE aggregate/chronic view (ALL recurring goals, not just this

    window): bash core/scripts/cargo-cult-detector.py --audit-all --dry-run

    computes the same per-goal lifetime_hit_rate across world+agent queues and

    flags chronic-low-rate rows. Use it when the report wants the full upkeep

    track record rather than only this-window goals; parse its markdown table

    (--dry-run suppresses the Idea-goal filing side effect).

    Fail-open: a read error for any goal defaults that goal to runs=0 (graceful

    omit in Phase 3) -- never error the report on missing substantive data.

Read the full file on GitHub · 902 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. today Changed · +45 lines 3671bfa31d19
  2. 5d ago Changed · +76 lines c41be8ad1df1
  3. 9d ago First seen · 781 lines · 112 tokens per session scan A 8dc011e67035

Subscribe to this mod's changes

agent-completion-report is a skill published in the GitHub repository zkysar1/Claude-Mind (5 stars, last pushed yesterday), licensed MIT. It adds 112 tokens to every session and 15,390 once invoked, about $0.0006 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.

Related

Other skills, from other repositories

hive.browser-automation

Required before any hive-browser CLI command. The browser is driven from the terminal by running hive-browser ... --json via terminalexec — not via MCP tools. Teaches the browser lifecycle rules (the bridge attaches to the USER'S running Chrome — never kill or launch browser processes; timeouts are transport issues…

aden-hive/hive · 142 tokens

hive.linkedin-automation

Read before automating LinkedIn with browser tools. LinkedIn combines shadow DOM (#interop-outlet), strict Trusted Types CSP that silently drops innerHTML, Lexical composer, native beforeunload dialogs that hang the bridge, and aggressive spam filters — each has bitten us at least once. Verified flows for profile…

aden-hive/hive · 99 tokens

hive.worker-delegation

Concrete patterns for breaking colony work into parallel worker jobs via runplaybook — when fan-out helps, how to model the goal as a tracker table, write the worker skill, author the playbook, pilot, and let convergence retry/resume the gap.

aden-hive/hive · 58 tokens

hive.x-automation

Read before automating X / Twitter with browser tools. Verified flows for post, reply, delete, search-and-engage, plus the Draft.js compose quirks that silently disable the send button. Includes the daily-reply and job-market-reply playbooks. Requires hive.browser-automation for the underlying screenshot + coordinate…

aden-hive/hive · 81 tokens

hive.slack-notifications-setup

Set up a Slack notification channel (Sentinel) for a colony by driving the browser — reuse or create the "Hive Sentinel" Slack app from a JSON manifest, install it, capture the bot + app tokens, create/select the channel via the Slack API, and turn Sentinel on so the colony can ping the user on Slack and accept…

aden-hive/hive · 136 tokens

hive.writing-hive-skills

Author a new Agent Skill for a Hive agent that conforms to the Agent Skills specification (SKILL.md with YAML frontmatter, optional scripts/references/assets directories). Use when the user asks to create, scaffold, add, or package a new skill for a Hive agent.

aden-hive/hive · 63 tokens