You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Save every session created by agent in loop action #77
Thanks for the pointer. I checked the run you linked before classifying this, and the literal request already appears to be implemented:
.github/workflows/loop.yml has uploaded the pi session directory as an artifact since the first loop-host commit (ec85a181, 2026-09-10): step Upload session transcripts → loop-sessions-${{ github.run_id }}, retention-days: 90, run if: always().
The run you cited — 35837782467 — has artifact loop-sessions-35837782467 (id 10740240739, 89,434 bytes, created 2026-09-23T08:36:26Z, not expired). It contains the complete sweep session (2026-09-23T08-34-04-278Z_01a0cd66-….jsonl, 307 KB, 91 events, ending with the final assistant turn).
pr-review runs save both isolated reviewer sessions too, e.g. artifact loop-sessions-35641633339 contains reviewer-a/…jsonl and reviewer-b/…jsonl.
Runs that create no session (smoke mode, or a task skipped as not claimable) correctly upload nothing — there is no session to save.
So "save every session" is already true, via a 90-day, run-scoped artifact. What I can't tell from the issue is what the artifact does not give you. Which of these is the goal (or something else)?
Longer/permanent retention — the artifact expires after 90 days. Keep sessions for longer (e.g. a year, forever)?
Durable persistence in the state layer — copy each session under state/sessions/<run_id>/ so it is synced to the R2 state bucket with the rest of the run record and readable by sweep/retro without the Actions UI. (Loop-actionable; no workflow change.)
A pointer from the durable run record — record the session/artifact path on the run's end row in state/runs/<run_id>.jsonl, which today holds only the token/duration aggregate.
A human-readable copy — additionally export each session to HTML via pi --export.
Something else.
One constraint worth knowing up front: if the fix means changing .github/workflows/loop.yml itself (e.g. a different retention-days or upload target), the loop cannot push it — the job token has no workflows permission — so that part would need a human. Options 2–4 are implementable in scripts/loop/** as a normal loop PR.
Tell me which one (or correct me if the gap is elsewhere) and I'll classify and route it.
Thanks, and fair point: saving was never the goal, it's the input. I re-checked the loop with that framing, and the gap is real:
The sessions are saved (90-day loop-sessions-<run_id> artifact, present since the first loop-host commit), but nothing reads them back. There is no artifact consumer anywhere in scripts/loop/**.
The self-improvement stage, retro, reads only state/metrics/acceptance.jsonl and the run end rows (tokens/durationMs/model/outcome) — never the transcript. scripts/loop/README.md says so by design: "full transcripts go to the artifact store (90 days)".
So today the uploaded sessions buy durability, not improvement: the bits that would explain a run (why it timed out, which tool calls failed, what a reviewer saw, where a triage verdict went wrong) are written and then never consumed. You're asking to close that loop.
Ways to use them, in increasing scope:
One-off mine — download recent loop-sessions-* artifacts, extract failure/retry signals (timeouts, tool errors, review rejections, triage→needs-triage), and post a findings report with proposed rule changes. No automated change.
Wire retro-scheduled to sessions — the same mining, but turned into proposal PRs automatically, in scripts/loop/** + skills/retro/SKILL.md. No workflow-file change needed; the artifact already exists.
Session-aware run records — record an artifact/session pointer plus a small outcome summary on each end row, so sweep/retro can find the transcript without listing artifacts.
Two things a human should pin down before this is implementable:
What "improve" is measured against — one yardstick (auto-acceptance rate, human-intervention rate, retry/timeout count, review-problem taxonomy), or the analysis has nothing to attribute to.
The maker/checker line — automatic proposals are allowed, but a session-mining stage must not become the checker of the changes it proposes (AGENTS.md: maker or checker, never both; norms-layer changes are proposal PRs a human merges).
One constraint up front: if the fix is a different retention-days or upload target, that means editing .github/workflows/loop.yml, which the loop cannot push (no workflows permission) — that part needs a human. Options 1–3 are normal loop work.
Because this is a cross-cutting design call about the loop's own improvement process — not a bounded bug/feature we can spec from the issue — I'm labelling it needs-triage rather than starting a feature run. Pick a direction (e.g. "do 1 now, then 2"), or tell me the gap is elsewhere, and it can go ready-for-agent.
What the sessions say (full evidence in the run report; the tool is in the PR):
Recorded tokens is context size, not spend. 148,246,119 processed vs 7,120,313 recorded = 20.8×. summarize() keeps the last message_end usage, so every retro's tokensSum has been a context-growth metric. The largest single session (Support Torch Object Storage from VolcanoEngine #59, TOS provider) processed 28.96M tokens against 278,188 recorded.
The checkout is shallow, so git diff origin/main...HEAD cannot work. 15 of 29 git failures are no merge base/ambiguous argument 'origin/main'; sessions show is-shallow-repository → true, git log | wc -l → 1. Fix needs fetch-depth: 0 in .github/workflows/loop.yml — a workflow edit, so it needs you, the loop cannot push it.
Two stage skills the prompt names do not exist. 9 failed reads across 7 sessions (skills/feature/SKILL.md ×4, skills/pr-review/SKILL.md ×5). Add them or make buildPrompt name the real fallback.
Two nonexistent gh --json fields are re-learned every run. 31 of 35 gh-field failures are authorAssociation (23) and isPullRequest (8), across 34 sessions — a norms gap, not model noise.
Engine faults are invisible. Both fault sessions (terminated, Stream ended without finish_reason) still ended completed with a normal end row.
Edit mismatches concentrate on state/ANOMALIES.md (9 of 11) — one big long-lived file edited blind.
No retry storms: exactly one repeated failing command in the whole corpus. Worth knowing before optimising for retries.
What the PR does (option 2).scripts/loop/sessions.mjs mines the artifacts through the job's existing gh credential (no new scope; --dir works offline) and renders the report above. entry.mjs runs it before every retro-scheduled agent and passes the report path in the prompt (fail-open, and an unavailable report is stated in the prompt so it is never read as "no signals"). skills/retro/SKILL.md makes reading it step 0 and requires each non-zero signal to become a proposal or be dismissed with a reason. The parser is dependency-free and unit-tested.
Proposals 1, 3, 5 and 6 are left for the retro/owner rather than bundled here — this PR is the mechanism, not the rule changes. Proposal 2 is yours to make in the workflow.
Activity
github-actions commentedon Sep 23, 2026
Triage — needs more information
Thanks for the pointer. I checked the run you linked before classifying this, and the literal request already appears to be implemented:
.github/workflows/loop.ymlhas uploaded the pi session directory as an artifact since the first loop-host commit (ec85a181, 2026-09-10): step Upload session transcripts →loop-sessions-${{ github.run_id }},retention-days: 90, runif: always().35837782467— has artifactloop-sessions-35837782467(id 10740240739, 89,434 bytes, created 2026-09-23T08:36:26Z, not expired). It contains the complete sweep session (2026-09-23T08-34-04-278Z_01a0cd66-….jsonl, 307 KB, 91 events, ending with the final assistant turn).pr-reviewruns save both isolated reviewer sessions too, e.g. artifactloop-sessions-35641633339containsreviewer-a/…jsonlandreviewer-b/…jsonl.So "save every session" is already true, via a 90-day, run-scoped artifact. What I can't tell from the issue is what the artifact does not give you. Which of these is the goal (or something else)?
state/sessions/<run_id>/so it is synced to the R2 state bucket with the rest of the run record and readable bysweep/retrowithout the Actions UI. (Loop-actionable; no workflow change.)endrow instate/runs/<run_id>.jsonl, which today holds only the token/duration aggregate.pi --export.One constraint worth knowing up front: if the fix means changing
.github/workflows/loop.ymlitself (e.g. a differentretention-daysor upload target), the loop cannot push it — the job token has noworkflowspermission — so that part would need a human. Options 2–4 are implementable inscripts/loop/**as a normal loop PR.Tell me which one (or correct me if the gap is elsewhere) and I'll classify and route it.
Alex1990 commentedon Sep 23, 2026
How to improve loop based on the uploaded sessions
github-actions commentedon Sep 23, 2026
Triage — routed to a maintainer decision
Thanks, and fair point: saving was never the goal, it's the input. I re-checked the loop with that framing, and the gap is real:
loop-sessions-<run_id>artifact, present since the first loop-host commit), but nothing reads them back. There is no artifact consumer anywhere inscripts/loop/**.retro, reads onlystate/metrics/acceptance.jsonland the runendrows (tokens/durationMs/model/outcome) — never the transcript.scripts/loop/README.mdsays so by design: "full transcripts go to the artifact store (90 days)".So today the uploaded sessions buy durability, not improvement: the bits that would explain a run (why it timed out, which tool calls failed, what a reviewer saw, where a triage verdict went wrong) are written and then never consumed. You're asking to close that loop.
Ways to use them, in increasing scope:
loop-sessions-*artifacts, extract failure/retry signals (timeouts, tool errors, review rejections, triage→needs-triage), and post a findings report with proposed rule changes. No automated change.retro-scheduledto sessions — the same mining, but turned into proposal PRs automatically, inscripts/loop/**+skills/retro/SKILL.md. No workflow-file change needed; the artifact already exists.endrow, so sweep/retro can find the transcript without listing artifacts.Two things a human should pin down before this is implementable:
AGENTS.md: maker or checker, never both; norms-layer changes are proposal PRs a human merges).One constraint up front: if the fix is a different
retention-daysor upload target, that means editing.github/workflows/loop.yml, which the loop cannot push (noworkflowspermission) — that part needs a human. Options 1–3 are normal loop work.Because this is a cross-cutting design call about the loop's own improvement process — not a bounded bug/feature we can spec from the issue — I'm labelling it
needs-triagerather than starting a feature run. Pick a direction (e.g. "do 1 now, then 2"), or tell me the gap is elsewhere, and it can goready-for-agent.Alex1990 commentedon Oct 12, 2026
do 1 now, then 2
github-actions commentedon Oct 21, 2026
Session mining — evidence, then the fix (options 1 → 2)
I ran the one-off mine first, then wired the recurring retro to it.
Corpus. 100 newest
loop-sessions-*artifacts → 103 sessions, 2026-09-10 → 2026-10-21: 4,551 tool calls, 148 classified tool failures (3.3%), 2 engine faults, 148,246,119 tokens processed.What the sessions say (full evidence in the run report; the tool is in the PR):
tokensis context size, not spend. 148,246,119 processed vs 7,120,313 recorded = 20.8×.summarize()keeps the lastmessage_endusage, so every retro'stokensSumhas been a context-growth metric. The largest single session (Support Torch Object Storage from VolcanoEngine #59, TOS provider) processed 28.96M tokens against 278,188 recorded.git diff origin/main...HEADcannot work. 15 of 29gitfailures areno merge base/ambiguous argument 'origin/main'; sessions showis-shallow-repository → true,git log | wc -l → 1. Fix needsfetch-depth: 0in.github/workflows/loop.yml— a workflow edit, so it needs you, the loop cannot push it.skills/feature/SKILL.md×4,skills/pr-review/SKILL.md×5). Add them or makebuildPromptname the real fallback.gh --jsonfields are re-learned every run. 31 of 35gh-fieldfailures areauthorAssociation(23) andisPullRequest(8), across 34 sessions — a norms gap, not model noise.terminated,Stream ended without finish_reason) still endedcompletedwith a normal end row.state/ANOMALIES.md(9 of 11) — one big long-lived file edited blind.What the PR does (option 2).
scripts/loop/sessions.mjsmines the artifacts through the job's existingghcredential (no new scope;--dirworks offline) and renders the report above.entry.mjsruns it before everyretro-scheduledagent and passes the report path in the prompt (fail-open, and an unavailable report is stated in the prompt so it is never read as "no signals").skills/retro/SKILL.mdmakes reading it step 0 and requires each non-zero signal to become a proposal or be dismissed with a reason. The parser is dependency-free and unit-tested.Proposals 1, 3, 5 and 6 are left for the retro/owner rather than bundled here — this PR is the mechanism, not the rule changes. Proposal 2 is yours to make in the workflow.
chore(loop): mine the uploaded agent sessions and feed them to retro (#…