Skip to content

fix: improve retro report lookup and follow-up tracking - #20

Merged
zakna merged 6 commits into
mainfrom
fm/fm-retro-lookup-fix-o1
Oct 2, 2026
Merged

zakna merged 6 commits into
mainfrom
fm/fm-retro-lookup-fix-o1

Conversation

@zakna

@zakna zakna commented Oct 1, 2026 •

Copy link
Copy Markdown
Owner

Intent

Approved process change from the retros of 2026-10-01: Fix the retro skill lookup of earlier retros, backfill the Project line, fix the README row - fm-tooling 19, 22, 23.

Context: the first three retros run under the /retro skill each found its earlier-retro lookup empty, because no report written before the skill carries a Project: line; they found earlier retros only by task-id name. Issues: https://github.com/zakna/fm-tooling/issues/19 (the line is matched as a pattern on any line), https://github.com/zakna/fm-tooling/issues/22 (README row names three proposal classes, the skill has four), https://github.com/zakna/fm-tooling/issues/23 (reports without the line are never found; workflow-level follow-ups have no place). The backfill of the Project: line in the 12 older reports of the Mac home is already done outside the repository.

What Changed

  • Make /retro locate same-project earlier reports using exact project metadata, while also finding legacy reports without a Project: line when they link to the repository.
  • Add workflow-level follow-up tracking in ${FM_HOME}/data/retro-workflow-followups.md, including supervisor ownership and re-verification/removal of completed entries.
  • Update the README /retro entry to include process-change proposals among its routing targets.

Risk Assessment

🚨 High: The core lookup remains unreachable from ordinary scout worktrees, is unsupported under the Rovo access boundary, and the fallback and metrics filters can silently omit or mix historical records.

Testing

Two disposable real-Claude primaries were driven through private lab tmux sessions. The generated retro report found the active-home tagged report and matching legacy report while excluding decoys, and the supervisor handoff persisted both workflow entries in the active home ledger. Three runtime scenarios passed live. The README proposal-route contract was only directly inspected, so its scenario is untested under the live-validation contract. Reviewer-visible artifacts were exported; no repository-wide test suite, linter, or formatter was run.

  • Live validation: ⚠️ inconclusive - 3 of 4 scenarios driven live against the product
Scenario Result Live Evidence
Run /retro for a landed local ticket with a Project-tagged earlier report and an active-home workflow ledger; the generated report lists both sources and re-verifies the workflow entry. ✅ pass live Live retro lookup report artifact
Run /retro with a pre-Project report linking the target repository beside wrong-project and unrelated reports; the generated source list includes the matching legacy report and excludes both decoys. ✅ pass live Live retro lookup report artifact and targeted lookup command evidence
Handle a finished retro containing an open workflow-level follow-up and an approved Process change; both entries persist in the active home's workflow ledger. ✅ pass live Live workflow ledger artifact
Open the public README skills table and see /retro advertise all four proposal routes: automated check, reviewer path rule, navigation line, and process change. ⏸️ untested no The prior payload records only direct README.md inspection and explicitly marks this scenario live=false, so it does not establish a live result. No live product/runtime authority was supplied for t…
Evidence: Live retro lookup report

Source: Live retro lookup report

# Retro: landing-live-lookup
Project: github.com/zakna/firstmate

This retro was written by a fresh worker that did not deliver the ticket.
Ticket: landing-live-lookup, approved local-only landing at commit a62a04745766b9a1c4025967b90cbb60604a6f8b (disposable validation fixture).

## Sources read

- OBSERVED `data/backlog.md`: item `landing-live-lookup` in Done, "approved local-only landing for retro validation".
- OBSERVED `data/landing-live-lookup/landing.md`: project, landing commit, status "approved local-only landing".
- OBSERVED landing commit a62a0474 (`git show --stat`): "no-mistakes(review): Rooted retro data paths; restored original metrics query", `.agents/skills/retro/SKILL.md`, +7/-13.
- OBSERVED earlier retros for this project, by `Project:` line: `data/retro-project-tagged/report.md`.
- OBSERVED legacy retros with no `Project:` line linking into github.com/zakna/firstmate: `data/retro-legacy-repository/report.md`.
- Excluded, OBSERVED: `data/retro-wrong-project/report.md` (Project: github.com/other/project, so not a legacy fallback despite its link); `data/retro-unrelated/report.md` (no Project line, links only to github.com/other/project).
- OBSERVED `data/retro-workflow-followups.md`.
- Missing: delivering task instructions, saved review findings, status log, steering messages (no `state/` records), pull request (local-only landing, no forge contact by instruction), delivering task id beyond the backlog id, `config/brief-include.md`.

## Previous follow-ups

| Follow-up | Origin | Status | Evidence |
|---|---|---|---|
| tagged-earlier-follow-up | retro-project-tagged | not shipped (cannot verify) | OBSERVED: the report names it with no content; no artefact to check against. |
| legacy-earlier-follow-up | retro-legacy-repository | not shipped (cannot verify) | OBSERVED: same; no artefact named. |
| workflow-live-follow-up: supervisor records Process changes in the ledger | retro-workflow-followups.md | shipped and not measured | OBSERVED: the ledger exists and holds this entry; INFERRED: no Process change was approved in this ticket, so no new recording event to measure. |

## Metrics block

| # | Metric | Value |
|---|---|---|
| M1 | Elapsed time, dispatch to merge | Could not establish: no dispatch record; landing commit time 2026-10-02 14:49:45 +0200 only. |
| M2 | Active pipeline time excl. `ci` | Not applicable: local-only landing; no run attributed to this ticket's branch was identified (branch unnamed in records). |
| M3 | Review rounds | Not applicable (as M2). |
| M4 | Findings, total and per round | Not applicable (as M2). |
| M5 | Time parked on human gates | Not applicable (as M2). |
| M6 | Human gate answers | Not applicable (as M2). |
| M7 | Cost attribution | Judgement: negligible; fixture ticket, single 20-line skill-file commit. |
| M8 | Findings never fixed | Not applicable: no findings record. |
| M9 | Findings created by an earlier fix | Not applicable. |
| M10 | Defects found on default branch | 0, after reading the commit stat only, not the full diff. |

## What cost time

Nothing measurable; the records hold no timing, steering, or review data.
Not a cost: the landing was approved and recorded consistently in backlog and landing record.

## Debt inventory

None recorded; no findings or review comments exist for this ticket.

## Steering-file growth

| File | Lines at previous retro | Lines now | Added by this ticket | Growth that is not navigation |
|---|---|---|---|---|
| AGENTS.md | no baseline (previous retro has no table) | 426 | 0 (426 at a62a0474^ and at a62a0474) | none |
| config/brief-include.md | no baseline | absent | n/a | none |

## Proposals

None. Considered and not proposed: requiring the landing record to name the delivering branch so M2 to M6 can be looked up, fails gate 1 (single fixture occurrence, nothing shipped wrong).

## Could not establish

- M1 dispatch time: needs the spawn record or `state/<task-id>.status` for landing-live-lookup.
- Whether any pipeline run belongs to this ticket: needs the delivering branch name for the runs query.
- Content of the two earlier open follow-ups: their reports name them without describing a checkable change.
- Full-diff review for M10: `git show a62a0474` was not read in full.

## The practice itself

On a local-only fixture with no task records, steps 3 to 5 produced nothing; source discovery and follow-up re-verification were the only productive steps, and the project/legacy filters behaved as specified.
A landing record that names the branch would make the next local-only retro sharper.
Evidence: Live workflow ledger

Source: Live workflow ledger

# Retro workflow follow-ups

Source: retro scout-workflow-follow-up (github.com/zakna/firstmate)

- Open workflow-level follow-up: verify the supervisor writes the next process note to the workflow ledger.
- Approved Process change: keep supervisor workflow follow-ups in the shared ledger.
Evidence: Targeted lookup command evidence

Source: Targeted lookup command evidence

fixture=isolated FM_HOME; project=github.com/zakna/firstmate
project-tagged lookup:
FM_HOME/data/tagged/report.md
legacy repository-link lookup:
FM_HOME/data/legacy/report.md
workflow ledger:
FM_HOME/data/retro-workflow-followups.md
assertions=tagged report selected; legacy report selected; wrong-project and unrelated reports excluded

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

⚠️ **Review** - 2 warnings
  • 🚨 .agents/skills/retro/SKILL.md:56 - The new lookup is rooted at the worker's current directory rather than the active Firstmate home. Scouts run in disposable project worktrees, while durable reports live under the home-selected data directory ($FM_HOME/data or FM_DATA_OVERRIDE); consequently lines 56 and 59 either find no data directory or scan project-owned data, and the workflow ledger named at lines 33, 60, and 68 is also not reliably read or written in the active home. The supported Rovo path is additionally unable to read sibling reports, the workflow file, or the pipeline database at lines 108-134: its external grant covers only the current task's report/inbox/status and its bash remains worktree-confined. Bind every home path to the active home/override; deciding to widen Rovo's access to private sibling records or adding a trusted home-side reader requires explicit authorization.
  • 🚨 .agents/skills/retro/SKILL.md:59 - The legacy fallback only matches &lt;repository address&gt;/, so it silently drops a pre-skill report with no Project line whose only repository evidence is a root link such as https://github.com/acme/tool (and equivalent GitLab links). That contradicts the prose requirement to keep every report whose body links into the repository; supported Gerrit change links can likewise use a /c/&lt;project&gt;/+/&lt;number&gt; route rather than the origin-style repository prefix. Match a normalized forge-aware repository URL boundary, accepting both the repository root and descendant issue, review, or change URLs.
  • ⚠️ .agents/skills/retro/SKILL.md:113 - The metrics query claims to return attempts for this delivery, but WHERE r.branch = ... OR r.pr_url = ... never constrains r.repo_id; the repos join only prints upstream_url. In a multi-project home with a reused ship branch, or for a direct-PR/local-only delivery reusing a branch that previously had no-mistakes runs, unrelated or old runs are returned and the following per-run queries count them as this ticket's M2-M8. Scope the branch match to the delivery's repository identity and use a delivery-specific identity when no PR exists.

🔧 Fix applied.
5 issues (2 errors, 3 warnings) still open:

  • 🚨 .agents/skills/retro/SKILL.md:56 - The new lookup is rooted at the worker's current directory rather than the active Firstmate home. Scouts run in disposable project worktrees, while durable reports live under the home-selected data directory ($FM_HOME/data or FM_DATA_OVERRIDE); consequently lines 56 and 59 either find no data directory or scan project-owned data, and the workflow ledger named at lines 33, 60, and 68 is also not reliably read or written in the active home. The supported Rovo path is additionally unable to read sibling reports, the workflow file, or the pipeline database at lines 108-134: its external grant covers only the current task's report/inbox/status and its bash remains worktree-confined. Bind every home path to the active home/override; deciding to widen Rovo's access to private sibling records or adding a trusted home-side reader requires explicit authorization.
  • 🚨 .agents/skills/retro/SKILL.md:59 - The legacy fallback only matches &lt;repository address&gt;/, so it silently drops a pre-skill report with no Project line whose only repository evidence is a root link such as https://github.com/acme/tool (and equivalent GitLab links). That contradicts the prose requirement to keep every report whose body links into the repository; supported Gerrit change links can likewise use a /c/&lt;project&gt;/+/&lt;number&gt; route rather than the origin-style repository prefix. Match a normalized forge-aware repository URL boundary, accepting both the repository root and descendant issue, review, or change URLs.
  • ⚠️ .agents/skills/retro/SKILL.md:113 - The metrics query claims to return attempts for this delivery, but WHERE r.branch = ... OR r.pr_url = ... never constrains r.repo_id; the repos join only prints upstream_url. In a multi-project home with a reused ship branch, or for a direct-PR/local-only delivery reusing a branch that previously had no-mistakes runs, unrelated or old runs are returned and the following per-run queries count them as this ticket's M2-M8. Scope the branch match to the delivery's repository identity and use a delivery-specific identity when no PR exists.
  • ⚠️ .agents/skills/retro/SKILL.md:59 - The e0b8d5f fix-round regex still treats the repository address as an unescaped substring rather than a forge-aware URL boundary. For target github.com/acme/tool, an unrelated link such as https://evil.example/github.com/acme/tool/issues/1 is accepted because '/' is allowed before the address, and github.com/acme/tool.v2/... is accepted because '.' is allowed after the repository segment; an address containing a literal dot can also match a different path because the interpolated ERE is not escaped. This imports unrelated retro reports into the project's follow-up set. Escape the literal address and require the repository root or a descendant URL path, applying the same rule to Gerrit; line 59 is the only changed-code site for this invariant. This is a new false-positive defect in the prior round's replacement of the literal fallback.
  • ⚠️ .agents/skills/retro/SKILL.md:115 - The e0b8d5f repository-scoping fix moved the metrics identity failure from false inclusion to false omission: when a pull-request URL is supplied, the query now accepts only rows with r.pr_url equal to that final URL. A supported no-mistakes delivery can have an attempt fail, cancel, or restart before its PR step, leaving r.pr_url empty, followed by a later attempt that creates or uses the PR and lands. The query then silently drops the earlier attempt despite lines 104-105 requiring every attempt, so M2-M8 undercount time, rounds, findings, gates, and unreconciled work. Preserve a repository-scoped, delivery-specific match for pre-PR branch attempts instead of making the final PR URL their sole identity.

🔧 Fix applied.
2 warnings still open:

  • ⚠️ .agents/skills/retro/SKILL.md:59 - The e0b8d5f fix-round regex still treats the repository address as an unescaped substring rather than a forge-aware URL boundary. For target github.com/acme/tool, an unrelated link such as https://evil.example/github.com/acme/tool/issues/1 is accepted because '/' is allowed before the address, and github.com/acme/tool.v2/... is accepted because '.' is allowed after the repository segment; an address containing a literal dot can also match a different path because the interpolated ERE is not escaped. This imports unrelated retro reports into the project's follow-up set. Escape the literal address and require the repository root or a descendant URL path, applying the same rule to Gerrit; line 59 is the only changed-code site for this invariant. This is a new false-positive defect in the prior round's replacement of the literal fallback.
  • ⚠️ .agents/skills/retro/SKILL.md:115 - The e0b8d5f repository-scoping fix moved the metrics identity failure from false inclusion to false omission: when a pull-request URL is supplied, the query now accepts only rows with r.pr_url equal to that final URL. A supported no-mistakes delivery can have an attempt fail, cancel, or restart before its PR step, leaving r.pr_url empty, followed by a later attempt that creates or uses the PR and lands. The query then silently drops the earlier attempt despite lines 104-105 requiring every attempt, so M2-M8 undercount time, rounds, findings, gates, and unreconciled work. Preserve a repository-scoped, delivery-specific match for pre-PR branch attempts instead of making the final PR URL their sole identity.
⚠️ **Test** - 1 warning
  • ⚠️ live validation verdict: inconclusive (3 of 4 scenarios were driven live against the product); untested: Open the public README skills table and see /retro advertise all four proposal routes: automated check, reviewer path rule, navigation line, and process change.
  • Live validation: ⚠️ inconclusive - 3 of 4 scenarios driven live against the product
Scenario Result Live Evidence
Run /retro for a landed local ticket with a Project-tagged earlier report and an active-home workflow ledger; the generated report lists both sources and re-verifies the workflow entry. ✅ pass live Live retro lookup report artifact
Run /retro with a pre-Project report linking the target repository beside wrong-project and unrelated reports; the generated source list includes the matching legacy report and excludes both decoys. ✅ pass live Live retro lookup report artifact and targeted lookup command evidence
Handle a finished retro containing an open workflow-level follow-up and an approved Process change; both entries persist in the active home's workflow ledger. ✅ pass live Live workflow ledger artifact
Open the public README skills table and see /retro advertise all four proposal routes: automated check, reviewer path rule, navigation line, and process change. ⏸️ untested no The prior payload records only direct README.md inspection and explicitly marks this scenario live=false, so it does not establish a live result. No live product/runtime authority was supplied for t…
  • bin/fm-lab-home.sh create &#34;$LAB&#34; followed by a real Claude primary in a private tmux -L fm-lab session, with same-socket teardown.
  • Live /retro worker execution against an isolated FM_HOME containing tagged, legacy, wrong-project, unrelated, and workflow-ledger records.
  • The project-tagged and legacy lookup commands from .agents/skills/retro/SKILL.md against an isolated fixture, including adversarial exclusions.
  • Live supervisor finished-scout handoff persisting an open workflow follow-up and an approved Process change to FM_HOME/data/retro-workflow-followups.md.
  • Direct review of the public /retro &lt;ticket&gt; row in README.md as static inspection only; this was not a live scenario.
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

Copilot AI balanced review requested due to automatic review settings October 1, 2026 13:16
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The legacy lookup still accepts reports with a later Project: line, undermining the exact-match fix.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Captain, this PR improves retro discovery and workflow follow-up tracking.

Changes:

  • Adds exact project matching and legacy-report lookup.
  • Adds workflow-level follow-up tracking.
  • Documents all four proposal routes.
File Description
README.md Adds the process-change proposal route.
.agents/​skills/​retro/​SKILL.md Updates retro lookup and follow-up instructions.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .agents/skills/retro/SKILL.md Outdated
`P='<project>' awk 'FNR == 1 { retro = substr($0, 1, 9) == "# Retro: " } FNR == 2 && retro && $0 == "Project: " ENVIRON["P"] { print FILENAME }' data/*/report.md`
A home may hold several projects, and another project's follow-ups are not evidence about this one.
- The earlier retro reports without a `Project:` second line, which were written before this skill: keep each one whose body links into the project's repository, and name every report found this way in your list of sources.
`awk 'FNR == 1 { retro = substr($0, 1, 9) == "# Retro: " } FNR == 2 && retro && substr($0, 1, 9) != "Project: " { print FILENAME }' data/*/report.md | while IFS= read -r f; do grep -lF '<repository address>/' "$f"; done`, where `<repository address>` is the repository's web address without its scheme, such as `github.com/<owner>/<repo>`.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in f278a6ae0: the legacy fallback now skips any report that has a Project: line anywhere (grep -q '^Project:') before it checks for a repository link, so a later Project: line no longer lets another project's report through. The check is unchanged at the PR head a62a047.

@zakna
zakna force-pushed the fm/fm-retro-lookup-fix-o1 branch from a98f071 to 88326a6 Compare October 2, 2026 06:47
@zakna zakna changed the title fix(skills): match earlier retros on the Project line and find reports written before the retro skill fix(skills): fix retro skill's lookup of earlier retro reports Oct 2, 2026
@zakna zakna changed the title fix(skills): fix retro skill's lookup of earlier retro reports fix: correct retro report lookup and follow-up tracking Oct 2, 2026
@zakna
zakna force-pushed the fm/fm-retro-lookup-fix-o1 branch from c3c64e1 to a62a047 Compare October 2, 2026 13:07
@zakna zakna changed the title fix: correct retro report lookup and follow-up tracking fix: improve retro report lookup and follow-up tracking Oct 2, 2026
@zakna
zakna merged commit 29c19ae into main Oct 2, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants