← Maya R.'s track Lesson 08 / 12 · Maya R.

C1 Provenance — Who Wrote This Diff: Attribution For Agent-Produced Code

AIHC.2.C1Bloom's: ApplyPBL
● Exhibit 8 of 12 — Maya R.'s track

Standard: AIHC.2.C1 · Bloom's: Apply · Structure: PBL.

Notice the Say-See-Do cycles running on Maya R.'s actual work — not a canned exercise — and that every capability claim is cited to the frozen doc-set. The exit ticket climbs Bloom's to Apply, and the lesson closes by writing to the ledger.

Learning objective

(Bloom's: Apply) Apply provenance discipline to agent-produced code on payments-service: make every merged change answer three questions from the record alone — what did the agent produce, what did the human verify, and where is the session that did the work — by writing attribution into commit/PR descriptions, wiring the session-to-PR link into your flow, and fixing the convention in CLAUDE.md so it survives you — AIHC.2.C1 (Provenance).

Work at hand: your pipeline now merges code that Claude wrote, your reviewer subagent first-passed, and you verified (L5's four-leg record). But git log tells none of that story: your fee-fix commit reads like every other commit you've ever made. Six months from now, "who wrote this and what was checked" should be answerable by a teammate at 2 a.m. without paging you — that answerability is what C1 means by provenance being first-class (X5).

SSD cycle 1 — the record must say what the workflow knew

  • SAY: Provenance isn't a confession; it's a load-bearing index. A change produced by an agent and verified by a human is a different object from a change a human wrote — different failure modes, different review needs, different questions when it breaks. If the record flattens the two, every future debugging session starts by reconstructing what the record should have carried. Claude Code participates in your git flow natively — §2: you do git conversationally ("commit my changes with a descriptive message"), and §1 lists git end-to-end (stage, commit-message, branch, PR) as core workflow — which means the commit message is composed inside the very session that knows the provenance. The knowledge is present at write time; the discipline is refusing to let it evaporate.
  • SEE: Your real fee-fix change, recorded two ways: ``` AS MERGED (L5): fix: correct fee rounding in calculate_fee()

PROVENANCE-COMPLETE (what the session knew at commit time): fix: correct fee rounding in calculate_fee()

produced-by: Claude Code session (general-purpose), under lesson-2 contract v2
first-pass:  payments-first-pass-reviewer (checklist items 1, 4, 6)
verified-by: Maya — four-leg record in PR description (legs a–d, one FAIL returned+fixed)
human-authored: contract, must-not-change list, verification verdicts

`` Same diff, same tests — but only one of these can answer the 2 a.m. questions. Note the last line: provenance runs *both* directions. It records what the agent produced AND what the human actually did — claiming agent work as yours and letting agent work pass as yours are the same record-corruption with different social prices. - **DO:** Take the three merged PRs from your lesson-1 baseline (#241, #238, #235 — pre-pipeline) plus the fee-fix PR, and for each write the one-line provenance verdict the current record supports:fully-answerable / partially answerable / unanswerable` against the three objective questions (what produced, what verified, where's the session). No rewriting history — this is the "before" column your convention exists to end.

SSD cycle 2 — the session-to-PR link: provenance the tool already carries

  • SAY: One leg of provenance is mechanical and already built: §3, Pull requests — create the PR from inside the session ("create a pr for my changes"), and "gh pr create auto-links the session to the PR; find it later with claude --from-pr 1234." That link is the "where is the session that did the work" answer, for free — but only if the PR is created through the session rather than pasted together afterward in the browser. Provenance that depends on remembering to write things down loses to provenance the workflow emits as exhaust.
  • SEE: The retrieval, six months later, as it would run (described): $ claude --from-pr 312 # resumes/opens the session that produced PR #312 — the contract, the reviewer's # first-pass report, the elicitation answers, and your verification commands, # in the order they actually happened Next to it, the alternative for PR #241: nothing. The session that produced it (if any) is unfindable, because nothing ties it to the PR number. (Fania pressed the credits into the record sleeve — who played the solo isn't a thing you ask around about, it's a thing you read off the object itself.)
  • DO: Your ledger-migration review will produce your next real PR. Commit now, in your runbook/notes, to the in-session PR flow for it: PR created via the session, and a session-linked: yes (claude --from-pr <n>) line in the PR description so the link's existence is itself recorded and checkable. Then verify the claim the doc-set makes — after the PR exists, run claude --from-pr <n> (described) and confirm it resolves; a provenance mechanism you've never exercised is a mechanism you're assuming (that's your L5 discipline applied to the record itself).

SSD cycle 3 — the convention outlives the intention: fix it in CLAUDE.md

  • SAY: Cycles 1–2 produced good behavior; C1 at band 2 requires it to be standing. The carrier for a standing team convention is the project CLAUDE.md — §4: project scope is shared "team, via source control," loaded every session — written to §4's concreteness bar ("be concrete enough to verify"), so compliance is visible in a diff, not in anyone's goodwill. This is context, not enforcement (§4) — an honest limit you already know from L6 — so the convention should be cheap enough to follow that drift is laziness, not cost.
  • SEE: The convention, drafted at checkable size: markdown ## Provenance (agent-assisted changes) Every PR containing agent-produced code states, in the PR description: 1. produced-by: which agent/subagent + which contract (link or path) 2. first-pass: which reviewer ran + which checklist items it owns 3. verified-by: who ran the verification record; record pasted in the PR (see L5 format) 4. session-linked: yes/no — PRs are created in-session so `--from-pr` resolves Changes with NO agent involvement state `agent: none` — absence is declared, not implied. Line 5 is the one teams skip and regret: without it, silence is ambiguous between "no agent" and "nobody wrote it down," and the whole record decays to vibes.
  • DO: Write the real section into payments-service/CLAUDE.md, adjusted to your team's vocabulary, and run your L2 unverifiable-line audit against it: every line checkable by reading a PR, none requiring interrogation of the author. Then apply it once, retroactively, to the fee-fix PR (edit its description to the convention) so the convention's first compliant instance exists as a worked reference you produced.

SSD cycle 4 — provenance under review: reading a record skeptically

  • SAY: A provenance record is a claim like any other (your L5 rule: a claim gets a check, not a shrug). The band-2 reviewer habit: when a PR arrives claiming verified-by, spot-check that the verification it names could actually have produced the verdicts it reports — a record can be complete in form and false in content, and form-checking alone would just move the vibes one layer up.
  • SEE: A PR description that passes the convention's form and still fails a spot-check (described): first-pass: payments-first-pass-reviewer — but the diff touches db/migrations/, which items 1/4/6 don't cover and your L7 deny lane shouldn't even have allowed the session to edit. Two record-vs-reality collisions, both catchable by reading.
  • DO: Trade PRs with yourself: take the retroactively-conventioned fee-fix PR from cycle 3 and spot-check it cold, as the 2 a.m. teammate — do the named contract, reviewer scope, and verification legs actually cover this diff's files? File anything that doesn't hold in docs/failure-log.md (L6 format) as a provenance-class entry; the log's gap field should name the record, not the agent.

Independent at-bat

Unscaffolded: your PII log-scrub task (checklist item 4) is next in the backlog and will be agent-produced under an L2-style contract. Run its entire provenance chain alone: in-session PR, convention-complete description, verification record pasted, --from-pr link exercised, and a one-line agent: none declaration on whichever companion commit (if any) you wrote by hand. The chain is complete when a teammate could answer all three provenance questions from the PR page alone — check it by actually reading the PR page as that teammate before merging.

Exit ticket

(Graded against your PR records, your CLAUDE.md convention, and the cited doc-set sections — never against intentions.)

  1. (Remember) Per §3, what does gh pr create do to the session, and what command uses that link later?
  2. (Understand) Why does the convention require agent: none to be declared rather than letting absence imply it? Answer in terms of what an ambiguous silence does to the record's value.
  3. (Apply) A teammate merges an agent-produced hotfix with the message fix: null check. Write the convention-complete PR description they should have written, inventing nothing — mark each field they alone can fill as <author must supply>.
  4. (Analyze) In cycle 4's SEE, the record claimed a first-pass that couldn't cover the diff. Which convention field, which L7 lane, and which L5 leg each independently could have caught it — and which of the three catches it earliest?
  5. (Evaluate) Judge your own convention: which field will your team most likely rubber-stamp into meaninglessness within a quarter, and what one change (wording, placement, or a spot-check ritual) most cheaply protects it?

ledger_write

ledger_write:
  learner_id: L1-DEV-MAYA
  lesson_id: L1-dev-maya-08-c1-provenance
  anchors: [AIHC.2.C1]
  bloom_reached: Apply
  exit_ticket_score: ""
  auto_score: ""
  self_score: ""
  calibration_gap: " — computed once Maya's self_score exists"
  starting_mastery:
    AIHC.2.C1: "not previously evidenced — first measurement this lesson"
  journal_prompt: >
    Cycle 1 made you grade four of your own merged PRs "unanswerable/partial/full." Write the
    honest sentence about how it felt to see your own name on records that can't say what you
    did versus what the agent did — and which direction of mis-attribution you were closer to.
  structure_used: PBL
  referents_used: [salsa-fania-liner-notes]
  next_lesson_seed: >
    Lesson 9 assembles the team-facing governance proposal: the L7 project-scope flag list,
    the L6 hook draft, and this lesson's convention, sorted into advisory vs. permissioned vs.
    enforced layers — C2, with hooks as the enforcement floor.

RUBRIC SELF-AUDIT

# Indicator Verdict Evidence
R1 One objective, Bloom's-leveled, named anchor PASS States "Bloom's: Apply," names AIHC.2.C1 only
R2 Every tool claim traces to the doc-set PASS §1 (git end-to-end), §2 (conversational git), §3 (in-session PR creation; gh pr create auto-link + --from-pr, quoted verbatim), §4 (project CLAUDE.md scope, concreteness bar, context-not-enforcement) cited at point of use; the convention's content is explicitly framed as Maya's team policy, not a product claim
R3 3–6 cycles, one point each PASS 4 cycles: the record must carry what the workflow knew; the mechanical session-to-PR link; the standing convention in CLAUDE.md; skeptical reading of provenance records
R4 SEE verified against ground truth PASS SEEs quote §3 verbatim behavior, reuse her real commit/PR artifacts from L1/L5, and the cycle-4 collision is constructed from her own established reviewer scope (items 1/4/6) and L7 deny lane — nothing about the product exceeds the freeze
R5 Every DO on real work-at-hand PASS DOs grade her real merged PRs, wire the flow for her real migration PR, write her real CLAUDE.md section, retro-fix her real fee-fix PR, and log findings in her real failure log
R6 Media doctrine honored PASS Static commit/PR/markdown text only; no motion/process content
R7 Exit ticket 3–5 Qs, Bloom's-climbing PASS 5 Qs, Remember→Understand→Apply→Analyze→Evaluate, graded against records + doc-set
R8 Ledger write complete PASS auto_score/self_score = ""; journal prompt present; seed recorded
R9 Scaffolding fades; at-bat genuinely independent PASS Cycle 1 gives a full worked before/after; cycle 3 gives a draft she must rewrite and audit; cycle 4's spot-check is unmodeled beyond one SEE; the at-bat is a complete provenance chain with only an end-state test — part-faded per arc position
R10 Referents elected-only, flavor-only PASS One Fania liner-notes referent (cycle 2), decorative; the link mechanism stands on §3
R11 Info-at-point-of-use honored PASS --from-pr introduced in the cycle where she exercises it; §4 scope facts appear at the CLAUDE.md-writing DO; no front-loaded reading
R12 No replication PASS No prior lesson or exemplar touches attribution, the session-to-PR link, or record-reading; the failure-log reuse follows L6's format but files a new class of entry; all DOs/exit Qs new

Escalation: all load-bearing indicators PASS → auto-ships (Playbook §5, AIHC X2/B3).