From 69848a4931cbc559886dfc70bcc83817c2f6da19 Mon Sep 17 00:00:00 2001 From: E Ismail Date: Sat, 19 Sep 2026 00:13:56 +0100 Subject: [PATCH 1/2] test(flow): each row states the floor it claims, and a row holds them to it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pacedFloor lived inside pacingFor's body, so four rows asserted a minimum none of them had written down. A hidden floor in shared machinery is a global claim every caller inherits without saying so: a leg unable to meet it would have failed rows whose authors never made that claim. The floor is now a parameter with no default — omitting it does not compile, so a caller cannot inherit one by silence — and each caller derives its own from ITS OWN entry's record: eight times that leg's recorded block point, the multiple the retired constant was reverse-engineered from, applied to each leg's own number instead of approximated once for all three. THE NUMBERS MOVE, AND TWO LEGS MOVE DOWN. Per leg, both entries: darwin 6,553,600 (+262,144 against the old shared 6,291,456), linux 4,718,592 (-1,572,864), windows 1,835,008 (-4,456,448, a 71% cut). Those two legs were previously floored at 6 MiB purely by inheritance, which is the defect; the consequence is nonetheless that their paced phases shrink, and only CI can say whether their assertions still hold. Darwin's own recorded mutation says its margin is 300 ms, so this is not a free change. THE ROW READS SOURCE, NOT VALUES: a caller whose leg has a measured record must not name the shared identifier. The number cannot answer that question — eight times a block point can land on a shared constant by arithmetic accident, and two reasons producing one number is the confusion this change is against. It reds on scanning nothing, resolves the one single-assignment alias this package uses, and fails on an alias it cannot resolve rather than passing over a caller it cannot see. THE ROW REJECTED MY FIRST SHAPE AND WAS RIGHT TO. Each site originally derived the floor and then assigned the shared value inside an `if !Measured()` fallback. Every leg is measured on both entries, so that branch was dead code — a dead else naming a shared constant is an inherited claim wearing a conditional, and the row reddened all four sites. The honest shape refuses an empty record instead: there is nothing for these rows to size a fixture from, and substituting a minimum would be invisible at the call. So unmeasuredLegFloor is now referenced by no call site. It stays documented as the value a caller passes deliberately, in the open, having reasoned about an empty record — not as a default anything falls back to. Mutation, through the harness: control green; the shared floor restored at one measured site reds this row alone, naming file, line, row, entry, leg and block point; the revert is byte-identical to the recorded sha256 and the row is green after it. make ci green — exit 0, zero FAIL, five rows passing on both the race and plain legs, three declared skips. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01XfBYBGuUkF7zUnZfAFD3dW --- internal/flow/stall_probe_test.go | 297 +++++++++++++++++++++++++++++- internal/flow/upload_test.go | 150 +++++++++++++-- 2 files changed, 428 insertions(+), 19 deletions(-) diff --git a/internal/flow/stall_probe_test.go b/internal/flow/stall_probe_test.go index e8b8019..5a9a01e 100644 --- a/internal/flow/stall_probe_test.go +++ b/internal/flow/stall_probe_test.go @@ -5,6 +5,9 @@ import ( "context" "crypto/rand" "fmt" + "go/ast" + "go/parser" + "go/token" "io" "net/http" "net/http/httptest" @@ -968,7 +971,15 @@ func probeBody(t *testing.T, size int64) string { // autotuning. func TestProbeTheUploadStallGap(t *testing.T) { entry := &timing.UploadSlowIsNotStalled - pacing := pacingFor(t, entry.Window) + // THE FLOOR IS THE ROW'S, BECAUSE THIS PROBE'S FIXTURE IS THE ROW'S. + // The comment above says why the body comes from pacingFor at all: + // the probe and the row it measures for must not drift apart as the + // window moves. A floor of this probe's own would reintroduce exactly + // that drift in the one dimension the window does not cover — so this + // is deliberately the same expression the row writes, against the + // same entry, and not a number chosen here. + floor := blockPointFloor(t, entry) + pacing := pacingFor(t, entry.Window, floor) path := probeBody(t, pacing.bodySize) store := newObjectStore(t, &deployJournal{}, pinnedBuffer) @@ -1114,7 +1125,21 @@ func TestProbeTheUploadBlockPoint(t *testing.T) { // whether the ROW's fixture is large enough to make the client // block. A body of some other size would answer it about some other // fixture. - bodySize := pacingFor(t, timing.UploadSlowIsNotStalled.Window).bodySize + // THE ROW'S FLOOR ALONG WITH THE ROW'S WINDOW, for the reason stated + // directly above about the body: this probe answers whether THE ROW's + // fixture is large enough to make the client block, so every input + // that sizes that fixture has to be the row's too. A floor of this + // probe's own would answer the question about a fixture the row does + // not use. + // + // AND THIS PROBE IS THE ONE THAT MEASURES THE BLOCK POINT, so the + // circularity is worth naming: on a leg with a record it sizes its + // fixture from the block point recorded last time, and what it + // reports is whether that is still the right number. That is a + // retake, not a tautology — the fixture is built from the old reading + // and the new reading is compared against it. + floor := blockPointFloor(t, &timing.UploadSlowIsNotStalled) + bodySize := pacingFor(t, timing.UploadSlowIsNotStalled.Window, floor).bodySize path := probeBody(t, bodySize) store := newObjectStore(t, &deployJournal{}, pinnedBuffer) @@ -1960,3 +1985,271 @@ func TestAStarvedPassIsRetakenRatherThanCounted(t *testing.T) { } }) } + +// --------------------------------------------------------------------- +// The floor is stated where it is claimed. +// --------------------------------------------------------------------- + +// sharedFloorIdent is the one floor value this package still shares, and +// the only identifier this row objects to seeing at a call site whose leg +// has something recorded. +const sharedFloorIdent = "unmeasuredLegFloor" + +// pacingForName is the helper whose floor used to be a constant inside its +// own body. Named once, so this row and its failure messages cannot +// disagree about what they are talking about. +const pacingForName = "pacingFor" + +// floorCall is one pacingFor call site and what the SOURCE says about the +// floor it passes. +type floorCall struct { + file string + line int + row string // the test function it sits in + entry string // the timing entry the floor is derived from + sharesFloor bool // the floor expression mentions the shared identifier +} + +// TestNoRowInheritsAFloorItDidNotState is the row the floor's move out of +// pacingFor's body exists for. +// +// THE CLAIM IT HOLDS: a caller whose leg has a MEASURED record derives its +// floor from that record and does not reach for the shared value. The +// shared value is for a leg with nothing recorded — the only case it was +// ever right about — and a row reaching for it on a measured leg asserts a +// minimum it has the evidence to replace. +// +// WHY IT READS SOURCE RATHER THAN VALUES. The floor arrives at pacingFor +// as an int64, and the number cannot answer the question: eight times a +// block point can land on a shared constant by arithmetic accident, and +// two different reasons producing one number is exactly the confusion this +// change is against. "Was this read from a shared constant" is a question +// about what the caller WROTE. +// +// IT REDS ON SCANNING NOTHING, like every guard in this repository. A row +// that finds no call sites has not confirmed every call site is honest; it +// has confirmed it cannot see them — which is what renaming the helper +// would produce, quietly. +func TestNoRowInheritsAFloorItDidNotState(t *testing.T) { + calls := floorCallsInThisPackage(t) + if len(calls) == 0 { + t.Fatalf("found no %s call sites to read, so this row confirmed nothing.\n"+ + "Either the helper was renamed and this row's own name for it (%q) is "+ + "stale, or the calls left this package. A row that scans an empty set "+ + "passes for the same reason a clean one does.", + pacingForName, pacingForName) + } + + leg := probeLeg() + for _, call := range calls { + entry, known := timing.Lookup(call.entry) + if !known { + t.Errorf("%s:%d (%s) derives its floor from %q, which the timing registry does "+ + "not carry.\nThis row cannot tell whether that leg has a record, so it "+ + "cannot tell whether the floor is stated or inherited.", + call.file, call.line, call.row, call.entry) + continue + } + measurement := entry.Measurements[leg] + if measurement.Measured() && call.sharesFloor { + t.Errorf("%s:%d (%s) passes a floor that reads %s, and %s has a MEASURED record "+ + "on %s — block point %d bytes.\n"+ + "A shared floor on a leg with a record is a claim this row inherits instead "+ + "of making. The block point is the measurement the floor stands in for, and "+ + "where it exists the row derives from it and says so; the shared value is for "+ + "a leg with nothing recorded.", + call.file, call.line, call.row, sharedFloorIdent, call.entry, leg, + measurement.BlockPoint) + } + } +} + +// floorCallsInThisPackage parses the package's own source and reports every +// pacingFor call with what its floor argument mentions. +// +// It resolves a single-assignment alias — `entry := &timing.Name` — and +// FAILS on one it cannot resolve rather than passing over it. A call site +// this row cannot attribute is a caller it cannot check, and skipping one +// silently is how a guard comes to cover less than its name claims. +// +// THE FILE LIST IS DERIVED, not written down: it globs the test files +// beside itself, so a call added in a third file is covered without an +// edit here. A hard-coded pair of filenames would be the second +// transcription this repository keeps removing. +func floorCallsInThisPackage(t *testing.T) []floorCall { + t.Helper() + _, thisFile, _, ok := runtime.Caller(0) + if !ok { + t.Fatal("cannot locate this file, so the package's own source cannot be read") + } + + names, err := filepath.Glob(filepath.Join(filepath.Dir(thisFile), "*_test.go")) + if err != nil { + t.Fatalf("listing this package's test files: %v", err) + } + fset := token.NewFileSet() + var calls []floorCall + for _, name := range names { + parsed, perr := parser.ParseFile(fset, name, nil, 0) + if perr != nil { + t.Fatalf("parsing %s: %v", filepath.Base(name), perr) + } + for _, decl := range parsed.Decls { + fn, isFunc := decl.(*ast.FuncDecl) + if !isFunc || fn.Body == nil { + continue + } + aliases := map[string]string{} + floors := map[string]*floorCall{} + ast.Inspect(fn.Body, func(n ast.Node) bool { + switch node := n.(type) { + case *ast.AssignStmt: + recordAlias(node, aliases) + recordFloor(node, aliases, floors) + case *ast.CallExpr: + if calleeName(node.Fun) != pacingForName { + return true + } + call := floorCall{ + file: filepath.Base(name), + line: fset.Position(node.Pos()).Line, + row: fn.Name.Name, + } + if len(node.Args) < 3 { + t.Errorf("%s:%d (%s) calls %s with %d argument(s).\n"+ + "The floor is a parameter with no default on purpose, so a call "+ + "without one should not compile — this row is looking at something "+ + "it does not understand.", + call.file, call.line, call.row, pacingForName, len(node.Args)) + return true + } + if ident, isIdent := node.Args[2].(*ast.Ident); isIdent { + built, seen := floors[ident.Name] + if !seen { + t.Errorf("%s:%d (%s) passes a floor named %q, and this row cannot "+ + "find where that value was built inside the same function.\n"+ + "It reads single assignments only, deliberately: a floor "+ + "assembled somewhere this row cannot follow is a floor no "+ + "reader can attribute either.", + call.file, call.line, call.row, ident.Name) + return true + } + call.entry, call.sharesFloor = built.entry, built.sharesFloor + } else { + call.entry, call.sharesFloor = floorFromExpr(node.Args[2], aliases) + } + if call.entry == "" { + t.Errorf("%s:%d (%s) passes a floor this row cannot attribute to a "+ + "timing entry.\nA floor has to name the record it was derived from, "+ + "or nothing can check that a measured leg is not inheriting a "+ + "shared minimum.", + call.file, call.line, call.row) + return true + } + calls = append(calls, call) + } + return true + }) + } + } + return calls +} + +// recordAlias notes `x := &timing.Name` and `x := timing.Name`. +func recordAlias(assign *ast.AssignStmt, aliases map[string]string) { + if len(assign.Lhs) != 1 || len(assign.Rhs) != 1 { + return + } + lhs, isIdent := assign.Lhs[0].(*ast.Ident) + if !isIdent { + return + } + rhs := assign.Rhs[0] + if unary, isUnary := rhs.(*ast.UnaryExpr); isUnary { + rhs = unary.X + } + if name := timingEntryName(rhs); name != "" { + aliases[lhs.Name] = name + } +} + +// recordFloor notes a local built from a timing entry and whether the +// shared identifier is ever assigned into it. Both halves of the +// `floor := 8 * … ; if !… { floor = shared }` shape reach one local, so the +// second is what makes sharesFloor true. +func recordFloor(assign *ast.AssignStmt, aliases map[string]string, floors map[string]*floorCall) { + if len(assign.Lhs) != 1 || len(assign.Rhs) != 1 { + return + } + lhs, isIdent := assign.Lhs[0].(*ast.Ident) + if !isIdent { + return + } + entry, shares := floorFromExpr(assign.Rhs[0], aliases) + if entry == "" && !shares { + return + } + existing := floors[lhs.Name] + if existing == nil { + floors[lhs.Name] = &floorCall{entry: entry, sharesFloor: shares} + return + } + if entry != "" { + existing.entry = entry + } + existing.sharesFloor = existing.sharesFloor || shares +} + +// floorFromExpr reports which timing entry an expression derives from and +// whether it mentions the shared floor identifier. +func floorFromExpr(expr ast.Expr, aliases map[string]string) (entry string, shares bool) { + ast.Inspect(expr, func(n ast.Node) bool { + switch node := n.(type) { + case *ast.Ident: + if node.Name == sharedFloorIdent { + shares = true + } + if name, isAlias := aliases[node.Name]; isAlias && entry == "" { + entry = name + } + case *ast.SelectorExpr: + if name := timingEntryName(node); name != "" && entry == "" { + entry = name + } + } + return true + }) + return entry, shares +} + +// timingEntryName reports the entry name in `timing.Name`, walking past +// trailing selectors, indexes and calls so that +// `timing.Name.Measurements[leg].BlockPoint` answers `Name`. +func timingEntryName(expr ast.Expr) string { + for { + switch node := expr.(type) { + case *ast.IndexExpr: + expr = node.X + case *ast.CallExpr: + expr = node.Fun + case *ast.SelectorExpr: + if pkg, isIdent := node.X.(*ast.Ident); isIdent && pkg.Name == "timing" { + return node.Sel.Name + } + expr = node.X + default: + return "" + } + } +} + +// calleeName is the function name of a call, ignoring any receiver. +func calleeName(fun ast.Expr) string { + switch node := fun.(type) { + case *ast.Ident: + return node.Name + case *ast.SelectorExpr: + return node.Sel.Name + } + return "" +} diff --git a/internal/flow/upload_test.go b/internal/flow/upload_test.go index 3d1edc2..721f9f0 100644 --- a/internal/flow/upload_test.go +++ b/internal/flow/upload_test.go @@ -1049,22 +1049,39 @@ const ( pacedWindowsNum = 7 pacedWindowsDen = 2 - // pacedFloor is the least paced volume this fixture is ever built - // with, however small the window gets, and it is a floor on the - // MECHANISM rather than on the duration. The client does not begin + // unmeasuredLegFloor is the floor for a leg whose record has no + // measurement, and it is the ONLY shared floor left. It is a floor on + // the MECHANISM rather than on the duration: the client does not begin // waiting on buffer space until it has handed over a block point's - // worth of body; a paced phase shorter than that is a phase the + // worth of body, so a paced phase shorter than that is a phase the // client spent writing into a buffer, and a row that never blocked // measured nothing at all. // // Six MiB is roughly eight times the largest block point recorded in // internal/timing — 819,200 bytes on darwin, against 589,824 on // linux and 229,376 on windows — and it is deliberately not derived - // from that record. A floor exists to - // be right when the record is empty, which is the state of two of the - // three legs, and a floor computed from a leg's own measurement would - // be widest exactly where least is known. - pacedFloor = 6 << 20 + // from that record. A floor exists to be right when the record is + // EMPTY, and a floor computed from a leg's own measurement is widest + // exactly where least is known. + // + // THE CLAIM THAT USED TO FOLLOW — that an empty record "is the state + // of two of the three legs" — IS STRUCK, and it is struck because it + // stopped being true rather than because it was ever wrong. All three + // write-side legs now carry a block point for both entries, so every + // caller today derives its floor from its own record and NOTHING + // reaches this value. It stays for the leg that has nothing recorded, + // which is the case it was always for; it is no longer the case any + // caller is in. A sentence counting legs is a fact with an expiry + // date, and this one expired. + // + // IT USED TO BE THE FLOOR FOR EVERY CALLER, applied inside pacingFor's + // body where no row mentioned it. That made it a global claim four + // callers inherited without saying so — and a leg unable to meet it + // would have failed rows whose authors never made the claim. Now each + // caller passes its own and says why; this value is what a caller + // passes when its leg has nothing measured to reason from, and passing + // it is a statement about the RECORD rather than about the row. + unmeasuredLegFloor = 6 << 20 // drainTail is how much body is left after the pacing stops, to be // drained at full speed. It matters for the reason the paced phase @@ -1076,6 +1093,50 @@ const ( drainTail = 6 << 20 ) +// blockPointFloor is a caller's floor derived from ITS OWN entry's record +// on the leg this run is on: eight times the block point. +// +// THE MULTIPLE IS THE CLAIM AND IT IS ONE SENTENCE. The block point is the +// bytes the client hands over before it blocks at all, measured on this +// leg and recorded beside this window; a paced phase under it is a phase +// spent filling a buffer, and a row that never blocked measured nothing. +// Eight times is the margin the retired shared constant was +// reverse-engineered from, now applied to each leg's own number instead of +// approximated once for all three. +// +// IT IS A DERIVATION AND NOT A DEFAULT, which is the distinction the whole +// change turns on. It takes the caller's entry as an argument and holds no +// opinion about which entry that should be; two callers naming different +// entries get different floors, and two callers naming the same entry are +// making the same claim on purpose rather than by inheritance. +// +// IT REFUSES ON AN EMPTY RECORD rather than falling back. A leg with no +// block point has nothing for these rows to size a fixture from, and +// quietly substituting a shared minimum is what this change exists to +// stop: the substitution would be invisible at the call, and the row would +// assert a minimum nobody wrote. A caller that has actually reasoned about +// an empty record passes unmeasuredLegFloor itself, in the open, where a +// reader and the guard can both see it. +func blockPointFloor(t *testing.T, entry *timing.Entry) int64 { + t.Helper() + measurement := entry.Measurements[probeLeg()] + if !measurement.Measured() { + t.Fatalf("%s has no measurement on %s, so there is no block point to size this "+ + "row's fixture from.\nThat is a gap in the record rather than a reason to "+ + "reach for a shared minimum: %s exists for a caller that has reasoned about "+ + "an empty record and says so at the call. Run this entry's probe on this leg, "+ + "or pass a floor here and state why.", + entry.Name, probeLeg(), "unmeasuredLegFloor") + } + if measurement.BlockPoint <= 0 { + t.Fatalf("%s is measured on %s but records a block point of %d.\n"+ + "A measured write-side leg carries one by rule, so this is a record that "+ + "passed its own guard and cannot answer the question this floor asks.", + entry.Name, probeLeg(), measurement.BlockPoint) + } + return 8 * measurement.BlockPoint +} + // uploadPacing is one built fixture: the store's knobs, how much it // paces, and how large the body has to be. type uploadPacing struct { @@ -1086,7 +1147,22 @@ type uploadPacing struct { } // pacingFor derives the fixture from the stall window it has to spend -// three of. +// three of, and from the FLOOR ITS CALLER STATES. +// +// THE FLOOR IS A PARAMETER AND HAS NO DEFAULT, which is the whole point +// of it being one. A floor held inside this body was a claim every caller +// made silently: four rows asserted a minimum none of them had written +// down, and a leg that could not meet it would have failed rows whose +// authors never made that claim. There is deliberately no zero-value +// escape — a caller cannot inherit a floor by omitting the argument, +// because omitting it does not compile. +// +// WHAT A CALLER IS SAYING when it passes one: this is the least paced +// volume below which MY assertion stops meaning what it says. That is a +// different sentence for each row, and each one writes it at the call. +// A caller whose leg has nothing measured to reason from passes +// unmeasuredLegFloor and is thereby saying something about the record +// rather than about itself. // // IT REFUSES RATHER THAN TRUNCATES when the answer will not fit. A // window wide enough that the row proving it cannot be built inside this @@ -1095,12 +1171,18 @@ type uploadPacing struct { // windows, are set against each other by one kernel buffer — and the // answer to that is to say so, not to quietly build a smaller fixture // that passes by asserting less. -func pacingFor(t *testing.T, window time.Duration) uploadPacing { +func pacingFor(t *testing.T, window time.Duration, floor int64) uploadPacing { t.Helper() + if floor <= 0 { + t.Fatalf("pacingFor was given a floor of %d, and a floor is the caller's "+ + "statement of the least paced volume its assertion still means something "+ + "over.\nThere is no default here on purpose: a shared floor is a claim "+ + "every caller makes without writing it down.", floor) + } paced := int64(pacedChunk) * pacedWindowsNum * window.Nanoseconds() / (pacedWindowsDen * int64(pacedPause)) - if paced < pacedFloor { - paced = pacedFloor + if paced < floor { + paced = floor } body := paced + drainTail // The project carries a few hundred bytes of Astro scaffolding @@ -1207,8 +1289,11 @@ func bulkyProject(t *testing.T, size int64) string { // REQUIRED MUTATION: stop resetting the watchdog on progress. // // REQUIRED MUTATION, RUN 2026-09-10, for the fixture derivation: make -// pacingFor return its floor whatever the window is. Reds here and -// nowhere else — +// the fixture come out at its floor whatever the window is — which was +// then a matter of editing pacingFor's body, and is now a matter of +// passing an enormous floor at the call below, the floor having become +// this row's own argument rather than a constant inside that function. +// Reds here and nowhere else — // // the upload took 2.701646834s, which is under 3s — this row did not // spend long enough to prove a total deadline would have killed it @@ -1227,7 +1312,22 @@ func TestASlowUploadIsNotAStalledOne(t *testing.T) { // replaced by a number of somebody's own is the hole it exists to // close. stall := timing.UploadSlowIsNotStalled.Window - pacing := pacingFor(t, stall) + // THE FLOOR IS THIS ROW'S OWN CLAIM, and the claim is about the + // ASSERTION rather than about the mechanism: this row asserts the + // upload spends at least three windows, and a paced phase too short + // to keep the client blocking stops proving that a total deadline + // would have killed it. The recorded mutation above measures how + // little room there is — the assertion goes quiet by 300 ms. + // + // EIGHT TIMES THIS LEG'S OWN BLOCK POINT. The block point is the + // bytes the client hands over before it blocks at all, measured on + // this leg and recorded beside this window; a paced phase under it is + // a phase spent filling a buffer. Eight times is the margin the + // retired shared constant was reverse-engineered from, said here + // against this leg's number instead of approximated once for all + // three. + floor := blockPointFloor(t, &timing.UploadSlowIsNotStalled) + pacing := pacingFor(t, stall, floor) run, client, fixture := pinnedUploadRun(t, bulkyProject(t, pacing.bodySize), pinnedBuffer) run.scriptedLogin() @@ -1286,7 +1386,23 @@ func TestAWedgedUploadStopsAndSaysSo(t *testing.T) { // Written out for the reason its sibling's is, one row up. stall := timing.UploadWedgedStops.Window - run, client, fixture := pinnedUploadRun(t, bulkyProject(t, pacingFor(t, stall).bodySize), pinnedBuffer) + // THIS ROW'S FLOOR IS ABOUT BEING LARGE ENOUGH TO BLOCK, and nothing + // else: it takes only the body size, and what it needs of that body + // is that the client is still writing when the store stops reading. + // It asserts nothing about how long the upload spends, so the + // duration reasoning its sibling states does not apply here — which + // is why the two floors are written separately even where they come + // out equal. Two rows agreeing on a number is not two rows making one + // claim. + // + // Eight times THIS entry's own recorded block point, for the reason + // its sibling gives: under the block point the client never blocks, + // and this row's whole fixture is "still writing when the far end + // stops reading". + floor := blockPointFloor(t, &timing.UploadWedgedStops) + run, client, fixture := pinnedUploadRun(t, + bulkyProject(t, pacingFor(t, stall, floor).bodySize), + pinnedBuffer) run.scriptedLogin() run.prompt.confirms = []answer{no()} run.deps.UploadStallTimeout = stall From 509fdd491bc4de6a7aca901f0bb478c5f7f1a134 Mon Sep 17 00:00:00 2001 From: E Ismail Date: Sat, 19 Sep 2026 00:14:04 +0100 Subject: [PATCH 2/2] docs(readme): "What this is" is conditional too, for the reason the rest is MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The publication flip put the install copy in the present tense and left the deploy copy in the future, because the control plane is not deployed and api.curious.pub answers NXDOMAIN. This paragraph was missed: three lines above a Try-it section written in the conditional, it said curious "packs an Astro project, sends it to curious.pub, and hands you back a public address" — flat present tense, describing the finished product to the reader most likely to act on it, since somebody who comes straight to "What this is" comes here to find out what this is. It now reads "once the platform is up", and says why in its own two sentences rather than relying on the Status section above having been read. A page that is true above the fold and false one heading down has still told its reader something untrue; that the two sentences contradict each other only makes it harder to notice, not less wrong. Nothing else on the page changes. What is claimed is unchanged in substance: the tool is released and installs today, and there is nothing at the other end of it yet. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01XfBYBGuUkF7zUnZfAFD3dW --- README.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 11f8379..b8d4dfa 100644 --- a/README.md +++ b/README.md @@ -62,11 +62,19 @@ launch note: [hello -a- curious.pub] ## What this is -`curious` packs an Astro project, sends it to curious.pub, and hands you -back a public address in about the time a build takes — no dashboard, no -project setup beyond an email address. What comes back is a **temporary -preview**: every site curious.pub builds for you expires after a period -of inactivity, which is what makes trying it free of any commitment. +**Once the platform is up**, `curious` will pack an Astro project, send +it to curious.pub, and hand you back a public address in about the time a +build takes — no dashboard, no project setup beyond an email address. +What comes back will be a **temporary preview**: every site curious.pub +builds for you expires after a period of inactivity, which is what makes +trying it free of any commitment. + +This paragraph is conditional for the same reason "Try it" below is: the +tool is released and installs today, and there is nothing at the other +end of it yet. Describing the finished product in the present tense here +would undo, three lines later, what the Status section above says — and +the reader most likely to act on it is the one who came straight to this +heading to find out what this is. ## Try it