F3 — Live human/Claude attribution in the buffer, git-native provenance #6
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Live human/Claude attribution in the buffer: as a document is coauthored, the
editor shows — live, in the buffer — which spans were written by the human
and which by Claude, with the attribution record persisted git-natively in
the same sidecar (the spec's reserved
attributions[]extension point, reusingthe shared
anchorsprimitive established by F2).Problem / pain
Coauthoring with an AI in the editor has no attribution/provenance: once a
machine edit lands in the buffer it is indistinguishable from human typing. The
human can't see, while writing, which spans they authored vs. which the machine
did — so there is no basis for trust ("did I write this claim or did it?"), no
provenance to carry up the ladder to review surfaces, and no substrate for F4's
propose/accept to render against. F2 gave regions durable discussion; nothing
yet records who wrote what.
Who feels it
A writer/engineer coauthoring prose or specs with Claude inside VS Code — one
human + one machine — who needs to know at a glance, while the document is being
written, which spans are theirs and which are the machine's, and to keep that
record when the file is committed and reopened.
Desired outcome / value
The buffer becomes an honest record of authorship: human and Claude spans are
visibly distinguished as edits happen, the attribution
survives further editing (the same hybrid re-anchoring F2 shipped), and it
persists git-natively in the shared sidecar — no server. This delivers the
epic's second acceptance pillar ("see, live in the buffer, which spans are human
vs. Claude"), populates the
attributions[]/provenancemodel F2 reserved, andgives F4's propose/accept flow the attribution substrate its accepted diffs
render into.
Acceptance — "done right"
human-attributed; when a machine edit is applied to the buffer, its spans
are recorded and rendered as Claude-attributed (visibly distinct in the
buffer, with the
provenanceprimitive —kind: human | agent— as therecord).
without a save/reload cycle.
keeps the attribution on the same logical span (anchor re-resolution); spans
that can't be confidently re-resolved are orphaned, never silently moved
(F2's INV-1 applies to attributions too).
workspace restores attributed spans from the sidecar's
attributions[](
schemaVersionhonored, no format break — spec INV-4).re-attributes it sensibly (the exact granularity/merge rules are design-time
decisions, documented in the slice).
round-trip; host E2E covers type → attribute → machine-edit → attribute →
reload, per the F2 test pattern.
Scope / non-goals
In scope: live in-buffer rendering of human/Claude span attribution;
capturing human keystrokes vs. applied machine edits as attributed, anchored
spans; the
attributions[]shape on the sharedanchors/provenanceprimitives;attribution survival across edits (re-anchor / orphan); git-native persistence +
reload in the existing sidecar; whatever minimal machine-edit ingress the
design settles on so there is something real to attribute (see the open question
below).
Out of scope (deferred): the propose/accept diff flow itself (F4 — keep /
reject UX, inline diff); the final cross-rung persistence format + Gitea
round-trip (F5 / #46); attribution of edits made outside the session (external
editors, git merges) beyond the orphan rule; per-character blame depth (span-level
is the unit); multi-file orchestration; any server.
Assumptions · constraints · dependencies
Blocks / feeds: F4 (propose/accept renders into this attribution substrate);
relates to F5 (cross-rung format).
specs/coauthoring-inner-loop.md): thesidecar's reserved
attributions: []extension point, the sharedanchorsprimitive (INV-4), the
provenanceprimitive (kind: human | agent), and theAnchorer's resolve/orphan ladder (INV-1/INV-3) are the established base — F3
fills the extension point, it does not re-litigate the format.
"applied-proposal edits vs. human keystrokes", but proposals are F4. What
counts as a machine edit in F3 before F4 exists is a genuine design
decision: (a) a minimal live
@cline/sdkturn that applies edits directly(the spec defers "where Claude runs + provider/auth" to exactly this moment —
"the first live
@cline/sdkturn, F3/F4"), (b) a programmatic apply-editingress (an internal API/command F4 later drives), or (c) both. Also open: the
exact
attributions[]shape and the split/merge granularity rules for mixededits. Epic #1 routes these to a follow-on brainstorming session — this
Feature consumes that reviewed Solution Design (or makes a provisional call
inline and flags it, per the F2 precedent). Resolve which before planning.
it — F2's no-credentials invariant (spec INV-5) ends at F3's door by design.
(
vscode.window.createTextEditorDecorationType) renders span styling withoutbespoke UI.
Source / signal
Epic #1 (
coauthoring-plugin-on-cline) decomposition item F3; the graduatedSolution Design
vscode-cowriting-plugin-content/specs/coauthoring-inner-loop.md(§6.3
attributions[]/provenance, §9 "OPEN → F3/F4"); architecture lineageben.stull/rfc-app#48. Builds on F2 shipped in #4 (PR #5, sessionvscode-cowriting-plugin-0004). Captured in sessionvscode-cowriting-plugin-0005.Priority (WSJF)
Provisional: Value high (the epic's second acceptance pillar; the
trust/provenance capability that differentiates the coauthoring surface) ·
Time-criticality medium · Opportunity-enablement high (F4 renders its
accepted diffs into this substrate; F5 carries the provenance up the ladder) ÷
Size medium → P1.
Decomposition (Feature → slice checklist)
apply vs. both;
attributions[]shape; mixed-edit split/merge rules) — consumethe follow-on Solution Design, or make a provisional call and document it.
attributions[]data model on the sharedanchors/provenanceprimitives(schema extension, vscode-free, round-trip tests — per the F2 SLICE-1 pattern).
spans, with the split/merge rules from the design.
Claude-attributed spans (provenance carries the agent identity).
human/Claude styles), updating as edits happen.
via the existing Store/Anchorer (re-anchor or orphan, never guess).
(type → attribute → machine-edit → attribute → reload).
Solution notes (optional — NOT a design)
Native primitives map cleanly: the Decorations API
(
createTextEditorDecorationType) is the obvious renderer for attributed spans —the epic's F3 line names it — and
onDidChangeTextDocument(which F2's Anchoreralready consumes for live shift) carries the edit deltas attribution tracking
needs. The Anchorer's fingerprint/resolve/orphan ladder and the sidecar's
reserved
attributions[]are the intended reuse points (spec INV-4) — F3 fillsthem rather than inventing parallel machinery. If the design picks a live
@cline/sdkturn as the machine-edit ingress, the POC's vscode-freecline.tsdriver (F1/#2) is the starting point. All non-binding — the fork above is the
design session's to resolve.