SKILL
agent-seam✓ APPROVED

agent-seam

Define the handoff between two agents so a chain holds up in production: the payload schema both sides agree on, who validates it, how a refusal travels instead of turning into a null, what keys a record so a batch run cannot cross accounts, and where the checkpoint sits before anything expensive or irreversible. Takes two agent contracts and returns one seam spec per handoff, plus the reliability math for the whole chain. Trigger on "chain these agents", "how do these two talk", "the handoff between", "wire this pipeline", "pass the output to", "run this across my whole list", "multi agent workflow", "orchestrate these", or any moment one agent's output becomes another agent's input.

01 / HOW TO USE

Install it in one line, or paste it in.

1
In Claude Code (one command)
Copy the install line, paste it into your terminal, and restart Claude Code. The skill installs itself to ~/.claude/skills/ and runs automatically when it is relevant.
2
In Claude, ChatGPT, or a Project (no terminal)
Open the file, then upload it to your chat or paste its contents in. A skill is just a markdown file of instructions, so any capable AI can follow it.
New to skills? A skill is a plain-text file that teaches your AI a workflow. Point any capable assistant at it and it follows the steps, on your data.
02 / MAKE IT YOURS

Connect your context. Set it to your motion.

SET IT TO YOUR MOTION
Set thisWhat it isDefault / Example
PAYLOAD formathow records cross the seamone JSON object per record
CORRELATION keywhat uniquely names a record through the whole chainaccount domain plus run id
COST linethe step where a failure starts costing real moneythe render callthe send
RETRY policywhat may be retried automaticallyidempotent reads only
CHAIN floorthe end to end rate you will accept90 percent of records produce a usable output
03 / THE FULL SKILL

Everything the skill does, in full.

WHAT THIS DOES

Takes two agents that are about to be chained and returns the seam: the exact payload that crosses, who checks it, what happens when the upstream agent refuses, what keys each record so a batch of twenty cannot mix account nine into account fourteen, and where the human checkpoint sits if the next step spends money or cannot be undone.

Then it does the arithmetic nobody does. A chain is as reliable as the product of its links. Four agents at 95 percent is 81 percent, and 81 percent across twenty accounts is four bad outputs with your face on them. The seam spec is where you decide whether to fix that with a better link or a checkpoint.

This is step seven of the agent build order in SHIP-A-SOLUTION.md. It runs after both sides have a contract from agent-contract, and that half is not a preference: without contracts there is no seam, just two agents guessing at each other, and the guess shows up as a field that was always a string until the day it was an array. The verdicts from eval-set-builder are different. They should exist and often do not yet, and a missing one is a line on the card and a named blocker rather than a reason to leave the seam unwritten.

AN ASSERTED CONTRACT IS NOT A CONTRACT

"Both sides have contracts" is a sentence. The seam gets written from the consumer's input line and the producer's output schema, field by field, so you need the text in front of you. When you cannot see it, the seam is marked PROVISIONAL, every field you could not read is marked ASSUMED with the question that would confirm it, and no field name you invented is ever presented as agreed. A provisional seam is a useful draft. A provisional seam dressed as a spec is how two teams find out in week three that they meant different things by "signal."

The same rule applies to numbers. A link with no verdict has no pass rate, so the chain rate is unknown rather than estimated, and the missing verdict is the finding: an ungated link sets the chain's rate and nobody knows what it is. A verdict somebody quoted is not the same as one you read: name the verdict file, or mark the number REPORTED and put confirming it in the questions. A chain rate built from four remembered numbers is a sentence with a decimal point in it.

And the card always gets emitted. Every stop in this file, a missing contract, a gap at the seam, a cycle with no termination rule, is a state of the card rather than the absence of one. The line reads GAP or UNKNOWN, the questions collect at the bottom, and the card carries one of three statuses, defined so that exactly one of them fits every card:

  • READY. Every line is written, the change requests are empty or accepted, and the isolation test has been run with its result on the card.
  • PROVISIONAL. The lines are written but something is open: a field marked ASSUMED, a change request nobody has accepted, an isolation test still pending, a verdict missing. Most cards are this, and a card where every field is ASSUMED says so on the status line: it is a draft, not a spec.
  • BLOCKED. A required field has no source anywhere, a contract is missing, or a cycle has no termination rule. The rest of the card is still written.

They rank, because cards often qualify for two: BLOCKED beats PROVISIONAL beats READY. A card with a missing required field and a pending isolation test is BLOCKED, and the pending test goes in its body. A card that says BLOCKED on one line and specifies the other seven is the artifact two owners can act on. A three line refusal to write anything is not.

A field the seam needs that neither contract carries is a change request, not an invention. The correlation key, the run id, the schema version and the reason on a refusal are all of that kind: a seam needs them, and contracts written one agent at a time almost never have them. So list them on the card under CHANGE REQUESTS, name the side that has to add each one, and write the seam as though they exist. That is not passing a guess off as agreed, because the card says out loud that the field does not exist yet.

THE METHOD
  1. 1
    Step 1: Name the seam and the direction

    One producer, one consumer, one direction, one payload. Write it as a line: signal-research hands relevance one account-facts record.

    If the two agents talk both ways in one pass, a request out and an answer back, that is two seams and you spec both. If three agents all write into one, that is three seams, not one fan-in, and the differences between them are where the consumer breaks.

    A cycle is a different thing from two seams, and the test is whether the second payload re-enters the first agent as new input to redo its work. Researcher asks, writer answers, done, is two seams. Writer drafts, researcher corrects, writer redrafts, is a cycle. A cycle needs two things written down before anything gets built: what terminates it, and how many passes are allowed. Without both, do not build it, and say which of the two are missing rather than refusing the whole request. The card comes out BLOCKED on that pair of seams and READY on the rest.

  2. 2
    Step 2: Write the payload as the intersection, not the union

    The payload is what the consumer needs. Not everything the producer happens to know.

    Start from the consumer's input line, field by field, and pull only those from the producer's output schema. Whatever is left over stays home. A payload that carries the producer's whole output makes every field a dependency, and two months later someone deletes one and something unrelated breaks.

    An optional consumer field with no producer source anywhere is a different thing from one that is sometimes absent: its absence rule fires on every record, forever. Say that on the card, because an absence rule written for the odd case reads very differently once you know it is the only case, and the consumer's contract usually needs changing rather than the seam.

    If a required consumer field has no source anywhere in the producer's output schema, that is a gap at the seam and not a mapping exercise. Name it on the card as a GAP, say which side should produce it, and carry on writing the rest of the seam. The card comes out BLOCKED with one named gap, which is exactly the thing the two owners can act on. Projecting one field onto another because the names are close, a consumer that needs a dated fact and a producer that emits untyped news items, is how a required field arrives empty in production and the chain blames the consumer.

    One more shape, because half the agents in a chain have it. When the consumer's grain is a set rather than a record, a clusterer, a rollup, a report, the unit crossing the seam is the batch: the payload is a list plus a batch id, the manifest is the list of keys in that batch, and the validator checks the batch before any of it is read. The no carry rule then applies between batches rather than between records, because carrying between records is the whole function of an aggregator. Say which of the two shapes the seam is, record or batch, on the card. A batch assembled across several runs, a month of nightly output, is its own case: it carries a batch_id and a batch level manifest, while each member keeps the run_id it was produced under. Specifying a batch consumer per record is how you hand an agent a must-never that forbids its own job.

    The correlation key, the run id and the schema version sit on top of the intersection rather than inside it. They are seam fields: the consumer did not ask for them and the seam cannot work without them, so they go in the payload and, when neither contract carries them, onto the change request list. That is the one exception to pulling only what the consumer's input line names.

    Then mark each field on the consumer's side:

    • Required. Absent means the record does not cross. No default, ever.
    • Optional, with a defined absence. The consumer has a rule for missing. Write the rule here, not in the prompt.

    Three states, and collapsing them is the most common seam defect in existence: present, null because the producer looked and there is nothing, and missing because the producer never looked. Null and missing mean different things and the consumer must treat them differently. If the producer's schema has no way to say "looked and found nothing" as distinct from "never looked", that is a change request on the producer rather than a state you quietly drop. A schema offering only a complete answer or a refusal collapses the two on every record. A seam that turns "never checked" into an empty string is how an agent writes confidently about an account nobody researched.

  3. 3
    Step 3: Put the validator on the consumer

    The consumer validates every record it receives, against the payload schema, before doing any work. Always the consumer, for one reason: the producer cannot be the thing that certifies the producer.

    A record that fails validation does not get fixed and does not get guessed at. It gets rejected with the field that failed, and it goes to the operator, not to the next step. Write down where rejections land. A rejection nobody sees is a silent skip, and a silent skip in a twenty account run is the one you find out about from the prospect.

    The producer's job at the seam is smaller and it is not nothing: stamp the payload with its own version and the correlation key, and never emit a partial record. Half a record is worse than no record, because half a record validates on the fields that are there.

  4. 4
    Step 4: Make the refusal travel

    Both sides already have an abstain state from agent-contract. The seam decides what happens when one fires.

    The rule: a refusal upstream is a refusal for the record, not a null field downstream. When signal-research says it found no dated fact, the composer does not receive an empty facts array and write something anyway. It receives a refusal for that account and the account leaves the chain with its reason attached.

    Write three lines:

    • What the consumer does with an upstream refusal. Usually: stop this record, carry the reason forward, continue the batch.
    • Where the refused records collect. One list, visible, with the reason on each. This list is the most useful artifact the chain produces and almost nobody keeps it.
    • Whether a refusal is final or re-enterable. If a human can supply the missing fact and re-run that one record, say how, because that is the highest value human move in the whole pipeline.

    Fan-in changes this rule, and it is the case people get wrong. When several producers feed one consumer, a refusal from one of them is not automatically a refusal for the record. So the consumer marks each inbound payload required or contributing: a refusal on a required input ends the record, and a refusal on a contributing input degrades the output and is named inside it. A forecast rollup should not die because one rep-notes summarizer abstained, and it should also not present itself as complete when it did.

    Fan-in needs two more lines that nobody writes. What key joins the inbound records into one output, which is the correlation key and never the arrival order. And whether the consumer waits for all of them or runs on whatever arrived by a deadline, which is what decides whether a slow producer is a delay or a missing field.

    A chain that drops refusals quietly will always look like it worked.

  5. 5
    Step 5: Key every record, then prove isolation

    Every record crossing every seam carries a correlation key and a run id. Not for tidiness. Because the failure mode of a batch is contamination, and contamination is invisible in the output.

    Two rules:

    • The run carries a manifest, the list of keys this run is supposed to process, and the consumer refuses any record whose key is not on it. If there is no manifest, say so on the card: the isolation test below is then the only protection you have, and it is the weaker one.
    • Nothing carries between records, or between batches where the consumer's grain is a set. No cached page, no last good value, no "the customer story from the previous account." State that as a must-never on the consumer if it is not there already, test it with a batch where two records are deliberately adjacent and similar, and write the result of that test on the card. An untested isolation rule is a sentence.

    READY is a status a card earns after the chain has run once, not at the moment it is specified, so most cards are PROVISIONAL on the day they are written and that is correct rather than a failure. The test gates going live, not writing the card. Write it out, mark it PENDING with the three inputs it needs, and the card is PROVISIONAL until somebody runs it. What is not allowed is a READY card whose isolation rule has never been exercised.

    The test that catches this: run the chain over three accounts where account two has almost no data. If account two's output contains anything that can only have come from account one or three, the chain has a contamination defect, and a single account run will never show it.

  6. 6
    Step 6: Find the cost line and put the checkpoint above it

    Walk the chain and mark the first step that spends money, sends something, writes into a system other people read, or cannot be undone. That is the cost line.

    A chain of pure reads has no cost line, and that is a finding rather than a blank to fill. Say so, skip the checkpoint, and put a sample review on the chain's terminal output instead, which is the last seam when another agent consumes it and the screen or the document when a human does: the owner reads a handful of outputs, worst first, because the failure mode of a read-only chain is not a cost, it is a wrong answer nobody checked. Never name a false cost line to satisfy the step.

    Where more than one step is irreversible, each one gets its own checkpoint. The first is the cost line; the others do not become free because the first one was approved.

    When the cost line is the consumer itself, a sender that sends the moment it receives, there is nowhere above it to put a checkpoint inside the existing system. That is a change request on that consumer and the card says BLOCKED, with the checkpoint written out as the thing to build. Never specify a checkpoint as though it already exists, and never let "the sender is already live" settle it: already live is a description of the risk, not a resolution of it.

    The checkpoint goes immediately above it, and it is a human approving a batch, not a human approving each record, unless the per record cost is high enough to deserve it. Write what the human sees at the checkpoint: the thing that will be spent, the count, and the records that are about to go through with the weakest inputs. Ranked worst first, because the checkpoint is a sampling instrument and an unordered list of twenty gets approved without being read.

    Retries stop at the cost line too. Idempotent reads retry freely. Anything that spends gets one attempt and a ledger of what was already done, keyed by correlation id, so a re-run does not pay twice. A chain without that ledger will eventually bill you twice for the same twenty renders.

  7. 7
    Step 7: Do the arithmetic and decide

    Multiply the pass rates of the links on the serial path, the ones every record has to pass through to reach the output. That product is the chain rate, and it is the number that matters, not any individual agent's 95 percent. Contributing inputs do not multiply, because a record survives their refusal, so list them beside the product with what the output loses when each is absent.

    Two things do not belong in the product. The test for whether a step is an agent: does it make a judgment from an input that could have come out differently? A writer and a scorer do. A mail API, a render call and a person pressing send do not, whatever their uptime. A step that is not an agent is not scored even when somebody has attached a number to it, because its failure mode is availability rather than judgment and a 0.99 on a mail API is measuring a different thing than a 0.91 on a writer: name it, count it out, and say the product covers the agent links only. And a by design abstain is not a failure. An agent that correctly declines a third of accounts because those accounts have no tickets should not drag the chain rate down for doing its job, so compute that link's rate over the records it actually answered, and publish the abstain rate beside it as its own number. A sentiment reader that answers 60 of 100 accounts and is right on 53 of those is a 0.88 link with a 40 percent by design abstain rate, not a 0.53 link. An abstain that was supposed to happen and a wrong answer are not the same event, and the arithmetic has to stop treating them as one.

    Then compare it to your chain floor, and to the batch size when you have one. When the product is unknown because a link on the serial path has no verdict, there is no comparison to make and the decision is already decided: gate that link first. Say that rather than leaving the step half run. A 0.81 chain over twenty records is roughly four records that need a human. Decide, out loud, which of these four things you are doing about that:

    • Raise a link. Find the weakest and send it back to its own gate.
    • Move the checkpoint. Accept the rate and catch the four at the checkpoint, which is the right answer more often than people expect.
    • Shorten the chain. Two agents at 0.95 beat four at 0.95, and one of the four is usually plumbing that did not need to be an agent.
    • Add a sample review. The option for a chain of pure reads, where there is no cost line to put a checkpoint above. The owner reads a fixed number of terminal outputs per week, worst first.

    Two things about this step. The recommendation is yours and the decision is the pipeline owner's, so write it as a recommendation with the owner named, never as an acceptance issued on their behalf: accepting a rate below the floor is a risk somebody has to own and it is not you. And what you may not do is report the best link's number as the chain's number. Publish the product.

  8. 8
    Step 8: Emit the seam spec

    One card per seam, plus one chain line for the whole thing. File it with the consumer, at public-skills/<consumer-slug>/evals/seams.md, and link it from the producer. The seam belongs to both builds, and a document with two owners gets read by neither, so it lives with the side that validates and the other side is pointed at it. If neither has a directory yet, it lives with the work until one does.

QUALITY GATES
  • Both contracts were read as text, not asserted. Anything unread is marked ASSUMED and the seam says PROVISIONAL.
  • The payload is the consumer's intersection, not the producer's union.
  • Every required consumer field has a named source in the producer's schema. Any that does not is reported as a gap at the seam rather than mapped onto a near neighbour.
  • Every field is required or optional with a defined absence, and no required field has a default.
  • Present, null and missing are distinguished, and the consumer has a rule for each.
  • The validator sits on the consumer and rejections have a named destination.
  • Upstream refusals travel as refusals for the record, collect in one visible list, and have a stated re-entry path, an explicit none, or UNKNOWN with the question that would settle it.
  • On fan-in, every inbound payload is marked required or contributing, and the join key and the wait rule are written.
  • A cycle has a termination rule and a pass limit, or it is not built and the missing one is named.
  • The seam says whether its unit is a record or a batch, and a batch consumer is not specified per record.
  • Every record or batch carries a correlation key and a run id, the run carries a manifest or says it has none, and cross record contamination is a stated must-never whose test is written out, with its result on the card or marked PENDING.
  • The chain rate decision is written as a recommendation with the deciding owner named, not as an acceptance made on their behalf.
  • Any field the seam needs that neither contract carries appears under CHANGE REQUESTS with the side that has to add it.
  • The card was emitted with a status, READY or PROVISIONAL or BLOCKED, rather than withheld.
  • The cost line is named and the checkpoint sits above it, showing the weakest records first. A chain of pure reads says it has no cost line and puts a sample review on the chain's terminal output, which is the screen or the document when a human reads it and the last seam when another agent does.
  • Every irreversible step has its own checkpoint, not just the first one.
  • The retry policy stops at the cost line, with a ledger keyed by correlation id.
  • The chain rate is the product of the serial agent links, published as the product, compared to the chain floor, and reported as unknown when any link on that path has no verdict. Non agent steps are named and counted out, contributing inputs are listed beside it rather than multiplied, and by design abstains are published separately instead of scored as failures.
  • No em dashes anywhere.
OUTPUT (EXAMPLE)
EXAMPLE OUTPUT
CHAIN: account-list to rendered video        4 agents, 3 seams

SEAM 1   enrichment -> script-writer
  payload   one account_facts record
    domain            required   string, the correlation key
    run_id            required   string
    role              required   string, the decision maker's role
    pages[]           required   1 to 5 {url, text}, the source of truth
    use_case          optional   absent means the writer picks from
                                 pages[] and says so in beat 2
    customer_story    optional   absent means beat 3 carries no
                                 story and says what it does
                                 have. the output is four beats,
                                 so omitting one breaks the
                                 consumer's own schema
    schema_version    required   "1"
  three states
    pages[] null      enrichment looked, the site is JS only      REFUSE
    pages[] missing   enrichment never ran for this domain        REJECT
  validator  script-writer, before any writing
  rejections go to the run log and the operator, never onward
  refusals   upstream refusal ends the record. reason carried.
             re-entry: operator pastes 2 facts and re-runs that
             one domain.

SEAM 2   script-writer -> render
  payload   one script record
    domain            required   string, the correlation key
    run_id            required   string
    beats[]           required   exactly 4 {line, source_url}
    schema_version    required   "1"
  validator render step, and it checks one thing hard: every
            source_url is on the domain in the correlation key.
            A source_url from another account is a contamination
            hit and fails the record.
  isolation  test run 2026-09-10 on three adjacent accounts with
            the middle one thin. no borrowed source_url. the
            result being on the card is what makes this seam
            READY rather than PROVISIONAL.
  COST LINE here. render spends per video and the output has
            Heath's face on it.
  checkpoint human approves the batch. sees: count, total cost,
            and the 5 weakest scripts first, ranked by fewest
            sourced lines.
  retries    none past this line. ledger keyed domain + run_id,
            so a re-run of a batch never re-renders a paid video.

SEAM 3   render -> delivery
  payload   one {domain, run_id, video_url, script_hash}, all
            required
  validator delivery, and it refuses any video whose script_hash
            is not in the approved batch. That is what stops an
            unapproved render from reaching a prospect.
  SECOND IRREVERSIBLE STEP. sending is not free because the
            render was approved, so it gets its own checkpoint.
            that checkpoint is a person, every time.

CHAIN RATE
  enrichment     0.94   verdict, 100 cases
  script-writer  0.91   verdict, 100 cases
  render         n/a    not an agent. a paid API call, watched
                        at the checkpoint rather than scored
  delivery       n/a    a human sending
  product        0.855  the two agent links only. the other
                        two are not agents and are not scored
                        here, which is why this is not called
                        the whole chain's number

  0.855 over 20 accounts is between 2 and 3 records that need a
  human, and it is below the 0.90 chain floor. Accepted anyway,
  with the reason written down: the checkpoint sits above the
  cost line, so a person sees the weak records before money is
  spent rather than after. Re-decide at 100 accounts, where 14
  is too many to read.

One sharpener: run three adjacent accounts where the middle one
is thin. If the thin one's script borrows a fact from its
neighbours, you have a contamination defect that no single
account run will ever show you.
EXAMPLE CHAT
EXAMPLE CHAT
You
Clay feeds the script writer, the script writer feeds HeyGen. Wire it.
CLAUDE
Two seams, and they are not alike. The first one is a data seam and the second one is a cost seam, and the second is where the thinking goes. Start with seam one. What does the writer actually need from Clay, field by field?
You
The account, the decision maker, a use case, and a customer story that fits.
CLAUDE
Then three of those are required and one is a trap. The customer story is Clay making a judgment, and when Clay cannot find a good fit it will still return something. What does the writer do with a story that does not fit this account?
You
Probably uses it anyway.
CLAUDE
That is the defect. It will be fluent and it will be wrong, and it is wrong in the beat where you are claiming relevance. So the seam says: customer_story is optional, and absent means beat three is omitted rather than invented. Three beats grounded beats four beats with one borrowed.
You
And HeyGen?
CLAUDE
That is the cost line, so the checkpoint sits above it. The part I want to insist on: the render step validates that every source URL in the script is on that account's own domain. That is one check and it is the only thing standing between you and a video with your face on it citing a different company's website.
You
That would be bad.
CLAUDE
It is also the normal failure of a twenty record batch, not an exotic one. Nothing about running twenty at once makes any single record wrong; what it does is make the wrong one invisible. Which is why the checkpoint shows you the five weakest scripts first rather than all twenty in the order they happened to finish. One sharpener: put the correlation key in the payload now, even before you automate anything. The first time you debug this at twenty accounts, that one field is the difference between a minute and an evening.
04 / GO FURTHER

Where an operator takes this next.

01
Keep the seam spec with the contracts

A seam is the only artifact in the chain that belongs to two builds at once, so it gets its own file and both owners read it.

02
Version the payload

One `schema_version` field costs nothing and it is how a producer upgrade stops being a silent consumer break.

03
Keep the refused list as a product

Over a month it is the best list you have of what your data cannot support yet, which is a buying signal for the next agent.

04
Re-run the arithmetic after every re-score

The chain rate moves when any link moves, and the checkpoint decision depends on it.

GET NEW SKILLS IN YOUR INBOX

One operator-built skill a week. Free.