Lesson 18 of 36

The Factory Charter and Scoreboard

ProjectFree to read · saving needs Core14 min · Slice → Gate → Run → Wrap → Prove · Updated 2026-10-28
You end this lesson with: factory/charter.md — one repo's complete factory charter: line map, lanes, gates, readiness tier, identities, context map, scoreboard and the incident tests, with the single lane you will switch on first

Illustrative composite. Parcelpath is a made-up seven-person company that sells a shipping-label API and a merchant dashboard. Over six months its team wrote fifteen good documents about its agent line: a line map, review rules, a holdout set, a registry, a scoreboard. They sit in a folder. Then a new engineer asked a plain question in the team channel: "Which part of the repo can the agents merge on their own right now?" Four people gave four answers. One quoted the autonomy map, one quoted the risk lanes, one said "docs, I think", and one had a different list of protected paths in a pull-request comment. Nobody was wrong about their own file. The files had never been forced to agree.

You have built the pieces across all five modules. This project makes them agree on one page and makes you commit to a single first step. The deliverable is factory/charter.md - one repo's complete factory charter: line map, lanes, gates, readiness tier, identities, context map, scoreboard and the incident tests, with the single lane you will switch on first. It serves the Prove stage of the course loop (Slice, Gate, Run, Wrap, Prove): a line you cannot summarise in one reviewed page is a line nobody can hold to its promises.

Brief

Use the repo you have been building the factory/ folder for. If you skipped lessons or never had a real repo, use Parcelpath, given in full below, and write any module file you are missing as a short version from the fixture. The charter is not a copy of the fifteen files. It is a page that states, for each part of your repo, what the line may do unattended, what it may not, and how you will know when to stop it.

The inputs: fifteen module files

Every one of these must exist and be non-empty before the charter can be signed.

text
factory/  line-map.md          (Lesson 01, Slice)  release-slice.md     (Lesson 02, Slice)  autonomy-map.md      (Lesson 03, Slice)  review-gate.md       (Lesson 04, Gate)  holdout-set.md       (Lesson 05, Gate)  protected-paths.md   (Lesson 06, Gate)  risk-lanes.md        (Lesson 07, Gate)  blueprint.md         (Lesson 08, Run)  readiness-score.md   (Lesson 09, Run)  release-path.md      (Lesson 10, Run)  registry.md          (Lesson 11, Wrap)  identity-ledger.md   (Lesson 12, Wrap)  context-map.md       (Lesson 13, Wrap)  scoreboard.md        (Lesson 14, Prove)  incident-lessons.md  (Lesson 15, Prove)

If you did Projects 1 and 2, factory/merge-gate-charter.md and factory/readiness-scorecard.md are also inputs. Link them from the charter; the acceptance list does not require them.

The fallback repo: Parcelpath

Illustrative composite. Every figure below is modeled, not measured. Parcelpath does not exist.

text
Paths and what they do  docs/**       public help site; CI builds it, checks links and spelling;                a path guard fails any change touching a file outside docs/  web/**        merchant dashboard; unit tests, partial contract tests;                rollback to the previous build takes about five minutes  labels/**     carrier integrations and label generation; unit tests plus                a replay of last month's labels against hand-computed rates;                a bad release prints wrong labels until rolled back  billing/**    merchant invoices and payment calls; unit tests only;                a wrong run charges real merchants  .github/**, CODEOWNERS, .claude/**, factory/**, holdouts/**                the files that govern the agentsLine (from line-map.md)  intake queue -> build (agent) -> CI queue -> review queue -> merge queue -> staging  gates: CI (owner: platform lead), reviewer + human (owner: lane owner),         merge queue (owner: platform lead), staging soak (owner: release owner)Readiness (from readiness-score.md): Silver.  Checks 1-7 pass. Check 8 fails: two of five sampled tickets say only  "see the thread". Silver unlocks ready PRs in lanes risk-lanes.md marks low.Agents (from identity-ledger.md)  scribe    docs changes     sponsor: Dana (docs owner)  fixer     bug fixes        sponsor: Ravi (web owner)  migrator  dependency bumps sponsor: Mei (platform lead)  The requester never approves their own agent's PR.Context facts (from context-map.md)  service tier, owner, blast radius, who must approve, ticket acceptance  criteria. Tier for billing/: critical. Tier for docs/: low.Last 28 days (from scoreboard.md), agent PRs merged per lane  docs 31, web 40, labels 18, billing 7   (total 96)  reverts: docs 0, web 3, labels 2, billing 0  incidents traced to a merged PR: web 1, labels 1  merged with no human review: 8, all in docs (sampled audit: 1 in 5)  median wait for first human review: 6 hoursIncident tests (from incident-lessons.md)  1 prompt-only freeze        2 injected issue text      3 over-scoped token  4 oversized diff            5 upgrade passed, failed in production

The charter template

Your factory/charter.md must use these exact headings and these exact table columns, because the acceptance checks read them.

markdown

Factory charter: <repo name>

Owner: <one named human> Signed: <date> Next review: <date, at most 90 days out>

Scope and owner

Module fileStageOwnerLast reviewed
factory/line-map.mdSlice<name><date>
(one row for each of the fifteen files)

Line map

<five lines: stages, queues, gates, named approver per gate. Point to factory/line-map.md>

Lanes

LaneMatchAutonomyCheckRevert pathTripwire
(one row per lane, copied from factory/autonomy-map.md, with the tripwire from factory/risk-lanes.md)

Gates

<review-gate.md, holdout-set.md, protected-paths.md, risk-lanes.md: one line each, with the red control that proves the gate can fail>

Readiness tier

<tier held, what it unlocks, the tier-drop rule in one sentence. Point to factory/readiness-score.md>

Identities

<each agent, its sponsor, the rule that stops self-approval. Point to factory/identity-ledger.md>

Context map

<the facts the line cannot read from the repo, who keeps them fresh. Point to factory/context-map.md>

Scoreboard

<six metrics, each with its denominator and its paired guardrail. Point to factory/scoreboard.md>

Incident tests

<five incidents, each with the control that blocks it. Point to factory/incident-lessons.md>

First lane to switch on

  • Lane:
  • Why this lane first:
  • Check that earns it:
  • Revert path:
  • Tripwire:
  • Owner:
  • Review date:

What the line may not do

<three to five sentences, each a prohibition a script or a rule enforces>

The rule for contradictions

Your files will disagree somewhere. When they do, apply these in order and write each resolution in the charter:

  1. The stricter autonomy level wins (Lesson 03).
  2. A protected path outranks every lane (Lesson 06).
  3. A readiness tier caps every lane: a lane cannot sit above what the held tier unlocks (Lesson 09).
  4. A number with no denominator is dropped from the charter, not rounded.

Steps

Step 6 is fully worked on Parcelpath. Step 7 is faded: the shape is given and you finish it. Steps 1 to 5 and step 8 are open, with only the template to guide you.

  1. Inventory the module files. Run the script below from the repo root, then fill the Scope and owner table in factory/charter.md, one row per file, each with a named human owner. Produces the first section of factory/charter.md.

    bash
    for f in line-map release-slice autonomy-map review-gate holdout-set protected-paths risk-lanes blueprint readiness-score release-path registry identity-ledger context-map scoreboard incident-lessons; do  test -s "factory/$f.md" || echo "MISSING OR EMPTY: factory/$f.md"done

    A clean run prints nothing. Write any missing file from the fixture or your repo before moving on.

  2. Write the line map and lanes sections. Summarise factory/line-map.md in five lines, then build the lanes table from factory/autonomy-map.md. Add each lane's tripwire from factory/risk-lanes.md. Where two files give a lane different levels, apply the contradiction rule and write the resolution beneath the table. Produces the Line map and Lanes sections of factory/charter.md.

  3. Write the gates section. One line per gate file: what it blocks, who holds the approval, and the red control that proves it can fail. A gate with no red control is listed as "unproven" and cannot support the first lane. Produces the Gates section of factory/charter.md.

  4. Write readiness, identities and context. State the held tier and the single check blocking the next one. For each agent, name its sponsor and quote the rule that stops self-approval. List the context facts that route an approval and the person who keeps each fresh. Produces three sections of factory/charter.md.

  5. Write the scoreboard and incident sections. Name the six metrics with their denominators. Pair every throughput number with a guardrail. List the five incident tests and the control that blocks each. Produces two sections of factory/charter.md.

  6. Choose the one lane to switch on first (worked). The lane needs a written check, a cheap revert and a tripwire the scoreboard can read, and the held tier must unlock it. On Parcelpath:

    Illustrative composite. Modeled data, as above.

    LaneCheck that can failRevertHeld tier unlocks itScoreboard evidence (28 days)
    docsbuild, links, spelling, path guardrevert commit, site redeploysyes31 PRs, 0 reverts, 0 incidents
    webpartial contract testsredeploy previous buildyes40 PRs, 3 reverts, 1 incident
    labelsreplay against hand-computed ratesroll back releaseyes18 PRs, 2 reverts, 1 incident
    billingnone that fails on a wrong totalrefunds by handno7 PRs, human-led

    Web is the tempting choice because it has the most volume. It is also the lane with the most reverts, and its check does not fail on the failures that reached users. Billing has no check and no tier. Docs is the only lane where all three tests pass and the numbers are clean. Write it as:

    markdown

    First lane to switch on

    • Lane: docs (docs/**)
    • Why this lane first: only lane with a check that can fail, a one-commit revert, held-tier unlock and clean 28-day numbers
    • Check that earns it: CI build, link check, spell check and path guard (factory/autonomy-map.md)
    • Revert path: revert the commit; the site redeploys itself
    • Tripwire: TBD in step 7
    • Owner: Dana (docs owner)
    • Review date: 2026-11-25

    Produces the First lane to switch on section of factory/charter.md. The tripwire stays open until the next step.

  7. Write the tripwire (faded). The scoreboard says 8 docs PRs merged with no human review, sampled 1 in 5. The tripwire must name a number, a window, an action and a person who lifts it. Finish this line, then check your answer:

    markdown
    • Tripwire: pause the docs lane when ____ in a rolling ____ days; ____ lifts the pause after ____.

    Produces the finished First lane to switch on section of factory/charter.md.

  8. Sign and verify. Add factory/charter.md to factory/protected-paths.md, owned by the charter owner and enforced by the server-side rule. Run the dangling-reference check below, then get a second person to read only the charter and answer the new engineer's question: which part of the repo may the agents merge on their own right now? Produces the signed factory/charter.md.

    bash
    grep -o 'factory/[a-z-]*\.md' factory/charter.md | sort -u | while read p; do  test -s "$p" || echo "DANGLING: $p"done

    If the second reader gives a different answer from yours, the charter is not finished.

Acceptance

  • All fifteen module files exist and are non-empty: the inventory script from step 1 prints nothing.
  • factory/charter.md has every heading in the template, spelled exactly.
  • The Lanes table has the columns Lane, Match, Autonomy, Check, Revert path and Tripwire, with one row per lane and no empty cell in a dark or light lane.
  • The Scope and owner table lists all fifteen files, each with a named human owner and a review date.
  • Every factory/...md path named in the charter exists: the dangling-reference check prints nothing.
  • The first lane names its check, its revert path and its tripwire, and the held tier unlocks it.
  • The tripwire states a number, a window, an action and who lifts it.
  • Every gate in the Gates section names its red control, or is marked unproven and is not used to justify the first lane.
  • factory/charter.md is listed in factory/protected-paths.md, and no agent identity can write to it.
  • A second reader, shown only the charter, names the same first lane you chose.

Rubric

CriterionWeakStrong
ConsistencyThe charter repeats module files, and where they disagree it quietly picks oneEach contradiction is named and resolved by the stated order, with the stricter level winning
First laneChosen for volume or enthusiasm; check, revert or tripwire left vagueChosen because a check can fail, a revert is cheap and the tier unlocks it; all three written in one place
TripwireA round number copied from another lane, with no window and no person to lift itA number the lane's own history can trip, a window, an action, and a named lifter
Evidence honestyMetrics with no denominator, or gates listed as proven with no red controlEvery metric has a denominator and a guardrail; unproven gates are labelled and kept out of the argument
UsabilityOnly the author can answer what the line may do unattendedA second reader answers it from the charter alone, in under two minutes

Key Takeaways

  • Reconcile your fifteen files into one page before you let any lane run unattended.
  • Resolve contradictions with a written order: stricter level, protected path, readiness cap, denominators.
  • Start with one lane that has a check that can fail, a cheap revert and a tripwire.
  • Write a tripwire as number, window, action and the person who lifts it.
  • Protect the charter like any file that governs the agent, and review it on a date.
  • A charter earns trust when a stranger reads it and names the same first lane.

What You Have Now

factory/charter.md - one repo's complete factory charter: line map, lanes, gates, readiness tier, identities, context map, scoreboard and the incident tests, with the single lane you will switch on first. It sits on top of fifteen module files and answers, on one page, what the line may do unattended, what it may not, and what makes you stop it. If you also built the merge gate charter and the readiness scorecard in Projects 1 and 2, link them from the Gates and Readiness tier sections.

text
factory/  line-map.md  release-slice.md  autonomy-map.md  review-gate.md  holdout-set.md  protected-paths.md  risk-lanes.md  blueprint.md  readiness-score.md  release-path.md  registry.md  identity-ledger.md  context-map.md  scoreboard.md  incident-lessons.md  merge-gate-charter.md  readiness-scorecard.md  charter.md

The Software Factory kit above is what you hold, and the charter is the file the others report to. Open factory/scoreboard.md once the first lane has run for four weeks and read the lane's numbers against its tripwire. If the lane stayed clean, widen it by one lane through a dated edit to factory/autonomy-map.md, made by a human. If it tripped, the tripwire did its job: read the incident, add a test to factory/incident-lessons.md, and decide with the numbers whether to switch the lane back on. Either way, raise what you can verify before you raise how much the line produces.


NO-QUIZ

Quiz coming to this lesson

This lesson doesn't have a graded quiz yet — completion is still tracked, just not verified against questions.

Not savedReading every lesson is free; you only pay to save progress and do the labs.See plansSign in