From d0e96bccbf08ba47014432c1fa1e24ea39454f67 Mon Sep 17 00:00:00 2001 From: Jason Irish Date: Wed, 8 Jul 2026 01:52:02 -0500 Subject: [PATCH 1/2] feat(#21): v0.7.0 - handoff commit/push offer + next-session briefing Phase 4 of throughline-handoff now closes the loop after writing HANDOFF.md + the session log: it emits a copy-pasteable next-session briefing (rendered from the log's existing Next steps, emit-only, no new file) and offers - never auto-runs - to stage exactly those two committable artifacts, commit, and push, guarded by git check-ignore so it correctly skips when the handoff dir isn't committable (as in this repo's own gitignored .agent/handoff/). Co-Authored-By: Claude Opus 5 --- .claude-plugin/plugin.json | 2 +- CHANGELOG.md | 24 ++++++++++++++++++++ README.md | 5 ++++- skills/throughline-handoff/SKILL.md | 34 ++++++++++++++++++++++++++++- 4 files changed, 62 insertions(+), 3 deletions(-) diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 09d072e..729f7b3 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "throughline", "description": "Continuous, state-aware session memory for Claude Code. Captures what you did and what is (commands, file changes, decisions, and live git/PR state), then hands it off with judgment at session wrap-up. Readable, committable artifacts; binds to Claude's native memory.", - "version": "0.6.1", + "version": "0.7.0", "author": { "name": "Dynamic Agency", "email": "support@dynamicagency.com" diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a51cf9..4ba9ab7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,30 @@ All notable changes to throughline are documented here. Format loosely follows [Keep a Changelog](https://keepachangelog.com/); this project uses semantic versioning. +## [0.7.0] + +Closes the loop at the end of `throughline-handoff` Phase 4 (issue #21, found +while dogfooding the skill in a consuming project). No hook behavior change - +skill-content only, verified by the unchanged 154-assertion suite plus +shellcheck. + +### Added +- **Issue #21** - Phase 4 now offers (never auto-runs) to stage exactly + `HANDOFF.md` and the new session log and commit/push them, with a + `git check-ignore` guard that skips the offer entirely when those artifacts + aren't actually committable in the caller's layout (this repo's own + `.agent/handoff/` is itself gitignored, so the guard has to handle that case + too, not just consuming projects). Never stages `buffer/` or + `.capture-errors`; push is a separate, remote-affecting confirmation that + defers to whatever push-gate/branch conventions the calling agent already + follows. +- **Issue #21** - Phase 4 also emits a compact, copy-pasteable "next session + briefing" - a pre-written kickoff prompt rendered from the session log's + existing `## Next steps`/`## Objective`/`## Key learnings & gotchas`, aimed + at priming a brand-new agent or session rather than documenting for a human + reader. Emit-only: not persisted to a file, no new `throughline-onboard` + wiring. + ## [0.6.1] Docs/skill polish batch from the v0.4.0 audit (docs/AUDIT-v0.4.0.md, P2, items diff --git a/README.md b/README.md index 6c200b7..9194f50 100644 --- a/README.md +++ b/README.md @@ -167,7 +167,10 @@ tool-agnostic project record. teammates and fresh clones get oriented. The raw `buffer/` is scratch (and can contain unredacted command text), and `.capture-errors` is a scratch breadcrumb file (capture write/permission failures only, no command text) - neither should ever be committed. -Gitignore both for whichever data dir you use: +The `throughline-handoff` skill's Phase 4 offers (never auto-runs) to stage exactly +`HANDOFF.md` + the new session log and commit/push them - it checks `git check-ignore` +first and skips the offer if they aren't actually committable in your layout. Gitignore +both scratch paths for whichever data dir you use: ```gitignore # default layout diff --git a/skills/throughline-handoff/SKILL.md b/skills/throughline-handoff/SKILL.md index 8b5c8d0..bf41cb6 100644 --- a/skills/throughline-handoff/SKILL.md +++ b/skills/throughline-handoff/SKILL.md @@ -149,6 +149,36 @@ having to carry it. Omit the line entirely for a session that starts something n clear the file now that it has been distilled - it exists to make a swallowed capture failure visible exactly once, not to keep nagging on every future onboard after it's already been read and acted on. +6. **Emit a next-session briefing.** Render a second, compact view of the session + log's `## Next steps` (plus `## Objective`, what landed, and the sharpest + `## Key learnings & gotchas` item) as a copy-pasteable fenced block in your + report - this is not new synthesis, just a different rendering of what the + log already holds, aimed at priming a brand-new agent/session rather than + documenting for a human reader. Do not write it to a file; emit-only. + + ``` + ## Next session briefing - + Continuing: + Last done: + Next: + Watch out for: + ``` + +7. **Offer to commit + push the handoff artifacts** (offer only, never auto-run - + the write already happened; this is the review-gated action): + - First check `git check-ignore DATA/HANDOFF.md` (and the new session log). If + either is ignored, or this isn't a git repo, say so and skip the offer entirely + - nothing committable exists (this repo's own `.agent/handoff/` is itself + gitignored; the check must handle that case, not just consuming projects). + - If committable, offer to stage **exactly** `DATA/HANDOFF.md` and the new + `DATA/logs/handoff-*.md` file - never `git add -A`, never `buffer/` or + `.capture-errors` (see README "Commit policy"). + - Propose a conventional message, e.g. `docs: session handoff - `, + matching whatever commit-message convention the repo already follows. + - Treat push as a separate, remote-affecting confirmation after the commit - + defer to the calling agent's existing git safety norms (branch-first on a + default branch, respect any repo-configured push gate, don't bypass one + without explicit authorization each time). --- @@ -194,6 +224,8 @@ having to carry it. Omit the line entirely for a session that starts something n secret was caught, so check what's still readable around it, not just whether a mask is present. This is defense in depth, not the sole barrier. - **Report, then let the user review.** After writing, show the HANDOFF.md diff + - session-log path. The review gate is post-write, not pre-write. + session-log path, then the copy-pasteable next-session briefing block, then the + commit/push offer. The review gate is post-write, not pre-write - commit/push is + the only action in this sequence that waits on an explicit go. - **Buffers are the source of truth for *what happened*** — they don't lie about which commands ran or files changed, even after a long, compacted session. From b8242b625a0271df985c44aae3e41afe12313cc7 Mon Sep 17 00:00:00 2001 From: Jason Irish Date: Wed, 8 Jul 2026 01:59:29 -0500 Subject: [PATCH 2/2] fix(#21): commit-offer guard handles out-of-tree data dir and partial ignores Code review on PR #22 caught three defects in the new Phase 4 step 7: git check-ignore has no case for THROUGHLINE_DATA_DIR pointing outside the project's git tree (fatal error there, a scenario session-onboard.sh already special-cases), the guard treated "either path ignored" as "skip both" instead of checking each file independently, and the staging instruction's glob could sweep in older, previously-declined session logs instead of just the new one. Fixed all three. Co-Authored-By: Claude Opus 5 --- CHANGELOG.md | 18 ++++++++++-------- skills/throughline-handoff/SKILL.md | 23 ++++++++++++++++------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ba9ab7..8630728 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,14 +12,16 @@ shellcheck. ### Added - **Issue #21** - Phase 4 now offers (never auto-runs) to stage exactly - `HANDOFF.md` and the new session log and commit/push them, with a - `git check-ignore` guard that skips the offer entirely when those artifacts - aren't actually committable in the caller's layout (this repo's own - `.agent/handoff/` is itself gitignored, so the guard has to handle that case - too, not just consuming projects). Never stages `buffer/` or - `.capture-errors`; push is a separate, remote-affecting confirmation that - defers to whatever push-gate/branch conventions the calling agent already - follows. + `HANDOFF.md` and the new session log by their literal paths (never a glob, + which could sweep in older, previously-declined logs) and commit/push them. + Guarded by `git check-ignore`, checked **independently per file** so a + partially-ignored layout still offers to commit whichever file is actually + committable, and skipped entirely when `THROUGHLINE_DATA_DIR` points outside + the project's git tree (check-ignore is fatal on an out-of-tree path, the + same case `session-onboard.sh`'s gitignore nudge already special-cases). + Never stages `buffer/` or `.capture-errors`; push is a separate, + remote-affecting confirmation that defers to whatever push-gate/branch + conventions the calling agent already follows. - **Issue #21** - Phase 4 also emits a compact, copy-pasteable "next session briefing" - a pre-written kickoff prompt rendered from the session log's existing `## Next steps`/`## Objective`/`## Key learnings & gotchas`, aimed diff --git a/skills/throughline-handoff/SKILL.md b/skills/throughline-handoff/SKILL.md index bf41cb6..633e604 100644 --- a/skills/throughline-handoff/SKILL.md +++ b/skills/throughline-handoff/SKILL.md @@ -166,13 +166,22 @@ having to carry it. Omit the line entirely for a session that starts something n 7. **Offer to commit + push the handoff artifacts** (offer only, never auto-run - the write already happened; this is the review-gated action): - - First check `git check-ignore DATA/HANDOFF.md` (and the new session log). If - either is ignored, or this isn't a git repo, say so and skip the offer entirely - - nothing committable exists (this repo's own `.agent/handoff/` is itself - gitignored; the check must handle that case, not just consuming projects). - - If committable, offer to stage **exactly** `DATA/HANDOFF.md` and the new - `DATA/logs/handoff-*.md` file - never `git add -A`, never `buffer/` or - `.capture-errors` (see README "Commit policy"). + - If `DATA` lives outside the current project's git tree (an absolute + `THROUGHLINE_DATA_DIR` pointed at a shared, cross-harness location - a + documented, supported config), skip the offer entirely: those files aren't + part of this repo's commit at all, and `git check-ignore` on a path outside + the repo fails with a fatal error rather than a clean answer (same reasoning + `session-onboard.sh`'s gitignore nudge already applies - see its comment there). + - Otherwise, check `DATA/HANDOFF.md` and the new session log **independently** + with `git check-ignore`. Offer to stage whichever of the two is NOT ignored; + if both are ignored, say so and skip the offer - nothing committable exists + (this repo's own `.agent/handoff/` is itself gitignored, so this is the + common case when dogfooding here). + - Stage **exactly** the not-ignored file(s) by their literal paths - `DATA/HANDOFF.md` + and/or the specific `DATA/logs/handoff-YYYY-MM-DD-HHMM.md` just written this + session. Never a glob like `logs/handoff-*.md` (it would sweep in older, + previously-declined session logs too), never `git add -A`, never `buffer/` + or `.capture-errors` (see README "Commit policy"). - Propose a conventional message, e.g. `docs: session handoff - `, matching whatever commit-message convention the repo already follows. - Treat push as a separate, remote-affecting confirmation after the commit -