Skip to content

Land the Time chapter rewrite on main - #29

Merged
mikemaccana merged 25 commits into
mainfrom
claude/land-time-chapter
Aug 7, 2026
Merged

mikemaccana merged 25 commits into
mainfrom
claude/land-time-chapter

Conversation

@mikemaccana

Copy link
Copy Markdown
Collaborator

Targets main directly. Nothing here is new work — it is #22 and #26, which never reached main.

What went wrong

#22 was merged into claude/chapter-refs-only and #26 into claude/book-time-and-address-kinds-rqs594 — each into its stack base rather than into main. Both bases had already merged by then, so both merges went into dead branches and none of the work landed. main still had the old Time chapter opening:

Solana has two clocks. Validators can nudge one of them, so measuring the wrong thing with it lets whoever profits from the error shift what your program computes.

which now reads:

Solana has two clocks: a slot counter that nobody can bend, and a wall clock that validators report and can shift by a few seconds. Measure money with the slot counter.

What this brings in

  • The Time chapter rewrite — plain opening, per-scenario guidance instead of an abstract framing, the LastRestartSlot halt section, the day-boundary explanation, and the decision tree.
  • Two new figures: clock-decision-tree.svg (three question nodes with yes/no paths) and day-boundary.svg.
  • Built-in addresses as a third kind alongside on-curve and PDA, with address-types.svg updated to match.
  • The accumulation-factor rename, following lending: name the interest index for what it is solana-program-examples#121.
  • The gesture-phrase lint rules in scripts/lint-manuscript.mjs.

Conflict resolution

appendices/glossary.md conflicted with #28. Kept curator and custody, which #28 added to main; dropped cumulative interest index, which this stack renamed to borrow accumulation factor and moved alphabetically into the B's. No entry was lost.

One fix on top

The earlier rename pass missed two lending.md paragraphs still naming cumulative_borrow_rate_index and borrowed_amount_scaled. Both are corrected here. A repo-wide grep now finds no stale identifier, and both new names exist in the companion repository at main.

Verification

npm run lint clean, node scripts/check-figure-geometry.mjs clean across 72 figures, npm run build-pdf at 243 pages.


Generated by Claude Code

claude and others added 25 commits August 7, 2026 14:26
The section described halts without saying how often they happen,
which leaves a reader to assume they are routine. Name the last one
(February 6, 2024, about five hours) from Solana's own incident
report, and set it beside the ten-hour Visa Europe outage in 2018 so
the reader sees that a network stopping is not a blockchain
peculiarity.

Both figures are sourced in the text, per the numbers rule in
WRITING-PLAN.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABFpszmPxRorwWtWGR2jXj
The chapter said addresses come in two kinds, public keys and PDAs,
which leaves the System Program, the token programs, and the sysvars
unaccounted for. They are neither: nobody holds a key for them and no
seeds derive them. Somebody chose the byte string and the runtime
treats that exact address as the thing it names.

The figure gains a third column: the Clock sysvar hanging below the
curve like the PDA, captioned with its address where the PDA carries
its seed list, and with no derivation arrow, because the absence is
the point.

Whether one of these addresses happens to decode to a curve point is
an accident of the bytes, so the book says that and does not tabulate
which ones do.

Also haloes the PDA's seed label, which the cluster curve was cutting
through at its right end.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABFpszmPxRorwWtWGR2jXj
The paragraph carried two dated incidents and four figures to make one
point: this almost never happens. Say that instead. "At the time of
writing" dates the claim without printing a number that goes stale.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABFpszmPxRorwWtWGR2jXj
The section stated the rule and left the reader to apply it. Lead with
a table of the jobs a program actually has (accrual, price freshness,
human deadlines, annual rates, display), what to measure each in, and
what goes wrong with that choice. The principle keeps one line
underneath, where it belongs once the answers are in hand.

Drops the closing halt paragraph: the table's watch-for column now
carries what a halt does to each choice.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABFpszmPxRorwWtWGR2jXj
"The Arithmetic of Money builds this properly; what matters here is
the unit" tells the reader a point exists without making it. The point
is that the index advances by slots rather than seconds, so say that.

Same fix for "that is the whole reason they count slots", which
announces a reason before giving it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABFpszmPxRorwWtWGR2jXj
"Money that accrues does so per slot, in both programs of this book
that accrue anything" made the reader hunt for the programs and left
"accrues" without an object. Name them and say what accrues: the
lending market accrues interest on debt, the perpetual futures venue
accrues funding on open positions.

"Validators can nudge it" stated the capability and stopped. Say what
it buys: where an auction closes or an option expires on a timestamp,
whoever moves the clock decides which side of the boundary a
transaction lands on. Then give the two defenses, a margin wider than
the drift, or slots.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABFpszmPxRorwWtWGR2jXj
Final pass for practicality. Three additions and one correction.

A per-program table closes the chapter: every program in Part II that
touches time, what it times, the mechanism it chose, and how that
choice behaves under the two threats the chapter has been building
toward, validators leaning on the seconds and the chain stopping.

A figure for the day boundary, which the prose described but never
showed: the contribute window running to the first tick of day 7, the
refund window starting at that same tick, one expression deciding both.
With it, a paragraph on which edge "seven days" names, since a
contributor reads the phrase as the end of the seventh day and this
window closes at its start.

The order book gets its own answer recorded: where a clock would decide
something valuable, count instead. Price-time priority reads a sequence
number, and the order's timestamp is kept for display, which the
example's own comment states.

Correction: the freshness-window table said three programs and listed
three. The perpetual futures venue has a 150-slot window too, verified
against MAX_PRICE_STALENESS_SLOTS in the companion repository.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABFpszmPxRorwWtWGR2jXj
The built-in address column was drawn before the icons were restyled,
so its Clock sysvar box kept the old hand-drawn table glyph while the
offer account beside it had the new one.
A built-in address that decodes to a curve point has a perfectly well
known public key: it is the address, printed on the page. What nobody
holds is the private key. Three places said "key" where only the
private half was meant, in the chapter, the glossary, and the figure
caption.
The chapter used price feeds fourteen times across its prose and three
tables, three chapters before Offchain Truth introduces oracles. The
reader had met the word once, in a list in the Introduction.

Two fixes, both in place. The first prose mention now says what a price
feed is: an account some publisher keeps updated with a price and the
time they published it. And the freshness section opens by splitting
the two questions a program has about a price, sending trust to
Offchain Truth and keeping recency here, so a reader knows what they
are not being asked to understand yet.
Four sentences summarized a technique instead of stating it, leaving
the reader to reconstruct what was compressed:

- "one multiplication per refresh does the work of looping over every
  borrower every slot" is the effect. The design is that the market
  stores each borrower's principal and one shared index, and computes
  a debt by multiplying them.
- "there is a third answer, and the order book uses it" made the
  reader hunt for the answer. The order book takes the next number
  from a counter, and matching compares those numbers.
- "both are money" for two indexes: they decide what somebody owes.
- "where a program's own deadline is for humans, timestamps are what
  humans mean" is a riddle. A contributor told they have a week means
  seven days of wall-clock time, not a count of slots.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABFpszmPxRorwWtWGR2jXj
Cross-references named the chapter but never said it was a chapter, so
"Offchain Truth answers the first" read as a sentence about offchain
truth. Half the chapters are named after ordinary things (Time, Tokens,
Escrow, Offchain Truth), so the reader had no way to tell a pointer
from a subject.

The form is now "the *Offchain Truth* chapter": italics delimit the
title, the word says what it is, and a leading "The" is dropped inside
the italics so "the *The Adversary* chapter" never happens. Applied to
all 47 references across 16 files.

WRITING-PLAN carries the convention, and lint-manuscript.mjs enforces
it for the distinctive multi-word titles. The single-word ones are
ordinary words too often to match mechanically, which the rule says.

Also: "Mainnet has spent hours in that state" is "Mainnet has gone
down".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABFpszmPxRorwWtWGR2jXj
"Measure in slots anything an adversary would bend, and in timestamps
anything only a human would notice" presented two equal options and
made the reader classify their case. Slots are the default; timestamps
are the exception, and there are two of them.

The old line also mislabeled one of those exceptions. An annual fee is
not a number "only a human would notice", it is a number whose horizon
is long enough that a few seconds of drift are noise. Both exceptions
are now named for what they are.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABFpszmPxRorwWtWGR2jXj
"The example's own comment says what that field is for" cites the
source in front of the reader. The citation was evidence for the
writer; the reader needs the fact.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABFpszmPxRorwWtWGR2jXj
Four patterns, each written in this manuscript and each replaced by
the content it was standing in front of:

- "what matters here is the unit" became "the index advances by slots,
  not seconds"
- "the point is the awareness" became a sentence saying what the War
  Stories are for
- "that is the whole reason they count slots" became "they count slots
  because ..."
- "one multiplication does the work of looping over every borrower"
  became a description of what the market stores and what it computes

Three of the four had a live instance in the manuscript, now rewritten.
The lint catches the next one, which is the part that matters more than
the rules: these were all written after the rule against gesturing
already existed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABFpszmPxRorwWtWGR2jXj
One real clarity bug and eleven sentences that summarized instead of
stating.

The bug: "a freshness window measured in seconds is blown at the
restart, and one measured in slots is not" taught the opposite of the
lesson. Being blown is the safe outcome, so the bold lead made the
correct behaviour sound like the failure and the dangerous behaviour
sound fine. It now says which half is dangerous.

The rest:

- "measuring the wrong thing with it lets whoever profits from the
  error shift what your program computes" is "somebody else can move
  your numbers".
- "the exception that shows the rule" is a cliche standing in front of
  a reason. The vault counts seconds because its feed publishes a
  wall-clock time.
- "has a companion check that closes its gap" is "needs one more
  check".
- "counted in something nobody can lean on" is "nobody can move".
- "It advances by slots" could be the chapter or the index. Named.
- "reaches for it twice" is "uses it twice".
- The opening table still said slots were for what an adversary would
  bend, which contradicts the slots-by-default rule the chapter now
  gives. Both say default now.

What You Learnt gets the same treatment: the clock bullet matches the
default rule, the index bullet says what to store rather than what the
multiplication saves, and the halt bullet was one sentence carrying
four ideas and is now two bullets.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABFpszmPxRorwWtWGR2jXj
The chapter had grown to 2,546 words, longer than The Adversary and
nearly twice Tokens, for a subject that is two clocks. It is 2,336
now, and everything cut was said twice.

- The opening table's "Use it for" column previewed the chapter's own
  conclusion, which two closing tables give properly.
- The day-boundary edge had two paragraphs, added at different times,
  making the same point about "seven days" meaning day seven's first
  tick.
- "Two patterns run through the table" restated the slots-by-default
  rule from fifteen lines earlier.
- The roll-up repeated the four freshness numbers from the table above
  it. It carries the units now; the numbers stay where they are taught.
- "Everything measured in slots was paused, and everything measured in
  seconds was running the whole time" restated the two sentences
  before it.
- "Mainnet has gone down, but" in front of a sentence already saying
  halts are rare.

What stayed: both closing tables, which answer different questions
(which clock for a job, and what each program chose and how it holds
up), the three halt consequences, which teach with numbers the tables
have no room for, and the eight-bullet summary, one per section.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABFpszmPxRorwWtWGR2jXj
"Somebody else can move your numbers" named neither who nor how much,
and gave the reader nothing to do. Name both clocks, say which one
validators can shift and by how much, and give the rule in the third
sentence.
The table listed jobs and left the reader to find theirs. A tree asks
the questions instead, in an order that resolves the cases the table
could not: four questions, and the first one you answer yes to is your
answer.

- only the order things arrived in?      a counter of your own
- the age of a number someone published?  whichever unit they stamped
- a real-world time you promised a person? the wall clock
- anything else, and anything worth money  the slot count

The order carries a real decision. A fundraiser's deadline is worth
money and a validator would happily move it, which argues for slots,
but it is also a promise made to a person in days. The promise wins and
the margin handles the adversary, so the promise question comes first.
The prose under the figure says so, because a reader who reasons from
the adversary alone will pick differently.

Also gives the order book's counter and the "use the publisher's unit"
rule a place in the answer, which the table never had.

Chapter is 2,213 words, down from 2,336: the tree says more than the
table did in less room.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABFpszmPxRorwWtWGR2jXj
The first attempt was a spine with labels hanging off it, which is a
flowchart's skeleton without its nodes. Each question is now a boxed
node, and each edge is labelled: yes goes right to the answer, no goes
down to the next question, and three noes fall through to the slot
count.

Square corners on every box, because rounded corners mean an account
and nothing else.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABFpszmPxRorwWtWGR2jXj
The companion repository renamed `cumulative_borrow_rate_index` to
`borrow_accumulation_factor` and `borrowed_amount_scaled` to
`borrowed_principal`, because the old name described neither a rate nor
what the number is for. The book followed, so no prose names a field that
does not exist:

- the Time chapter's formula block and the surrounding prose
- the Arithmetic of Money heading and definition, which owns the concept
- the lending chapter's account model and invariants
- the glossary entry, retitled and moved into the B's
- five lending figures that showed either identifier

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABFpszmPxRorwWtWGR2jXj
The pair of handler conditions is a two-item comparison a reader wants to
hold side by side, so it reads better as a list than as a sentence. The
prose after it keeps the reason the two conditions come from one
expression.

Also correct the What You Learnt summary, which said four questions decide
the clock when the decision tree asks three and defaults on three noes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABFpszmPxRorwWtWGR2jXj
Rename the lending index to the borrow accumulation factor
PRs #22 and #26 were each merged into their stack base rather than into
main, and both bases had already merged, so none of the work reached main.
This merges the tip of that stack onto current main.

Glossary conflict resolved by keeping `curator` and `custody`, added to
main by #28, and dropping `cumulative interest index`, which this stack
renamed to `borrow accumulation factor` and moved into the B's.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABFpszmPxRorwWtWGR2jXj
The account-model paragraph and the reserve-setup paragraph still named
`cumulative_borrow_rate_index` and `borrowed_amount_scaled`, neither of
which exists in the companion repository any more.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABFpszmPxRorwWtWGR2jXj
@mikemaccana
mikemaccana merged commit 8798d95 into main Aug 7, 2026
@mikemaccana
mikemaccana deleted the claude/land-time-chapter branch October 13, 2026 00:23
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.

2 participants