Skip to content

Copy words, Take names, Drive access and Repair each live in one place (#302) - #312

Merged
Skeyelab merged 5 commits into
mainfrom
issue-302-copy-module
Oct 11, 2026
Merged

Skeyelab merged 5 commits into
mainfrom
issue-302-copy-module

Conversation

@Skeyelab

Copy link
Copy Markdown
Member

Closes #302

Scope agreed with Eric: "after the Take". Gaps are still found in TakeWriter (on the writer thread, ADR-0002) and tracked by TakeSession during the Take. Nothing in the live recording path changes beyond renaming the access type.

What changed (one commit each)

  1. Copy and outcome words live once. DestinationKind.name ("Device"/"Drive"), CopyOutcome.word and TakeMetadata.Repair.Outcome.word. CopySummary, ShowList, ShowReport and CopyCheck build their sentences from these, and every sentence is unchanged. The Show report is per Gap rather than per Copy, so what it shares is the Copy name and the two Repair words. "Not repaired" stays in the report.
  2. A Take's name is made in one place. TakeMetadata.name(take:) ("Take 01") replaces 11 String(format: "Take %02d") calls (9 in the Kit, 2 in the App). ReaperExporter.takeName is left alone: it is a Marker label inside ProjectExport, which only renders, not a folder name.
  3. One type for the Drive opened for a Take. Destinations.DriveAccess replaces Recording.DestinationAccess. It has a public init(folder:stop:), and release() becomes end(). The App passes store.beginAccess() straight in.
  4. DriveAccess can be ended from any thread. An earlier version made end() main-actor only, which broke the App's Show-list load because it ends access inside a detached Task. The tests' release counters are now a Sendable ReleaseCounter.
  5. Repair is one module. RepairQueue folds into TakeRepair: an ended Take goes in, Copy outcomes come out. The work that fills Gaps (fill, length, bytesToExtend) is now internal to it. StemRepair in BroadcastWave is untouched.

Kept on purpose

The run: test seam on TakeRepair stays. The real Gap fill and the tests' stand-in are two adapters. The stand-in's gate is the only test that pins "the latest Take's outcome wins" deterministically: RepairTests.laterTakeOutcomeWins passes whichever order the Repairs finish in.

How it was checked

https://claude.ai/code/session_013qdugNZbXwKKz5gPzzi2CL

…ord, Repair.Outcome.word (#302)

Assisted-by: Claude Code:claude-opus-5-5
Claude-Session: https://claude.ai/code/session_013qdugNZbXwKKz5gPzzi2CL
…s count with a Sendable counter (#302)

Assisted-by: Claude Code:claude-opus-5-5
Claude-Session: https://claude.ai/code/session_013qdugNZbXwKKz5gPzzi2CL
Ended Take in, Copy outcomes out. The Gap-filling work is private to it; the
run: seam stays (the real fill and the tests' stand-in are two adapters, and the
stand-in is what pins the latest Take winning).

Assisted-by: Claude Code:claude-opus-5-5
Claude-Session: https://claude.ai/code/session_013qdugNZbXwKKz5gPzzi2CL
@Skeyelab
Skeyelab enabled auto-merge (squash) October 11, 2026 03:49
@Skeyelab
Skeyelab merged commit e00addd into main Oct 11, 2026
2 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.

One module owns a Copy's Gaps, Repair and outcome

1 participant