Since 5.0 this engine has corrected four defects. Not one was caught by a suite going red on the commit that introduced it. Three were found by a check with a real capacity to come back negative, two of them built for an entirely different purpose. The fourth is what this post opens with, because nothing in the suite could have found it, and the reason why is the point.
That distinction is the whole subject of this post. A test suite is not evidence of correctness; it is evidence about the specific propositions it can refute. A green run tells you nothing about a proposition none of its assertions touches. Each of the four sections below ends on the rule the episode taught, because the rules transfer and the fixes do not.
1. v5: the ascendant, not the ephemeris
An ephemeris runs on two clocks. Where a planet is, is a function of dynamical time. How the Earth is turned underneath it, is a function of UT1, which tracks the actual rotation. The gap between the two is about 69 seconds today.
Sidereal time measures rotation, so the right ascension of the midheaven is defined on UT1. The engine converted to Terrestrial Time first. That does not merely ignore the gap: it applies the rotation in the wrong direction, adding what should have been removed. The RAMC error was uniform, roughly 0.29 degrees. The resulting ascendant error was not uniform, because it varies with latitude, and measured between 5.18 and 30.23 arcminutes across three test charts. A second defect rotated planets by the ayanamsha while leaving the house cusps tropical, then placed the rotated planets against the unrotated cusps: 77.4% of placements, 669 of 864 measured, fell in the wrong bhava. A third returned the Universal Time weekday as the vara, which runs from local sunrise and therefore depends on where the observer stands.
Here is the part worth sitting with. At the time, the engine already agreed with JPL Horizons DE441 to 0.106 arcseconds mean across the 15,350 committed reference positions inside the era where the Earth's clock error is measured rather than predicted, and that suite was green. It stayed green through v5, byte for byte, because no planetary longitude was wrong. The oracle compares body positions. Every one of these three defects lived in the orientation of the Earth, the frame the cusps were expressed in, or the definition of a day. The best check in the codebase could not have failed on any of them.
Precision and correctness are different properties, and a precision number is routinely offered as evidence for both. A sub-arcsecond engine can put an ascendant in the wrong sign. It will do so to five decimal places.
Rule 1
Precision is not correctness. Digits describe how finely you answered; they say nothing about whether you answered the question that was asked.
2. v6.0.0: forty-four ayanamshas become eleven
Vedaksha 5 shipped forty-four ayanamshas. For most of them there was no derivation in the record: no path from a primary source to the number sitting in the constant. A citation was often attached. A citation is not a derivation.
Auditing them in place was the obvious move and it is the wrong one, because an audit performed with the existing value in view cannot tell you whether the value came from the source or the source was found for the value. So they were deleted, and computed again, forward from primaries, by an implementation that never saw what it was replacing. Eleven survived. Each of the eleven traces to a chapter, a star, a committee, or a named proposer's own publication.
Of the systems that did not survive, most are unverified rather than refuted: their definitions exist only in works that had to be obtained and read, and the search is recorded in the audit directory whether or not it succeeded. A handful were dropped on principle. Where the historical zero point of a system is something a scholar estimated, two secondary accounts of the same figure can differ by minutes of arc. A definition does not have competing values. A measurement does.
Every retired name now hard-errors, on parse and on serde deserialization, carrying its own disposition in the message. No silent remap to a near neighbour, because a silent remap moves a caller's chart without telling them.
The same work turned up a defect with nothing to do with ayanamshas. precession_matrix composed its four Fukushima-Williams rotations in the wrong order. At J2000 that is 0.014 milliarcseconds, which is nothing. At 499 CE it is 0.56 arcseconds, and it grows without bound as you move away. Every accuracy check the engine had sampled 1900 to 2100, where the error is invisible. It surfaced only because deriving an epoch-anchored sidereal system means evaluating the transform a long way from its anchor.
Sitting at one epoch, a rotation composed in the wrong order and a rotation with a slightly wrong constant produce the same residual. They are the same shape until you move.
What the resulting tests do not establish is stated in the engine rather than left for a reader to discover. Anchor reproduction is self-consistency, and for the epoch-anchored systems it is algebraically vacuous. The independent Python re-derivation establishes that no constant entered by being typed into one side, not that the two implementations are independent: both read the same recorded primary inputs. Derivation integrity rests on the audit trail, not on the suite.
Rule 2
Direction of derivation is what makes something clean-room, not the citations attached afterwards. Tuning toward a known answer stays reverse engineering however it is cited.
3. v6.0.1: the licence release that nearly shipped without the licence
6.0.1 changed no code. It existed for one reason: crates.io publishes are immutable, so corrected licence terms can only reach an installed copy through a new version. The corrections mattered. The commercial grant had said “one-time per organization” and then “perpetually for that version”, two readings of one sentence, and the narrower one is the reading a licensee would have had to argue against. It now says plainly that one purchase covers the version licensed and every version released afterwards. Separately, the Change Date moved from five years to four, because BSL 1.1 caps it at four and a five-year parameter was dead text contradicting the same file.
The root LICENSE was corrected. Every check passed. And the release would have shipped the old terms to every user, because each crate carries its own copy of the file, and that copy, not the workspace root, is what cargo archives into the published .crate. Eight copies still carried the superseded terms while the suite was green.
It was caught by building the artifact, unpacking it, and reading the text inside. Not by inspecting the file that had been edited. There is now a check that compares every copy against the root and fails if any has drifted, and it runs before the tag rather than after, because a crates.io publish cannot be withdrawn.
The general form of this is not about licences. Anything that packages, vendors, minifies, inlines, or copies has a step between the file you edited and the bytes a user receives, and every check that reads the source instead of the output is asserting something about the wrong object.
Rule 3
Inspect the artifact you are about to publish, not the source you edited. For anything immutable once shipped, that is the only check that means anything.
4. v6.1.0: the observer was in the wrong place
A consumer of the engine sent an accuracy report. They had measured inner-planet residuals against the accuracy the authors of VSOP87A publish for VSOP87A itself: the theory's own specification, not another implementation's output. That is what made the report usable here at all. Their figures were reproduced from our own committed oracle before their reasoning was read.
The signature was clear and pointed the wrong way. Inner planets bad, outer planets fine, in a theory that is known to be truncated. The first diagnosis was that the shipped coefficient set was cut too aggressively.
That is a testable claim, so it was tested rather than argued. The coefficient set was regenerated at a threshold 100 times finer. The blobs came out byte-identical. Truncation was never the constraint, and the leading hypothesis was dead.
The second candidate was a time-scale error, which produces the same inner-bad signature for a different reason. The Moon settles it without any argument at all. The Moon moves about thirteen times faster than the Sun in longitude, so a clock error large enough to displace the Sun by 4 arcseconds would displace the Moon by roughly 55. The Moon measured 0.169 arcseconds.
A defect that spares the fastest-moving body is not a defect in time. What survives is geometry: something wrong with where the observer is, an error that scales as one over the distance to the target and therefore hurts the near bodies most and the Moon not at all, since the lunar path scales the barycentre-relative vector directly.
There were two, independently.
The analytical provider answered the wrong question. Asked for the Earth-Moon barycentre, it returned VSOP87A's ear series, which is the Earth's centre. earth_state then derived the Earth from the barycentre by subtracting the Moon term, subtracting it from a position that never contained it. About 4,671 km, on the analytical path only.
The barycentre conversion used the wrong divisor. The Moon state it receives is relative to the barycentre, which requires dividing by the Earth-Moon mass ratio; it divided by that ratio plus one. A further 56.8 km, and this one reached every provider, the JPL kernel path included.
Mean apparent ecliptic longitude against JPL Horizons DE441, 1,535 dates per body, 1900 to 2025. Analytical tier overall: 2.058″ to 0.239″ mean, 24.223″ to 1.896″ worst case. The JPL kernel tier improved from the second defect alone, 0.106″ to 0.103″. Reproducible from a checkout.
Neptune does not move. At 30 astronomical units an error of a few thousand kilometres in the observer is not significant, so its 0.503 arcseconds is what the theory actually costs. It is the control. Everything above it was ours.
Which is the uncomfortable part. Until this release the engine README explained the analytical tier's 2.06 arcseconds as VSOP87A being a truncated theory, necessarily looser than a numerical kernel. That sentence was reasonable, was believed, and attributed a defect of ours to the theory's authors. It is corrected in the engine, and the April post that repeated it now carries a dated correction. An explanation that makes a number feel accounted for is the most expensive kind of wrong, because it ends the investigation.
What it cost, honestly
No chart was ever wrong by an amount an astrologer would see. A planet four arcseconds out is in the same sign, the same nakshatra, and all but certainly the same pada.
Timing is a different matter. The Sun moves 0.0411 arcseconds per second of time, so a 4.09 arcsecond mean error is about 100 seconds on a solar ingress, with a worst case near 170. Everything derived from an ingress inherited it: sankranti, and through sankranti the solar month and the year, and any muhurta timed against one. Sunrise moved too, 0.44 seconds at Chennai and more at high latitude, where the Sun crosses the horizon slowly enough that a small positional error becomes a large temporal one.
Rule 4
The clean measurement is often the one that finds the bug. A quantity that refuses to move is evidence, and it eliminates hypotheses faster than the quantity that is visibly wrong.
What this adds up to
Two of these were found by checks built for another purpose entirely. The precession rotation order surfaced because deriving an epoch-anchored sidereal system means evaluating a transform fifteen centuries from where it is anchored, which no accuracy test had reason to do. The observer defect surfaced because the analytical residual is reported per body rather than as one average, so the Moon could be seen to be clean. Neither table was built with its eventual catch in mind.
One was built on the spot, and it is the cheapest of the four: unpack the artifact, read what is inside it.
And one, the first, was found by nothing in the suite at all, which is the reason it leads. Three defects sat behind the best check in the codebase for as long as they did because that check asserted about planetary longitudes and none of them touched a planetary longitude. The useful question about a suite is never whether it is green. It is which propositions it is capable of turning red on, and that list is always shorter than it feels.
One thing has not changed across any of it. Every accuracy figure on this site is measured against JPL Horizons or against the published specification of the theory being implemented. None is measured against another implementation of the same domain, and none ever will be. Agreement with somebody else's engine is not evidence of derivation, and the moment it is used as a target it stops being an independent implementation at all.
Check it yourself
All of this is in the public repository, which is the point of writing it down.
Upgrade to 6.1.0: cargo add vedaksha · pip install -U vedaksha · npm i vedaksha-wasm
There are no API changes and no migration steps, but every value from the analytical path moves. If you have stored charts, longitudes, or ingress timings computed by an earlier version, recompute them. Current measured figures live on /status, and you can run the ephemeris in your browser on /playground.