parsoFish

reflector

Run a deep structured retrospective at the end of a merged initiative — repeated actions, roadblocks hit, and operator notes (agentic self-reflection + agent-prompted user questions + pure user feedback) — and write the findings into the central forge-owned brain.

parsoFish 5 Actualitzat fa 4 setm.
GitHub

Instal·la

npx skillscat add parsofish/forge-studio/reflector

Instal·la des del registre de SkillsCat.

SKILL.md

Reflector

Single responsibility

Close the learning loop. After an initiative is merged, run the four-stage retro (per the Reflect section of the example-factory explanation) and write findings into the brain by direct file writes — theme markdown files under brain/projects/<project>/themes/ plus a cycle archive under brain/cycles/_raw/<cycle-id>.md.

Operator handoff (the reflection human moment)

The in-UI /reflect screen is the operator surface (ADR 023): it renders the user-questions.json this skill emits, writes user-feedback.md, and the bridge auto-reruns the reflector. In interactive mode (the default) the feedback is supplied by a human. In automated mode (R4-09-F3, selected by the trigger's mode: automated) there is no human: the reflector infers each answer from the cycle logs / demo / diff and self-answers with inferred: true provenance — the per-cycle brief's Stage 2/3 tells you which mode you are in and exactly what to write.

Reads: _logs/<id>/user-questions.json (≤4 entries; [] if none written); _logs/<id>/retro.md + _logs/<id>/events.jsonl for context.

Writes: _logs/<id>/user-feedback.md — answer each numbered question, then add free-form feedback. Stage 3 distils this into retro.md Section 2 (answers) + Section 3 (free-form). Contract: packages/stations/phases/reflector-binding.ts, packages/stations/phases/reflector.ts. If the file is absent when the reflector runs, record _(no feedback supplied this cycle)_ and continue.

Required first action

Invoke brain-query BEFORE writing anything (ADR 010). First tool calls MUST be Read/Grep/Glob against brain/... or brain/projects/<project>/... paths — at minimum brain/projects/<project>/profile.md and any prior brain/projects/<project>/themes/*.md matching a pattern observed in the event log. The orchestrator records tool_use.brainReads and fails the reflection if zero brain reads are recorded (production gates on brain_consulted). Unconditional, not "when unsure".

Inputs

  • _logs/<cycle-id>/events.jsonl — full cycle log.
  • _logs/<cycle-id>/brain-gaps.jsonl — questions the brain couldn't answer (may be empty/missing — tolerate).
  • Merged project tree (read-only inspection for code patterns).
  • The merged PR (R4-09-F2): its description at <worktree>/.forge/pr-description.md (the stated intent), the reviewer.pr-opened event (PR url), and the dev-loop.delivered diff-stats (what actually shipped). No gh — read the file + the events.
  • Existing brain knowledge (prior retros, established patterns).

Outputs

  • _logs/<cycle-id>/retro.md — three sections: ## Self-reflection, ## User questions, ## User feedback.
  • Theme pages in brain/projects/<project>/themes/<YYYY-MM-DD>-<slug>.md — one file per significant pattern. Required frontmatter: title, description, category, keywords (flow-style list of 5–10 lowercase search terms — feeds brain-query slug/one-liner matching and the contradiction lint), created_at, updated_at, and related_themes (flow-style list of sibling theme slugs — see Stage 4 linking; [] only if genuinely standalone). keywords and related_themes are mandatory, not best-effort: a prior reflector run dropped both and never indexed its themes, costing a 132-theme brain all of its theme↔theme edges (ADR 018). Body must include ## Sources listing ≥1 path resolving to _logs/<cycle-id>/... or brain/cycles/_raw/<cycle-id>.md, and — when related_themes is non-empty — a ## See also section mirroring it as [[slug]] — why bullets. This matches the canonical format in `brain/cycles/themes/README.md`.
  • brain/cycles/_raw/<cycle-id>.md (cycle log archived). Required frontmatter (write these placeholder values exactly — the orchestrator post-processes to compute retention and populate cited_by; do NOT compute these yourself):
    ---
    source_type: cycle
    source_url: _logs/<cycle-id>/events.jsonl
    source_title: Cycle <cycle-id> — Initiative <initiative-id>
    cycle_id: <cycle-id>
    initiative_id: <initiative-id>
    project: <project>
    ingested_at: <ISO-8601 timestamp>
    ingested_by: reflector
    retention: auto
    cited_by: []
    ---
    Body: short summary plus the full event-log excerpt (or a link).
  • _logs/<cycle-id>/user-questions.md (stage 2; write unless literally zero deliverables). Use ## N. <header> headings. The orchestrator derives user-questions.json post-exit.
  • _logs/<cycle-id>/user-questions.json — do NOT write this yourself; derived by the orchestrator from user-questions.md post-exit.

The reflector does NOT move the manifest to _queue/done/ — the reviewer already did that.

Event-log entries to emit

  • reflector.start
  • reflector.brain-query (per query)
  • reflector.self-reflection-complete
  • reflector.user-question-emitted (per question written into user-questions.md)
  • reflector.user-feedback-captured
  • reflector.theme-emitted (per theme file written)
  • reflector.lint-pass-clean (after structural validation passes)
  • reflector.end

Process

Stage 1 — Agentic self-reflection (unattended)

Scope: the WHOLE initiative, not just the closing cycle (DEC-2). The spine
(forge-architect → forge-develop → this post-merge reflect run) threads ONE
cycle_id, so events.jsonl holds the architect/PM decompose, the dev-loop build,
and the review for the entire initiative. Reflect across all of it.

  1. Brain query first.
  2. Read the full event log. Compute: iterations per WI/feature/initiative; cost by phase/skill/model; wedge events, recovery events, brain-gap counts, send-back rounds.
  3. Repeated actions — find actions the agents took more than once across the
    initiative (re-running the same gate, re-editing the same file, re-opening a PR,
    re-deriving the same fact, retrying the same command). A repeated action is a signal of
    a missing tool, a stale convention, or an unclear spec — name each one with its count.
  4. Roadblocks / wedges — find where the cycle stalled, wedged (wedge events), burnt
    tokens with no tool progress, hit a rate limit, or needed a recovery/resume. For each,
    capture what unblocked it (or that it stayed blocked).
    4b. Review the PR (R4-09-F2). Read <worktree>/.forge/pr-description.md for the PR's stated intent, then cross-reference the shipped diff (dev-loop.delivered stats + the merged tree). Note where the delivered code diverges from the stated intent (scope drift, dropped ACs, extra changes) — this is the grounding for the implementation-vs-design question in Stage 2, and every Stage-2 question must cite a concrete PR/log specific (a changed file, a PR claim, an event count), never a generic template.
  5. Identify notable patterns — worked unusually well, wedged or burnt token, antipatterns observed.
    • Delivery truth = the dev-loop.delivered / dev-loop.discarded events (git diff-stat) + the merged tree, NOT per-WI status counts. dev-loop.delivered fires ONLY for a WI that shipped (outcome: 'complete'); a failed WI's diff-stat carries the SAME fields on dev-loop.discarded (outcome: 'failed') — attempted but not delivered. Per-WI status: failed can be stale after a resume. Never conclude "nothing delivered / empty branch" if dev-loop.delivered shows files_changed > 0. If status and diff disagree, the diff wins — and that contradiction is itself the antipattern worth a theme (stale-status-vs-real-delivery), not "the PR was empty" (cascade-v4 #1).
  6. Draft Section 1 of retro.md (## Self-reflection) — concrete observations, no hand-waving. Lead with the repeated actions and roadblocks found in 3-4 (or _(none observed)_ for either).

Stage 2 — Agent-prompted user questions (file-based handoff)

Do NOT call AskUserQuestion. Write questions to user-questions.md only; the orchestrator derives user-questions.json post-exit.

Mode (R4-09-F3). In automated mode the per-cycle brief additionally directs you to write an **Inferred answer:** <answer> — <citation> line under each question (inferred from the logs/demo/diff, never fabricated) and to self-write user-feedback.md. The orchestrator stamps inferred: true per answer in user-questions.json. In interactive mode (default) follow the human-handoff steps below unchanged.

Before writing anything, read _logs/<cycle-id>/user-feedback.md if it exists (this is a rerun — the operator already answered a prior question set). For each candidate question below (seed or Stage-1-derived), check whether user-feedback.md already answers it — same question, a paraphrase of it, or the underlying open item it was probing. Do NOT re-emit a question user-feedback.md already answers. Only genuinely new/unanswered questions may be written to user-questions.md. If every candidate is already answered, write _logs/<cycle-id>/user-questions.md with a single line — _(no open questions — prior feedback covers this cycle)_ — instead of the seed set; do not pad back up to 4 with already-answered questions just to hit a count.

  1. From Stage 1, identify items you cannot resolve from established principles + brain knowledge. These become user questions.

  2. Write up to 4 structured questions into _logs/<cycle-id>/user-questions.md (## N. <header> per question). Each question is a ## N. <header> heading, a one-line body, then (optionally) a markdown bullet list of choices — the orchestrator renders a bullet list as radio options and a question with no bullets as a freeform textarea.

    Guaranteed seed questions — include these four unless literally zero deliverables or user-feedback.md already answers them (see above):

    1. "Was the work-item decomposition the right size?" (bullets: too-few, right-sized, too-many)
    2. "Did the implementation match the design intent and stay on the initiative's goals?" (bullets: exact match, minor divergence, scope drift)
    3. Repeated actions / roadblocks — surface the specific repeated actions + roadblocks you found in Stage 1 and ask which is worth a forge fix or a new tool (bullets drawn from the actual findings, e.g. the most-repeated action, the worst wedge, "none — leave as-is").
    4. General notes — a freeform question (NO bullet list) inviting any other operator notes on this initiative.

    Replace a seed with a sharper project-grounded follow-up only when Stage 1 gives a more pointed version of the same question; keep #4 freeform. Cap at 4 total, minus whatever user-feedback.md already covers.

  3. Capture user answers (from user-feedback.md in stage 3) as Section 2 of retro.md.

Stage 3 — Pure user feedback (file-based handoff)

  1. Read _logs/<cycle-id>/user-feedback.md.
  2. If present, distil answers into Section 2 and free-form text into Section 3 (## User feedback). If absent, write _(no feedback supplied this cycle)_ for both.

Stage 4 — Brain writes (unattended)

  1. For each notable Stage-1 observation, write a theme file scoped to the right brain (Q5-B — route by the lesson's SUBJECT, per the three-brain model, ADR 018). Two routing decisions apply, in order:

    (a) Project-specific vs forge-wide. Lesson about this project (code, conventions, domain, a bug) → its project KB brain/projects/<project>/themes/<YYYY-MM-DD>-<slug>.md. Lesson about forge machinery (orchestrator, gate behaviour, Ralph loop, scheduler, PM/reflector behaviour) → forge-wide, one of the two dirs in (b). Litmus test: "would this lesson be true for a DIFFERENT project too?" If yes → forge-wide, NOT Brain 3.

    (b) For forge-wide themes, category decides the sub-wiki — this is enforced by checkCategoryScope (cli/brain-lint.ts) and a mismatch is a lint error, not a style choice:

    category frontmatter Brain dir
    pattern brain/cycles/themes/
    antipattern brain/cycles/themes/
    operation brain/cycles/themes/
    decision brain/forge-dev/themes/
    reference brain/forge-dev/themes/

    Set category first, then place the file per this table — do not default a decision or reference theme into brain/cycles/themes/ (a real rerun mis-routed a decision-category theme there; caught only by hand-running checkCategoryScope). Project-scoped themes (a) are exempt from this table — they always go under brain/projects/<project>/themes/ regardless of category.

    • Required frontmatter + ## Sources listing ≥1 path resolving to the cycle log or archive.
  2. Link + index the new theme (do not leave it an island). You already read the prior related themes in Stage 1 — record the connection instead of discarding it into prose:

    • related_themes: set it to the slugs of the prior themes this one extends, repeats, or contradicts (e.g. the earlier cycle in a recurring saga, or the topical *-index hub page for its cluster). For each slug you add, add the reciprocal entry to that theme's related_themes too, and add a ## See also [[slug]] — why bullet to both. A brand-new standalone lesson may use related_themes: [].
    • Category index: append the theme's one-line entry (- [\`](./themes/.md) — ) under the ### Auto-linkedtail of the owning category index in the same brain dir —patterns.md/antipatterns.md/decisions.md/reference.md(project brains carry these four; create the file from the cycles-index template if absent). This is whatcheckCategoryIndex` gates and what brain-query reads first.
  3. Archive the cycle log to brain/cycles/_raw/<cycle-id>.md with full provenance frontmatter.

  4. Validate: every theme file has valid frontmatter (incl. keywords + related_themes) + valid category + ≥1 resolvable evidence path + a category-index entry + reciprocal related_themes. Fix before exiting.

Direct-write brain. The reflector writes theme files directly; brain-ingest is NOT invoked. The orchestrator calls regenerateBrainIndex after you exit — that regenerates brain/INDEX.md only, not the per-category indexes; you maintain those (step 11). Do not update brain/INDEX.md yourself.

Constraints

  • Brain query first. Zero brain reads before writes = reflection fails (production gates on brain_consulted).
  • Concrete actions, not vague intentions. "We could improve X" rejected. "X happened N times; new theme page Y added; antipattern Z indexed" required.
  • Evidence-grounded themes. Every theme MUST cite ≥1 source path resolving to _logs/<cycle-id>/... or brain/cycles/_raw/<cycle-id>.md.
  • One theme per file. Don't combine unrelated lessons.
  • No queue mutation. _queue/done/ already contains the manifest. Read-only.
  • No gh operations. The reviewer already merged.
  • No web tools. WebFetch / WebSearch are disabled.

Output style

S8 / C25 — micro-caveman directive (per-phase, NOT global). Theme drafts are operator-iterated; brevity = signal. Forge-internal only.

  • Drop articles, filler ("just", "really", "basically"), pleasantries, hedging.
  • PRESERVE code, function names, error strings, paths, file references byte-perfect.
  • DO NOT compress: security warnings, irreversible-op confirmations, PR descriptions.
  • When in doubt, prefer terse.