Development record
add a cross-agent session-capture source as an optional plugin
add a cross-agent session-capture source as an optional plugin
SOTA survey (2026-07-30, .abcd/development/research/notes/2026-07-30-session-recording-sota.md — candidates are named there):
- What an external capture source would add over the native store (adr-29, itd-89): capture of sessions from non-Claude harnesses, normalised to one per-session markdown format, and a reader for the legacy pre-rebuild transcript archives (the Phase-0 corpus of 439 transcripts is an immediate import candidate).
- Importing through the seam keeps the native store's posture for imported
material: storage stays out of the repo, provenance hashing applies, and the
two-stage fail-closed redaction (secrets, paths, identity) runs on import
exactly as on native capture. The
SessionEndhook remains the capture path for Claude Code sessions. - The record pre-declares the seam:
--kind specstory-importexists, the verification matrix promises timestamp/content-hash merge over the same store, but no merge/parse logic is implemented — that is the plug-in. - Under sota-per-intent this is path 2 (native floor + seam) being exercised,
not a new required dependency; guardrails are the existing invariants
applied at the import boundary (one door through
history.Capture, imported transcripts treated as untrusted, records and docs name no tool before adoption is decided). - Related gaps that shaped import quality at research time: iss-95 (capture precondition) and iss-96 (unanchored secrets) remain open; iss-125 (hostnames) and iss-157 (network identifiers) have since been resolved by the scanner's network-pattern work.
Decision (dcn-2607300000000007): a cross-agent capture source is the current default SOTA upgrade, triggered when compatibility beyond Claude Code becomes a concern. Adoption shape is import-only over the native store; the native floor stays the default and capture degrades to it when the tool is absent. The candidate tool, the target harness, and the provider-coverage caveats binding at adoption time are recorded in the research note's addendum. The SOTA verdict is re-verified at the adopting intent, and a move from optional to required tool is a sota-per-intent path-1 hard stop.
(Originally captured 2026-07-30 as iss-161 against a stale ledger; re-minted as iss-217 after the id collision with main's iss-161.)
Remedy grounds (2026-09-29)
- The remedy keeps the suggested_fix (kept above) and extends it with the J13 labelling ruling and a named trigger, so the parked record has a condition the ledger can check.
- SOTA check: the candidate tool's upstream README (https://github.com/specstoryai/getspecstory, read 2026-09-29) lists eleven terminal agent harnesses, writes history inside the project directory and is Apache-2.0, so the research note's adoption shape (import-only, the in-repo history never tracked, telemetry opted out) still fits; the README does not state the telemetry default, so the note's reading stands until re-verified at adoption.
- Rejected: a second store or a capture path that bypasses
history.Capture(the one-door rule).
Frontmatter
| id | iss-217 |
|---|---|
| type | issue |
| lifecycle | open |
| severity | minor |
.abcd/work/issues/open/iss-217-add-a-cross-agent-capture-source-as-an.md
open on GitHub ↗ · commit history ↗
mentions10
- adr-29A native local redacted transcript corpus
- dcn-26073000000000072026-07-30 — a cross-agent transcript-capture source is the current default SOTA upgrade for the history corpus, triggered when compatibility beyond Claude Code becomes a concern; adopted import-only: its output enters through the pre-declared `specstory-import` seam over the native store, so the fail-closed redaction applies to imported material, and the native floor stays the default with capture degrading to it when the tool is absent. The candidate tool, target harness, and provider-coverage caveats live in research/notes/2026-07-30-session-recording-sota.md (§6 addendum) — commitment records name no external tool before adoption is decided. The SOTA verdict is re-verified at the adopting intent; a move from optional to required tool is a sota-per-intent path-1 hard stop (new-dependency approval). Rejected: adopting the tool's in-repo history directory as a store (adr-29 already rejected external stores; transcripts stay out of the repo) and bespoke per-host parsers (a permanent maintenance burden the external tool already carries). See iss-217. (Recorded 2026-08-15; decided 2026-07-30, parked across the attribution epoch.)
- iss-95Wiring the Stop hook does NOT by itself start the transcript clock: history.Capture requires ~/.abcd/history/<root-sha>/transcripts/ to already exist and deliberately never creates it (ownedDirsReal validates the store's dirs are real, not symlinks). That dir is bootstrapped by 'abcd ahoy install'. On a machine where install has not run — including this one, where ~/.abcd/ does not exist at all — 'hook session-end' fails closed, logs to stderr, exits 0, and captures NOTHING. Silently. That is precisely the failure mode itd-89 exists to prevent: a hook that appears wired while the corpus never accrues. Decide: (a) the hook bootstraps the store itself (changes Capture's stated precondition, and a hook creating dirs is a trust-boundary act the ownedDirsReal discipline deliberately avoids), or (b) 'ahoy install' stays the sanctioned bootstrap and the not-installed case is made LOUD rather than a stderr line nobody reads (e.g. ahoy doctor already flags history.bootstrap_missing as a required gap). Until this is settled, itd-89's acceptance is met in code but not on any machine that has not installed.
- iss-96Now that transcripts are captured automatically on every session end, the scanner's secret-pattern coverage becomes load-bearing in a way it was not when capture was a manual verb nobody ran. Verified by live test: the bundled patterns DO catch anchored tokens (AKIA... access key IDs, ghp_/gho_/sk-ant- style prefixes) and absolute home paths, but they do NOT catch unanchored high-entropy values — an AWS SECRET access key (the 40-char base64 value, no prefix), a bare password, or a generic API token with no recognisable prefix all pass through into the store verbatim. This is the standard prefix-matching limitation and is pre-existing, not a regression; the point is that the blast radius changed. Consider entropy-based detection or the opt-in gitleaks adapter for the transcript path specifically, where the input is unstructured prose rather than curated source.
- iss-125Hostnames are absent from the Stage-1 redaction pattern list: itd-28's write-time sanitiser enumerates home-dir paths and provider secrets (AWS/GCP/Azure/Cloudflare/GitHub/Anthropic/OpenAI/Stripe/Slack/JWT/PEM) but no hostname patterns, and the transcript scanner's coverage gaps are already tracked as iss-96 — yet the PII discipline forbids posting real hostnames anywhere. Live specimen: a saved third-party PR page (reviewed 2026-07-25) shows two real machine hostnames leaked into public PR comments by a resident review fleet, including a '.fritz.box' home-router LAN name — exactly the class a Stage-1 net must catch before any abcd-produced artefact (review receipt, rendered PR comment, transcript) leaves the machine. Fix belongs in the scanner seam's canonical pattern set (one-canonical-primitive), not a per-surface copy; detector first: add hostname fixtures (LAN suffixes like .local/.fritz.box/.lan, machine-name shapes) to the scanner's acceptance corpus and watch them flag before widening the patterns.
- iss-157shared scanner (launch dry-run, lifeboat pack, history capture) has token-shaped secret patterns and identity matchers (username, email, home path, github remote) but no network-identifier patterns — a lifeboat pack or launch bundle carrying a tailnet IP, device hostnames, or firewall posture ships clean. Same root gap as the audit rule; fix belongs in the shared primitive, not per-surface.
- iss-161Plugin verbs render as /abcd:abcd:<verb> instead of /abcd:<verb>: the verb files live in commands/abcd/, and the harness maps a commands/ subdirectory to a namespace segment, so the directory name duplicates the plugin prefix. Verbs need to live flat under commands/ (or the subdirectory renamed away from the plugin name) for the documented /abcd:<verb> surface.
- iss-2608230752354928the history store's validKinds drops the source harness of an imported transcript
- iss-2610252224202553.abcd/development/research/notes/2026-07-30-session-recording-sota.md:79 says, from facts verified 2026-08-15, that opencode is not among SpecStory's documented providers. SpecStory now lists 15 providers, OpenCode among them (read 2026-10-24 in the state-of-the-art pass on iss-217), so the statement is out of date.
- itd-89Capture the Session You Just Had, Because You Cannot Capture It Later