docs: stop counting benchmark classes in the present tense
PR #26 added AreaPassStageBenchmark, so the suite went from sixteen classes to
seventeen and from nine single-fork classes to ten. Four sentences here said
sixteen, three of them about the suite as it is rather than as it was at a
named commit. Those three drop the count: what they actually assert is that
the property holds for every class, which stays true as classes are added.
The fourth keeps its number because it names the commit it was read at —
488 configurations counted at ca79507 — and is the only one of the four that
could not go stale.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QzEdy5fN5JKGxJo8gwtNeu
0c4c83d
docs: three entries leave the open list, and the fourth loses its ranking
The exception hierarchy (#21), the stale-read item (#23) and the missing ring
diagonals (#24) are done. What they have in common is in the section header
now, because it is worth more than the three results: none was closed by
building what the entry proposed. One needed a decision, one needed a sentence
in the javadoc, and only the third was a defect.
The opacity tables stay, reworded. The entry called them "the largest
remaining cost block by a wide margin", which was written before 69381af took
the per-section table from 31.33 to 8.07 us and left propagate dominant at
31.41 - a change the smaller-items entry records while this one was not pulled
along. Measured over a whole pass with its ring, the tables are between a
sixth and a fifth. The mechanism the entry proposes survives that; the ranking
does not, and the entry now says what the cache has to earn against the risk
that a wrongly invalidated table produces light nothing recomputes.
The figures are from three forks. A single-fork run of the same benchmark
suggested a share that falls as the area grows, and that was an artefact: the
three-fork numbers are not monotone and the whole-pass column moved by up to
25 % between runs. Both the range and that correction are in the page, because
a reader who saw the first number should learn why it changed.
Numbering: the two removed entries were 1 and 2, so the rest moved up. The
cross-reference in smaller items that pointed at the diagonals is gone with
them - that gap is closed - and the one pointing at the tables now says item 1.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
fdd8518
docs: count the two-fork re-run as the fifth repeat
The run published this morning is itself a cross-run repeat of this table, and
the register two hundred lines above it still said "No repeat run of this
table exists" and counted four. Both sentences were made false by the commit
that added the run — the same failure this wiki has now recorded three times:
a change that invalidates a sentence somewhere else, where no tool looks.
There are five. The new one repeats one cell rather than the whole table:
109.88 ± 1.47 against the row's 109.2 ± 1.6, intervals that overlap, so the
row reproduces. The single-fork run beside it is the same control at weaker
settings and is not counted separately — what it establishes is that it should
not have been trusted alone.
The subset that teaches "ratios reproduce" is still two; only the total moved.
Eleven sentences across four pages carried the old total and now carry the new
one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QzEdy5fN5JKGxJo8gwtNeu
0e8d8e6
docs: a two-fork run overturns yesterday's single-fork one
The single-fork control run published here earlier today appeared to resolve
the MIXED pair at 64 sources and 0 % solid, at 1.15× faster on disjoint
intervals, and was used to argue that the lead does not fall as brightness
mixes. Repeated at two forks with ten measurement iterations, it does not
resolve at all: Falco 155.73 ± 8.44 against Minestom 161.77 ± 1.60, intervals
that overlap, conservative bounds 0.98× to 1.11× — a range that includes Falco
being the slower of the two. UNIFORM holds at 1.13× faster, bounds 1.09×–1.17×.
The two-fork run agrees with the published row, which also finds this pair
unresolvable, and it is the one whose ± covers more than one JVM launch. No
factor may be quoted for this cell. The direction the withdrawn sentence
claimed — a lead that falls away as brightness mixes — survives after all; the
1.30× and the 1.06× still do not.
Falco's own rise measures 41.7 % at two forks with bounds of 32.3 % to 51.4 %,
so "about a third" sits at the bottom of that range rather than at its centre.
Yesterday's 32.8 % was the single-fork estimate and is superseded.
This is the page's own thesis happening to the page: at one fork the interval
describes dispersion inside a single JVM and is narrower than the true
uncertainty, so a pair can look ordered when it is not. Both runs are kept,
with their settings, because the pair of them is the demonstration.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QzEdy5fN5JKGxJo8gwtNeu
640a4f8
docs: stop claiming every table, and let the research index list all six
Three defects that had been carried as known and open.
Measured Results said it owns every measured table in the wiki, on four pages.
Anvil Chunk Loader refutes that on its own page: it publishes an independent
second run of the loader table and the two-fork four-thread control beside it,
the only published run whose ± covers more than one JVM launch. The claim that
was actually needed is narrower and is now what stands — where a table appears
twice, the copy in Measured Results is the one that is right.
Research listed five documents and omitted Research: Fluent API, which is an
investigation that produced code (#16) rather than a proposal. A group index
that omits one of its own pages misstates its contents, which is the part of
the folding rule that survives now that collapsed sidebar blocks make height a
non-issue. The heading loses its count rather than gaining one, so it cannot
go stale again the way the pull request numbering in CONTRIBUTING.md did.
The #### exception is written down instead of being re-decided every round. It
covers a document that records a completed investigation and no other kind of
page, and it was checked before being granted: no page links a #### anchor on
either of the two, and neither Contents block lists below ##.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QzEdy5fN5JKGxJo8gwtNeu
c6f6da7
docs: give every wiki page a direct sidebar link, collapsed
The test in the previous commit answered the question the first navigation
design left open: GitHub does render <details> inside _Sidebar.md, as a real
element rather than escaped text. The folding rule was written because a
sidebar had to fit one screen and thirty pages do not; that constraint is now
a choice.
Rationale, Research and Build Setup each carry their subpages in a collapsed
block. Collapsed height is unchanged, and every page in the wiki is one click
away instead of one hop through a landing page.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QzEdy5fN5JKGxJo8gwtNeu
8863788
test: does GitHub render <details> inside _Sidebar.md
Open since the first navigation design and answerable only against the live
wiki: it renders in the page body, but the sidebar carries none and none of
24 inspected project wikis uses one. Reverted immediately if it does not.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QzEdy5fN5JKGxJo8gwtNeu
c68d59e
docs: measure the row the tables could not resolve, and fix the repeat count
Two things a reader could quote against this wiki, and one measurement.
The count of cross-run repeats disagreed with itself. Measured Results is the
register and says four; several sentences said two, including one on that same
page twelve lines from where it counts four correctly, and one that called two
of them "the whole of the project's direct answer to the single-fork
objection" — excluding the two-fork control, the only published run whose ±
covers more than one JVM launch, which is the most direct answer there is.
Three further sentences said three of the four teach that ratios reproduce;
two do, because both loader repeats establish an asymmetry rather than a
ratio, which the register already stated.
The 112.7 µs anchor has been marked TODO on four pages because it appears in
no table. A control run at ed83cad settles part of it. Falco's cost rises
32.8 % from UNIFORM to MIXED on disjoint intervals — the "about a third" that
depended on 112.7 reproduces without it. The lead does not fall from 1.30× to
1.06× as the withdrawn sentence had it: it measures 1.16× and 1.15×, and where
the published MIXED row cannot order the two at all, this one can. Where 112.7
came from is still unknown; this run measures that cell at 107.59 and the
published table says 109.2.
The control run is published beside the table, never inside it, and no digit
above it changed. It is one fork on a machine recorded as not idle, its lower
bound reaches 1.03×, and the page says so where the number is rather than only
in the provenance line.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QzEdy5fN5JKGxJo8gwtNeu
33d11f8
docs: the exception hierarchy is no longer open
It stood at the top of the list, and what it was waiting on was a decision
rather than work: whether the checked root extends IOException. #21 made that
call - it does not - and built the hierarchy, so the entry goes and the five
below it move up one.
The reasoning is kept in the section header rather than dropped, because the
list is ordered by consequence and a reader who knew the old item 1 should
find out where it went. Research: Exception Hierarchy holds the detail,
including the three places where the implementation departed from the design.
The two cross-references inside item 5 move with the numbering: what used to
be item 3 and item 4 are now 2 and 3.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
6013363
docs: split the working record into status, measurements and contributing
Project Status had grown to 1 783 lines and eighteen sections, from Environment
and Conventions through Measured to Defects and Open. A table of contents above
a page that holds three unrelated things does not make it one thing.
Measured Results now holds every measured table and all eleven provenance
lines. Contributing holds Environment, Working on this, Conventions and
Releasing and snapshots, and is what the repository's new CONTRIBUTING.md
points at. Project Status keeps what its name says: facts, decisions, what is
in the branch, defects, what is open.
The text moved word for word. Heading levels are unchanged, so every
subsection anchor still resolves — only the page in front of it differs. The
old file was checked paragraph by paragraph against the three new ones: 257 of
274 identical, the other 17 differing only in a redirected link or a rewrapped
line. ± appears 94 times before and 94 in the moved text, × 106 times in both.
No figure changed.
The split also broke eighteen sentences that no link checker can catch. They
carry no anchor — "the full tables are in Project Status", "the working
record: benchmark results with their conditions" — so they resolve perfectly
and say something that stopped being true. The worst of them was in
_Footer.md, which renders under all thirty pages. Every one of the twenty-eight
references to Project Status has since been read in context and either
redirected or confirmed.
The Gradle group folds to Build Setup, which already listed all six pages
behind it. Five more long pages gained a table of contents. Home no longer
opens with a greeting.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QzEdy5fN5JKGxJo8gwtNeu
fb7ca54
docs: record what the exception hierarchy became
The page read as a design with an open decision, and #21 made that decision
and built it. It stays the record of the investigation rather than becoming
documentation of the result, with the three places marked where the code
departed from it.
The decision went against extending IOException, on a detail the page already
named without weighting it: one of the multi-catches is the swallowing block
in saveChunk. Under an IOException root the new types would keep being
swallowed there, in the path where a silent failure costs a whole chunk.
Three corrections. The .exception package cannot exist - without a module
system a sealed type may only permit subtypes of its own package, and moving
AnvilChunkException would be a binary break for a package name. The six types
are as designed but carry a Reason enum each, and one chunk-data reason is
absent from the catalogue here because NbtReads throws through a single
missing() helper rather than at its six call sites. And the multi-catches are
three rather than two; the other counts were exact.
The page could not know about falco-archunit, which arrived a fortnight after
it and whose rule required every throwable to be unchecked - forbidding this
design outright. That rule now covers the unchecked types only, and three new
rules keep the exemption from being a hole. Two of them enforce what this page
could state only as prose, including rule 1 of the implementation rules.
Project-Status still lists this as open item 1; left alone deliberately, since
that page is currently being reworked.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
c96b341
docs: write down what checkApiCompatibility does and why it looks odd
#20 added a binary compatibility gate and left its reasoning nowhere, since
build files here carry no comments. Two details of that configuration look
like something to tidy up and must not be, so they are written down rather
than left to be rediscovered.
The baseline resolves through a detached configuration because Gradle
substitutes an external dependency with a project of the same group and name
from the same build, regardless of version - a named configuration brings the
substitution back and the check then compares the local jar against itself.
And the new side has to be the archive of the jar task rather than the task,
which fails the same silent way.
Both were found by removing a public method on purpose and watching the check
stay green, which is also why the doFirst guard exists: a compatibility gate
that cannot fail reads as coverage while providing none.
apiBaselineVersion is the one line a release can leave stale - Release Please
rewrites version through its marker and knows nothing about this property.
The per-module check table gains the task; it listed only jacoco for the three
published modules.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
b0c2468
docs: mark what the fluent API research produced, and where it was wrong
The page was written before any of it was built. #16 implements steps 3 to 6
of its sequence and departs from it in three places, so the page now says so
at each of them rather than reading as a plan that is still pending.
The three departures, each in a quote box where it happens:
Question 13 called the missing copy override a defect. It is not one - the
copy keeps its light, because the sections are cloned with it, and losing the
scheduler binding is the only correct outcome, since a copy goes into another
instance and a bound one would throw on the first block change.
Section 3.1 called for a mutable anvil builder, with reuse across dimensions
as the argument. That argument does not hold, and following it would have
left three builders with two semantics: the same line taking effect on one
and silently doing nothing on the other.
Step 6 of the sequence wanted a third ServerStack entry. It did not get one,
because the comparison holds only while the two servers differ in the loader
and the chunk type and in nothing else.
Section 7.1 predicted that a mutable light builder breaks
sharedStateIsSafelyPublished. That was verified rather than assumed: one
field from final to mutable turns the rule red with the predicted message.
The blocker in 1.2(f) is marked as cleared, and the lead no longer claims the
page describes nothing that exists - it now says to read it as a record and
that the code wins where the two disagree.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
01837dd
docs: give the wiki navigation that survives a deep link
Home.md was the only page reaching the other 25, and had no inbound link
itself. Between the content cluster and the seven Gradle pages there was
exactly one bridge outside it, so a reader arriving by search never reached
the other half. Four long pages also ran hundreds of lines past their last
internal link — Anvil Chunk Loader carries its last one 247 lines before the
end, including the section the README sends the reader to.
_Sidebar.md and _Footer.md are new and render on every page. The sidebar
groups all 26 pages into four; a group folds to its landing page only where
that page lists every subpage, which is why Research: Fluent API stands
beside Research and the Gradle cluster stands open. Group labels are bold
text rather than headings, so the one-title-per-page rule is avoided rather
than broken.
Home keeps the full index — the sidebar is not rendered on _pages or
_history, and narrow viewports push it below the body. It gains an H1, a
"The measured record" rubric that finally gives "These two pages are the
measured record" the two entries it refers to, deep links written as
statements rather than directions, and a gloss per rationale page so a
reader looking for one decision no longer has to guess.
Five long pages gain a "## Contents" block in the form Project Status
already uses. Two links to a "What the ± is" anchor that never existed now
resolve to "The interval after a number" — the one definition the
documentation standard calls authoritative.
No page renamed, split or deleted; no sentence, link or figure removed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QzEdy5fN5JKGxJo8gwtNeu
6844b4c
docs: check the fluent API sketches against falco-archunit
The page was written before cb30cf0 added the module, so every builder in
it was a proposal against rules nobody had read. Section 7 closes that:
all five proposed types against the 39 rules as they stand at 4c86c96.
One sketch fails. ChunkLightScheduler.Builder needs an Executor field for
its executor(Executor) slot, and SHARED_OBJECT selects any class holding a
field whose raw type sits in java.util.concurrent. The condition then wants
every non-static field final, volatile, or written only from a constructor
or a synchronized method - which a mutable builder is not. False positive
in intent, true positive in mechanism, and the mechanism runs in CI. The
recommendation is an immutable builder, or a record: it passes without
touching a rule that was red against a real defect and caught it.
Two rules confirm decisions the page had already reached. The module
isolation rules forbid any dependency between the three modules, and the
javadoc of isolated(...) cites the same ServerStack passage section 4.2
argued from - which is why variant (D) works and (A) and (B) could not:
the cast lives in user code, so neither module names a type of the other.
And lightCoreKnowsNoMinestom backs putting the Overrides helper in
MinestomBlockLightSource rather than in the registry-free interface.
The rest costs annotations: @ApiStatus.Experimental on all five, since
nested types are in scope, and final on the two builder classes and
Overrides. Section 7.4 records what this does not establish - the rules
were read, not compiled against, and two of them state limitations of
their own.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
0f57b23
docs: add the fluent API research and link it from Home
Asks whether falco-anvil, falco-light and falco-instance should get a
fluent construction surface, and in what shape. The page describes no
existing API: every builder, slot and terminal method in it is a proposal,
and the lead says so before anything else, because a reader arriving from
Home would otherwise take the code examples for something callable.
The finding that outweighs the API question is the blocker in section
1.2(f): FalcoInstance accepts FalcoChunk only while FalcoLightingChunk
extends DynamicChunk, so the two modules cannot be combined today. Both
demo stacks run on InstanceContainer for that reason. A facade selling
"the whole Falco stack" cannot offer the one combination that would be
its argument, so the blocker has to be cleared before any API work.
What the page recommends: nested builders in all three modules, adding
five types and no top-level ones; no fourth falco-api module, because
the claim that one follows from the module structure does not hold; the
facade as a wiki recipe over existing types; and no observer mechanism
of Falco's own where Minestom's EventNode carries.
The evidence box carries the two caveats a reader has to know. The
Minestom line numbers mix 26.1.2 and 26.2 - types and signatures are
identical in both, line numbers are not. And the page is evidenced
against 26ac23e: e45dc1e has since fixed the data race it reports in
1.2(c), and cb30cf0 added falco-archunit, whose PublicApiTest binds
every builder sketched here against rules the page never checked.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
66f2788
docs: add the architecture rules page and count seven modules
falco-archunit landed in the repository and the wiki still described six
modules, with two build tables that did not know the seventh. The stale
counts are corrected in Build Setup, Project Status, Publishing, Dependency
Management and Benchmarks and Demo, and the two tables in Testing and
Javadoc now say what check and javadoc do for a module whose only source
set is test.
The new page covers what the 39 rules enforce, why the module sees only
main sources — which is what lets it catch a public method carrying a
package-private type, a mistake no test inside the modules can see — and
which invariants it deliberately cannot check: synchronized blocks, the
ordering of the seqlock protocol, and the claim that no CPU-bound work
happens while a lock is held.
637a54f
docs: note that the wiki's versions are hand-maintained, and pin Javadoc to latest
Renovate's custom manager matches README.md only, so the coordinates on
the Installation page cannot be kept current automatically. Say so at
the top of the module snippet and point at the README, which Renovate
does update, as the authority.
The Javadoc table pins `latest` instead of 0.3.0 for the same reason:
the endpoint resolves it to the newest published version, so the table
cannot go stale here.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
da07f88
docs: add an Installation page and link it from Home
Collects what a consumer needs to add Falco to a build: the three
modules, the BOM, the snapshot endpoint, Maven, the rendered Javadoc
and its address scheme, and building from source with the credentials
that needs. All of it was in the repository README, which is the wrong
place for it - the README should get someone to a running server, not
document every coordinate.
Cross-references the existing build pages rather than repeating them:
Dependency Management for why Minestom is compileOnly, Build Setup and
Publishing for what falco-bom is, Versioning and Releases for how the
snapshot version is derived.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
dd76eb1
docs: state every measured claim with its conditions and its limits
Reworks all 21 wiki pages so that no performance claim can be read as
saying more than the measurement supports.
The measurement model is now stated once and authoritatively: JMH's
score error is the half-width of a 99.9 % confidence interval over the
measurement iterations of a single fork, which bounds dispersion within
one JVM and says nothing about run-to-run variance. Every published
comparison was re-graded against a mechanical significance rule and is
labelled supported, indicative-only, or not usable. Ratios whose
intervals overlap no longer carry a factor.
The 8.00x loader figure is withdrawn. The two-thread 1.9x now carries
the independent repeat that did not reproduce it next to the number
rather than two pages away. What those repeats do establish - Falco's
read time repeats at every thread count and Minestom's does not repeat
above one - is stated as the asymmetry it is, not as a factor.
Each page separates what was measured from what is reasoned from the
code and what is judgement, cites the type or method behind every
structural claim, and carries threats-to-validity and reproduction
sections precise enough for a third party to attempt replication.
Environment facts that were never recorded are marked as gaps rather
than filled in.
No measured number was changed.
4e3e1be
Link Instance-Performance-Research from Home
That page landed concurrently with the documentation migration and was
not yet linked from anywhere.
7301b64
Migrate the long-form repository documentation to the wiki
Adds Anvil-Chunk-Loader, Light-Engine, Benchmarking (methodology and
headline results), Project-Status, the five Rationale-* pages and the
four Research-* pages, moved verbatim from the Falco repository's
docs/, STATUS.md and README benchmark section. Internal links were
rewritten to wiki page names; links to source files that stayed in the
repository were rewritten to GitHub blob URLs; chart images stayed in
docs/charts/ in the repository and are embedded here via raw GitHub
URLs. Home.md gains Getting started / Background: rationale /
Background: research groups above the existing Gradle build group.
8b8cbfa
Add the instance performance research findings
d0a3fd6
Document the Gradle build setup
a5d10a2