Repository navigation
Stability candidate and 1.0 readiness criteria #335
Description
Activity
- addeddocumentationImprovements or additions to documentationImprovements or additions to documentation
on Sep 9, 2026 - pinned this issue
on Sep 10, 2026 The candidate is published. termlens 0.11.0 and termlens-cli 0.11.0 went to crates.io on 2026-09-10T21:35Z from tag
v0.11.0=b8af0fa, through Trusted Publishing (release run 34532570645: tag check, full CI, semver gate, publish, GitHub Release, and the registry-consumer check — library in both feature shapes and the installed CLI — all green on Linux and macOS). The stress workflow ran on that exact commit first: 100 iterations per OS across five--test-threadsshards, Linux, macOS and Windows, all green (34530320216).What 0.11 shipped, against the list above. Correctness: #320 (in 0.10.2). The contract: #328, #329. Enforcement that can fail: #323 (with its self-test, and seen to fail on a real removal), #324, #325, #326, #327 (a 0.10.1 corpus written by the published 0.10.1, and a 0.11.0 one frozen from the release tree). The one breaking change: #330, landed alone under the
breakinglabel with the diagnostics pasted and the migration table in the CHANGELOG. Additive API: #331, #332, #306, #308, #315. Documentation and process: #333, #334. Plus #340, found while writing the CLI contract:inspect's stdout is now a saved screen. The docs carry the criteria above indocs/STABILITY.md, and the README, CHANGELOG header and STABILITY state the candidate in the same words, checked by CI.What the freeze now means in practice. Every pull request is compared against the published 0.11.0 (once #350 moves the baseline) with the release type forced to
patchin three feature views; the gate has been seen to fail on a removed item and on a gated one. One known blind spot, recorded in STABILITY.md: a method re-typed under the same name is not a lint cargo-semver-checks 0.50.0 has — it reported only the removedunsupported_overflow()beside #330's return-type change.For the criteria. 1 (contract published) and 2 (enforcement proven to fail; green on every PR since — from now) hold as of this release. 3 (consumers migrated) starts now: six maintained repositories move to
termlens = "0.11"from crates.io, never a path. 4–7 begin when an external pilot's first green run is recorded here; nothing here sets a date.Criterion 3 — consumers migrated — is met. All six maintained repositories now depend on
termlens = "0.11"from crates.io (never a path or[patch.crates-io]), each merged with its own CI green:Repository PR Notes reconverge #139 two manifests, moved together mossaic #106 launchbound #69 oxmera #43 oxidelake #20 two PTY suites termlens-demo #19 plus a new survey_0_11.rsThe observation window for criterion 6 does not start here — it starts at an external pilot's first green run, and there is no pilot yet.
What the migration measured, which is the point of doing it rather than asserting the table was right.
The
unsupported()break was mechanical everywhere, and in every repository it made the suite stricter rather than merely different: the pinned list and "the record is not truncated" collapse into one assertion, because the view is equal to a slice only when the retained shapes match and nothing overflowed. Five repositories deleted aVec<String>helper that existed only to make the old comparison typecheck.Two things were found by a test failing, both in termlens-demo, which is what that tier is for. Its
unsupported()probe pinned #320 as a defect and said in the test body that it should invert once fixed — against 0.11.0 it does, so the fix is now confirmed from outside against a real ratatui application. And its CLI test assertedinspect's trailer was in stdout, which #340 moved to stderr; it now asserts the split and the round trip.One gap in my own verification, worth recording. Five repositories keep their
termlens-clitests#[ignore]d because they install from crates.io, so a localcargo test— and reconverge'sjust ci, which says so explicitly — skips them. All five asserted the trailer from stdout and all five went red on CI after a locally green run. The#[ignore]is right (a local gate should not reach the network), but it means "green locally" is not evidence about the CLI contract in these repositories, and the next termlens CLI change will meet the same shape.A follow-up available but not taken:
cursor().2still appears at ten call sites across five repositories wherecursor_visible()would read better. It compiles identically, so mixing that sweep into a dependency bump would only have made the diffs harder to review.Criteria checked against
main, 2026-09-16A status pass over the seven criteria, since this issue is where the
evidence is supposed to live. Nothing here changes the criteria — the
wording above is unchanged and the issue stays open, which is what it says
it should do until criterion 4 is met.# criterion state evidence 1 Contract published met docs/STABILITY.md§§1–3 each carry a decision and the measurement behind it (Windows #149, backend #150, styled history #146); "What the promise covers" splits Promised / Third-party boundaries / Not promised2 Enforcement proven met tools/semver-gate-selftest/run.shpasses today, 7/7, asserting both holes as holes — including "forced minor still fails on 0.x", which is why the gate usesmajor. It runs in ci.yml'ssemverjob, andci.ymlonmainis green on every run since the candidate3 Consumers migrated met All six on termlens = "0.11"from crates.io, no path or patch override anywhere: reconverge (×2 manifests), mossaic, launchbound, oxmera, oxidelake, termlens-demo4 An external pilot NOT met — the blocker No repository outside the maintainer's own has tests on a 1.0.0-rc.N. Nothing else is waiting on anything5 No known correctness blocker met No open issue in the promised scope. The twelve issues open when this pass started were eleven enhancements/docs and this tracker 6 Eight weeks of stable pilot not started Counts from criterion 4's first green run, which has not happened. Not a calendar item and not startable yet 7 Fresh-install evidence met so far install.ymlgreen every day 2026-09-11 → 2026-09-16. The one failure in the window, 2026-09-10, predates the candidate's publication later that daySo: six of seven hold, and the seventh has not been started. Criterion 6
cannot begin until criterion 4 does, so the distance to 1.0 is measured
entirely by finding a pilot — at least eight weeks after that, and no
sooner. Worth saying plainly because five green boxes can read like
progress toward a date, and criterion 6 explicitly is not one.The honest reading of criterion 4 is that it is the one criterion this
repository cannot satisfy by working harder on itself. It may be worth its
own issue: who the candidate pilots are, what "one real user flow" means for
them, and what termlens offers in return for the trouble.- unpinned this issue
on Sep 16, 2026 Closing this as the discussion it was opened for, which has concluded:
the criteria were argued, finalised and pinned, and the status pass above
records each one againstmain.Closed does not mean met. Reading it that way would be wrong, so for
anyone who arrives here from the README,CHANGELOG.md,docs/STABILITY.md
ordocs/RELEASING.md:- Criterion 4 — an external pilot — has not started. No repository
outside the maintainer's own has tests on a1.0.0-rc.N. It is the one
criterion this project cannot satisfy by working harder on itself. - Criterion 6 — eight weeks of stable pilot usage — cannot begin until
criterion 4 does. It counts from the pilot's first green run, not from
a calendar date and not from the candidate's publication. - The other five held as of 2026-09-16, with the evidence in the comment
above.
So termlens is not 1.0-ready, and the distance to 1.0 is still measured
entirely by finding a pilot plus at least eight weeks after that.The criteria themselves are unchanged and remain readable here. 0.11.0 stays
the current release and the freeze it declares is unaffected: from 0.11.0 no
promised item changes incompatibly before 1.0, and a change that must break
one ships as a new candidate.docs/RELEASING.mdstill names this issue as the gate for av1.0.0tag —
"every criterion in #335 to be recorded as met, with its evidence". That
remains the rule; this issue is where the evidence is, closed or not.- Criterion 4 — an external pilot — has not started. No repository
The seven criteria in this issue are now a section of
docs/STABILITY.md: The 1.0 readiness criteria (#472, landed in #492). They are copied word for word, except that "this issue" now reads "this section". The candidate statement in the README, the CHANGELOG and STABILITY.md, anddocs/RELEASING.md'sv1.0.0gate now link that section instead of this closed issue. That section is the live record, and a criterion is recorded as met there. Nothing about the criteria themselves changed: criterion 4, the external pilot, has still not started.- added a commit that references this issue
on Sep 23, 2026
0.11 is the stability candidate. It is the release after which no promised public item of termlens changes incompatibly before 1.0. This issue holds the criteria 1.0 must meet, in one place, so they can be argued about here and then pinned. Proposed wording — finalise it in this issue, then pin.
What 0.11 ships
unsupported()names sequences the attribute shadow implements) — can ship as a 0.10.x patch before the candidate.Screen::unsupported()returns a view instead of&[Arc<str>].cursor_visible(), ScreenWithStyles is returned by Screen::with_styles but cannot be named outside the crate #332ScreenWithStylesre-export, Location has no accessors, so asking "screen or history?" needs a match #306, ScreenDiff computes which rows and style runs changed, then exposes neither #308, Color has no Display, so its snapshot token is hand-built at the one place that writes it #315.Everything else in the tracker is welcome and unaffected by the freeze: additive flags, fixture hygiene, docs polish.
What "frozen" means
From 0.11.0, the items
docs/STABILITY.mdnames as promised do not change incompatibly. A change that must break one ships as a new candidate (0.12.0) with a migration table, and restarts the observation window below. A patch release does not restart it. The_forwait methods,wait_idle,Recording,frame_timingsand the renderers stay as they are.1.0 readiness criteria
1.0 is tagged when all of the following hold, and not before. No calendar date is a criterion.
1.0.0-rc.N) covering one real user flow, has caught at least one regression with them, and has run them in its own CI repeatedly. Internal green runs do not count.install.yml(library and CLI) green throughout the window.If a criterion cannot be met, this issue records why, and 0.11 stays the current release. A candidate that is never promoted is a smaller failure than a 1.0 that is broken by 1.1.