Is this real?

For an engineer who has no reason to trust this and no time. What is claimed, what the evidence is, where it stops. Every figure names the file that owns it, so you can check the owner rather than this page, and carries a date, because three engine fixes moved the headline in one day on 1 September 2026 and two importer fixes moved it further the next day. Section 8 is the commands.

Most of this page is not in the watched list in engine/tests/test_docs_match_the_catalogue.py, which pins nine named pages to the files owning their numbers, so a re-measurement of those figures will not fail it — one more reason to go to the owner. The exception is §3's mutation figures, as of 2 September 2026. That watch is no longer a list of pages: it is every page that cites MUTATION-REPORT.md or MUTATION-LEDGER.json, this page among them, and it was made derived because a list of three missed the four superseded scores this page was carrying. Twenty-eight false statements have been found in this project's own documentation in two days (docs/STATE-OF-PLAY.md §4).

1. The number to start with

Agreement with Primavera P6 is 67.85% — 396,735 of 584,687 field comparisons across 82 projects, P6 5.0 to 24.12, measured 2026-09-02 (engine/oracle/corpus/SWEEP-2.md). Over the 66 projects that pass the harness's validity gate it is 78.06%, and that belongs beside the headline rather than instead of it, because the 16 refused projects hold 40.9% of all comparisons.

Three things about it matter more than its level.

The ceiling is 98.06%, so the shortfall is ours. A reader who sees 67.85% cannot tell an engine carrying thirty points of defects from an engine measured against a noisy target. That question is now settled and it settled against us. engine/oracle/corpus/P6-SELF.md measures P6 against itself over the same 82 projects and the same 584,687 comparisons — five predicates, each a statement a file makes twice using only fields P6 wrote, with our scheduler never called — and finds 11,330 comparisons sitting on a row whose stored values cannot all be true at once. No scheduler can reproduce those, so achievable agreement is capped at 98.06%: of the 32.14-point shortfall, at most 1.94 points are P6's and at least 30.20 are ours. The two figures are over the same denominator, which is the only reason the subtraction is allowed. This is the opposite of a mitigation. It removes the excuse the project had been able to lean on — some of what we call our defects may be theirs — and on this corpus the answer is almost none of them: the two projects holding 53.4% of the raw disagreement hold 5.2% of P6's self-inconsistency. The 98.06% is itself a bound and not an estimate; it counts only contradictions provable from the file, so the true ceiling is lower and nothing says how much.

It fell. It was 79.32% on a population of 22 projects and dropped to 60.51% when the corpus grew fifteenfold, because the old population contained not one mid-project update and so measured the engine only on the easiest schedules P6 produces (docs/LIMITATIONS.md §1). The fall was kept and explained. It then rose to 61.77% and to 61.89% on that same fixed corpus as two real arithmetic defects were fixed, and to 67.50% the next day on two more.

A single arithmetic defect was worth 1.26 points, and the per-project median went down while the aggregate rose — 85.7% to 85.6% — because the fix reached nine projects out of 82 (docs/LIMITATIONS.md §1). Defects of that size sitting in a lag rule and a date converter say how much is still wrong, not how far this has come. That median is a pre-2 September measurement and has not been re-derived since; it is the figure most likely to have moved without the aggregate saying so.

The largest movement of the five was not in the scheduler at all, and reads the same way. On 2 September 2026 two defects in the importer were fixed — a project calendar that did not inherit its base calendar's exception days, and a midnight act_end_date read as a day end where P6 means a day start — and the figure went 61.89% to 67.50%. Both are fields P6 stores rather than computes, which is the test this repository applies before a field is allowed into the model. Over the same commit, agreement with MPXJ — a second, independent importer — fell, 99.60% to 99.43%, on 1,408 rows where MPXJ keeps P6's raw midnight stamp. That arm measures agreement with another importer's convention rather than with P6's stored dates, and both movements are what the evidence says rather than what would read best.

The third movement of that day is not a movement in agreement at all, and it is the one most easily misread. is_longest_path had been publishing membership of a chain — one driving predecessor per hop — where P6's driving_path_flag marks membership of the set: the backward closure over driving relationships, which branches at every tie. A chain is a subset of its set, so the disagreement could only run one way and did, 2,564 rows to 94. Publishing the set took the headline 67.54% to 67.71% and the DRIVING_PATH disagreement class from 2,658 rows to 1,628, with every other class unchanged count for count — which is the evidence that a definition moved and no date did. The same evidence, scored against a corrected question. The ordered chain is still computed and published under its own name, because "is the longest path continuous" is a question a set cannot answer.

And a fourth movement, of a fourth kind again: 67.71% to 67.80%, with 77.85% to 77.97% beside it. A constraint stamp was being resolved with the start-of-day rule where the constraint it carries asks for the end of one — a calendar rule, neither arithmetic nor a definition. It is +526 comparisons, and one project of the eight it touched went down by one comparison, because two of its rows landed on P6's own stored answer where they had been landing on ours. That fall was kept and reported, which is what this repository does with a correct fix that lowers a number. Twenty-one other commits the same day were measured to move this corpus by exactly zero comparisons, identical project by project across all 82.

Four movements in one day, and no two of them are the same kind of movement: two fields the importer was not reading, then arithmetic, then a change of definition, then a calendar rule. A page that presents them as one number improving four times is telling a false story with correct digits.

If you stop here: the scheduling logic is internally consistent, deterministic and property-checked, which is not the same thing as agreeing with the software that produced the file.

2. What the engine does

It reads a submitted construction schedule and answers two different kinds of question. First, conformance: does this schedule comply with the specification that governs it — docs/CONFORMANCE.md publishes 351 rules across fourteen packs (UFGS 01 32 01.00 10, ANSI/ASCE/CI 67-17, AACE RP 29R-03, the SCL Protocol 2nd ed., an AACE review checklist pack, and eight contract-named or agency packs — VDOT, GAO, AACE 84R-13, Caltrans, PASEG, NYSDOT, NAVFAC, WisDOT and WVDOH), with a governed precedence per jurisdiction so that only rules from an authority that actually binds appear in the report at all. That is the size of the library and not what any one command runs, and the two have been confused on our own pages twice: --jurisdiction us_federal runs 120 of them, us_state_or_private and uk_scl 72 each, neutral 107, and a --contract name adds its own pack. Of the 351, none can any longer return a verdict about a population it cannot observe — ten could until 2 September 2026, eight of them a PASS no schedule could falsify (engine/quality/PROJECTION-BLINDNESS.md). Second, forensic delay analysis: all nine AACE RP 29R-03 Methods of Implementation run end to end, plus prospective TIA under RP 52R-06 (docs/METHODS.md, whose table is generated from the same catalogue the code uses). ~~Three schedule formats are read — XER, P6 XML and Microsoft Project MSPDI — detected from file contents rather than from the suffix.~~ Corrected 6 September 2026: four are read, and the count was wrong on the page that exists to be checked. The importer sniffs XER, P6 XML, Microsoft Project MSPDI and USACE SDEF (cpmcore/sdef.py, selected by cli.py::_detect), from file contents rather than from the suffix; the tool's own refusal message names all four, and this sentence named three. Read the correction the way §3 asks you to read every count here: only the XER reader has been measured against files this project did not write, the other three rest on our own tests, and a fourth format in that group is a fourth thing unvalidated rather than a fourth thing proved. The author holds no PE, no PSP and no CFCC; credentialing/LEGAL-POSTURE.md binds what may be claimed, and the tool supplies a computation while a person supplies the opinion.

3. What is measured, and against what denominator

P6's own stored answers, held-out corpus. 67.85% as above. The corpus is 68 harvested public XER files, 82 projects, 86,031 scheduled activities (engine/oracle/corpus/README.md, 2026-09-01). The files are gitignored and fetched by a pinned, digest-verified script; most source repositories state no licence, which is an absence of a grant and not a permission.

P6's own stored answers, first-party fixture. 156 of 160 field comparisons, 97.5%, on 27 activities across 13 networks captured from a real P6 23.12 installation (engine/oracle/README.md). Read it as "no divergence detected on the semantics these 13 cases exercise" and never as "agrees with P6" — no network in it is wider than a two- or three-activity chain.

Published worked examples. Better than the corpus per case, because it is the only oracle in the tree independent of Primavera: if P6 and this engine shared a misconception, no amount of XER diffing would surface it and an AACE figure would. The cases are in engine/oracle/cases/, each naming its document, section, and the file and line range it came from; a test fails if any case lacks that citation. Two caveats the owning document states and this page will not soften: the 29R-03 Figure 8/9 topology is a defended reconstruction rather than the RP's own drawing, and several cases test an assertion the RP makes using numbers we chose, marked numbers_from_source: false in the case file. Every case is under six activities, with no progress, constraints or holidays.

Our reader against a second reader. engine/oracle/FIDELITY.md, added 2 September 2026, is the first tier here that measures the importer rather than the scheduler, which matters because 265 of the 351 conformance rules never touch the CPM arithmetic. Our import of an XER against MPXJ's import of the same bytes is 1,923,733 of 1,947,919, 98.76%, over 80 projects in 65 files, and of the 24,186 remaining disagreements every one has a named cause; one class, RELATION_TYPE, is an open candidate defect of ours and our reader already warns about it. (Updated 2026-09-05. It read 99.45% over 64 projects in 50 files until the fifteen files recorded as unreadable by MPXJ turned out to be our own test driver crashing; on those same 64 projects the figure is unchanged to the cell, so the fall is the population and not the reading.) It measures agreement with another importer's convention, not with P6's stored dates, so it falls when we move toward P6 and that is not a regression.

The forensic layer against a delay of known size. Every tier above measures arithmetic. engine/oracle/injection/MATRIX.md injects a hand-counted delay into a five-activity network and asks whether each MIP reports the delay that was injected — the first ground truth in this repository that is neither "us against P6" nor "us against MPXJ". All five exercised methods recovered every headline figure, including a placebo and a neutral control that both correctly reported zero. Read docs/LIMITATIONS.md §11 next and not this paragraph alone: the same run is where the attribution limits were demonstrated, and it is the least flattering document in the repository.

How often a rule answers at all. Registered and answering are different numbers and only the second is the product: 39.8% of rule-file pairs return a verdict, 48.7% when the submission names its baseline, and all 13,099 abstentions name a specific missing input (engine/quality/VERDICT-YIELD.md §16, re-measured 2026-09-06 with a control arm at the same revision, and before that 2026-09-05 from two git archive extractions outside the repository; the 2026-09-04 run reproduces to the digit on its own revision, and that one reproduces the 2026-09-02 run).

That figure fell from 40.5% on 2026-09-02, and the reason is the point rather than the digit. One rule — SCL-CP1-1.59 — had been publishing "PASS — all 1 programme versions supplied are distinct" on every single-file submission, because both of its adverse branches quantify over pairs of programmes and a single submission has none. It could not have failed for any input whatsoever, and it shipped that verdict 66 times against a Society of Construction Law clause. It now abstains below two versions. No FAIL count moved; 66 unfalsifiable passes became 66 honest abstentions, and the yield dropped 0.3 points because an unfalsifiable PASS was never yield in the first place (engine/quality/NEVER-ADVERSE.md).

It has since happened twice more, in the same direction and for the same reason. UFGS-071 was withdrawn on a snapshot that had already computed, and UFGS-044 stopped passing on five files where a widened out-of-sequence check found progress it had been blind to — so the clause now abstains naming the approvals register instead of passing over work it had not seen. Three withdrawals, 137 rule-file pairs, no FAIL count moved in any of them. That is the whole of the fall from 40.5% to 39.9%: no rule gained an answer, three rules stopped publishing answers they had not earned, and the same repair that produced the last of the three added twenty adverse findings a reviewer can act on (engine/quality/VERDICT-YIELD.md §7.1).

It fell again the next day, 39.9% to 38.6%, and the second fall is larger and of the same kind (engine/quality/VERDICT-YIELD.md §13). A third fall, 38.6% to 38.2%, is a different kind and §14 keeps it apart: four NAVFAC submission clauses were made runnable and this corpus — single-file exports with no baseline named — cannot reach three of them, so the answered count is unchanged at 7,924 and only the denominator grew. Four more clauses stopped deciding on evidence they did not have — UFGS-037, UFGS-038, AACE-29R-03-2.3.D.3, ASCE-67-17-4.2, 61 files each, no rule gaining an answer. And five corpus files left the population altogether: each holds more than one project, and until 4 September a file like that produced one complete, scored, confident review of whichever project the exporter happened to write first — on one such file, a 181-clause federal report about a 1-activity stub out of 886. The tool now refuses the file and lists what it holds. Those five were supplying 638 of the published 8,720 answers.

Two repairs went the other way in the same window and neither raised the headline. UFGS-098's PASS branch was unreachable, so three real files had been told they breached a federal clause they meet; they now pass. And UFGS-071 — the clause withdrawn above for passing 66 times on 66 files that could not have failed it — now fires exactly once, adversely, on the one corpus file with circular logic, because a loop is reported rather than refused. A clause that answers once about something true is the product; sixty-six that could not have said anything else were never yield.

Answering is not discriminating, and this is the finding that most changes how the number should be read. The same instrument now counts, separately from the answered total, how many rules return a different verdict on different schedules. Every contract input a reviewer could supply adds 68 rules that answer and 8 that tell one schedule from another, across the then-331 rules and the 66 corpus files — the population as it stood on 4 September; §13.5 records that these counts were not re-measured on 5 September and why no before-arm exists for them. Under the UK SCL protocol's terms the answering count goes from 19 to 46 and the discriminating count from 12 to 12 — twenty-seven new answers and no new discrimination, because those clauses interrogate the analysis rather than the file, and against sixty-six unrelated schedules they give the same answer sixty-six times. The agency specifications behave the opposite way, and that is where the value sits: of the 972 new adverse findings the state-DOT terms produce, 642 vary from file to file, because those terms are approval registers and numeric limits checked against the reviewer's own activities. A higher answered count is not automatically a better product (engine/quality/VERDICT-YIELD.md §8.4, §9.1).

One rate is deliberately not published. That pass could have quoted a corpus-wide adverse rate with the contract's terms supplied, and refused to, because 65 of the 66 corpus files carry a data date before the terms file's own dates and a clause comparing a 2026 date to a 2011 schedule cannot do anything but fail. What is published instead is the one job those terms are true for: on a single 800-activity file, 10 federal FAILs became 20, and 18 became 30 under the state-DOT bundle — one job, generated, with terms we wrote ourselves (engine/quality/VERDICT-YIELD.md §9.1, §9.2).

How big, and how long. 19,202 activities and 28.6MB read and computed in 13.5 seconds on a 2017 four-core mobile i7; every stage linear in the activity count and linear in relationship density; past the limit it refuses and names what it refused (engine/quality/PERFORMANCE.md). Before that pass there was no benchmark, no stated limit and no published figure for runtime or memory at any size.

Mutation scores, per module, never the aggregate. engine/quality/MUTATION-REPORT.md says in terms that an aggregate "should not be quoted on its own". The current record is its seventh pass, 2026-09-02: twenty modules measured at one fixed revision, b547c5c, on seed 20260901, in a detached worktree nothing else could edit, every survivor re-run serially — 1,553 of 1,742 mutants killed, 89.2% — with five modules re-measured again at 0f19183, where that later row is the current one. The spread is what to read. resources.py at 64.8% exhaustive is the weakest, and is the module the CLI cannot call at all; graph.py, issues.py, model.py and network.py are at 100.0%; compare.py is 94.5%, progress_logic.py 96.4%, modelled.py 90.9%, cpm.py 86.4%. The four figures this page carried before — 98.2%, 91.8%, 88.3%, 88.2% — are superseded by those rows and are not corrected by them: cpm.py and progress_logic.py each differ by two mutants in a 110-mutant sample drawn on a seed the earlier pass did not use, which the report reads as unchanged, re-measured rather than as a fall.

Four earlier scores in the high nineties were withdrawn when the harness was caught reporting kills it had not made — both the reason to trust the current figures and the reason to read the ledger. quality/MUTATION-LEDGER.json now carries revision and seed on 25 of its 48 rows: every seventh-pass row records which commit the engine was at and which seed drew the sample, so git worktree add --detach <path> b547c5c and mutation.py --seed 20260901 draw the same mutants from the same population again. On the 23 rows measured before those fields existed both are null and are not recoverable — inferring a commit from a file's mtime would be a guess presented as a record. What is still missing, in the terms the pass itself named it: the per-mutant survivor lists are gitignored, so a reader can re-derive these figures and cannot audit our run; nothing here checks that the run happened, only that the ledger agrees with the results files it was written from; eight modules named in SUBSETSprogress, earned, levelling, locations, takt, lastplanner, weather, portfolio — were never measured at all, so 89.2% is a total over the twenty modules this project publishes and not over cpmcore; and a score is still the score of its subset, which widening SUBSETS can only raise.

One movement is worth stating without its percentage. windows.py had been published at 92.6%, measured 86.2% exhaustive at b547c5c, and is 98.3% at 0f19183. The gap between the first two was real and the exhaustive runs make it readable: seven of the eight survivors sat in one block, WINDOWS.NO_COMMON_IDENTITY, which no test in the suite ever touched — it could have been deleted and CI would have stayed green. That block is what stops a window publishing a slip, an attribution and a driving path measured across two schedules that pair no activity at all, which is what P6's renumbered internal ids produce when a series is matched on ID rather than CODE. One test in tests/test_mutation_gaps.py closed it and all eleven of the block's mutants are killed. The finding is a safety property that was unguarded, not twelve points.

The report's own assessment is that the suite "tests what the engine computes and not what it reports". That is the finding, not the percentages.

How much of the product the 67.85% speaks for. docs/RULE-DEPENDENCE.md, derived from the rules' own bytecode rather than written by hand, partitions all 351 rules across all fourteen packs: 56 rest on the CPM arithmetic (16.0%), 30 are engine-gated, and 265 do not touch it. The three sum to 351, which is asserted rather than assumed: engine/tests/test_rule_dependence.py binds the owner's total row to the code. For UFGS specifically, 35 of 48 rules are independent of the engine entirely. The partition covers every pack in the package because it discovers them rather than listing them — the defect that held it at five packs while the library had six is fixed, and the eight packs that landed afterwards needed no edit to it.

4. What is not measured

Nobody has run this on a real project. Zero customers, zero users. Every statement anywhere in business/ about what a reviewer wants is derived from specifications, standards and one published study, not from a reviewer (docs/LIMITATIONS.md §2, docs/STATE-OF-PLAY.md §3).

Importer fidelity has now been measured, and the admission it used to be is worth keeping in view because it was the sharpest one available. 265 of the 351 partitioned rules are facts read out of the submitted file — is a data date declared, are there open ends, is this relationship start-to-finish. They do not inherit the agreement figure at all; they are exactly as good as the importer's reading of the file, which docs/RULE-DEPENDENCE.md names as a separate question. That question went unanswered until 2 September 2026 and is now answered: engine/oracle/FIDELITY.md reads our import of an XER against MPXJ's import of the same bytes and reports 1,923,733 of 1,947,919, 98.76%, over 80 projects in 65 files, with the 24,186 remaining disagreements partitioned and one open candidate defect of ours among them, which our reader already warns about. The gate that ROADMAP item 4 asked for exists and owns its figure. (Updated 2026-09-05 from 99.45% over 64 projects in 50 files; the fifteen files this page counted as unreadable by MPXJ were our own test driver crashing, and on the old 64 projects the figure is unchanged to the cell.)

Read it with two cautions rather than as a clean bill. It measures agreement with another importer's convention, not with what P6 stored — which is why it correctly fell, 99.60% to 99.43%, over the very commit that moved us toward P6's own stored dates. And it does not cover every field: where no independent quantity exists for a field, that field is named as unmeasurable rather than scored. For how much this should have worried you before it was measured, an importer bug once made every calendar in every real XER fall back silently to Monday–Friday, invisible because the fixture used a format P6 does not write (engine/oracle/README.md).

The customer's actual job is a monthly sequence and the corpus cannot test one. engine/quality/SERIES-COHERENCE.md records six genuine series and every one is exactly two data dates long; there is no series of three or more that this engine can load, and two rules in the pack are unusable as a result. It answers "can this be used month after month?" with "Not yet."

Two of the kernel defects this project published against itself were not defects, and that is a finding about the method rather than an embarrassment. This bullet named an open defect in the arithmetic that decides criticality — B3, the late finish capped at the project finish — until 2026-09-02. B3 was withdrawn, as M1 was the day before. Neither was closed by a fix:

Read that in whichever direction you find harder. The weak reading is that a differential oracle reports a disagreement and does not report which side is wrong, and this project read a disagreement as a verdict against itself twice out of the three times it named its own kernel — so a tier (b) finding here is a question, not a verdict, and a page like this one carrying "an open kernel defect" was, for a week, simply wrong. The strong reading is that both false positives were caught by us, by measurement written into a test rather than into a paragraph, and that in the B3 case the fix that would have made the disagreement disappear was built, measured, and thrown away because the measurement said not to. Both readings are true and neither cancels the other. What is left in that tier is three unsettled semantics — B5, B6, M9 — each needing a donated P6 file to settle and none with a side established as wrong.

What the checks themselves do not cover is written down. Do not read a green suite as coverage. engine/tests/test_docs_match_the_catalogue.py publishes a NOT_CHECKED block naming what escapes its documentation tests; engine/src/forensic/rules/citations.py publishes one naming the packs whose citations are unverified and why; docs/CONFORMANCE.md §4 lists what the rule packs do not check, by clause number. Those three are worth more than the tests around them and are the first thing to read if you are trying to break this.

5. Two disagreements found while writing this page

Recorded rather than resolved: the owning files are not this page's to edit, and a finding not in a file does not exist.

M1. Resolved 2026-09-02, and the count moved twice more than this entry expected. As written, this said docs/STATE-OF-PLAY.md §3, business/BUSINESS-PLAN.md and business/RISKS.md say "two open kernel defects, B3 and M1, both URGENT and open", against engine/oracle/differential/FINDINGS.md, which marks M1 WITHDRAWN on 2026-09-01 as an adapter convention. Two corrections to that:

~~The vdot pack is outside the dependence partition.~~ Fixed 2 September 2026, and kept here because it is the seventh instance of the class. It was: docs/CONFORMANCE.md published 242 rules across six packs; docs/RULE-DEPENDENCE.md partitioned 216 across five, and engine/tests/test_rule_dependence.py held it there because the test named five registries by hand. Both pages were green, so vdot's 26 rules sat outside the partition and outside the dynamic witness that catches a rule reaching a computed field it was not classified for — a check whose subject is a list the check itself maintains. PACKS is now discovered by walking the package, the partition covers all thirteen, and the eight packs that landed afterwards needed no edit to it, which is the only proof that the fix was the right shape.

An eighth instance was found the same day, and this one was in the rules rather than in a test. Ten conformance rules were returning verdicts about level-of-effort and WBS-summary activities that ExchangeSchedule.to_network() had already dropped: eight returned a PASS no schedule could falsify, one restated an unfalsifiable sentence as an observation, and one printed a count of zero for a population of 297. All ten now decide from the file or report NOT_EVALUATED naming what would decide them, the count of rules that cannot fail is 0 of 351, and a test fails if that changes (engine/quality/PROJECTION-BLINDNESS.md). The residual is a real coverage gap — on a file carrying such activities, six clauses about their logic and their place on the critical path are not answered at all — and it is now printed as a gap in every report on such a file rather than absorbed into a PASS. 11 of the 69 corpus files reach it.

One staleness. engine/oracle/README.md's tier table describes eleven worked-example cases and 94 assertions; engine/oracle/cases/ holds seventeen case files as of 1 September 2026. ls settles it in five seconds, which is the point of §8.

6. The architectural ceiling, and why it is credible

The time axis is whole-day. P6 finishes an in-progress activity with a fractional remaining duration at a mid-day instant and starts its finish-to-start successor at that same instant on that same date; a whole-day engine cannot, so it loses a working day at the link on top of the one lost inside the activity.

That mechanism is controlled, not merely correlated: taking only activities all of whose predecessors already agree with P6, 5,441 activities in 22 files hand off at a mid-day instant and the successor's start is one working day late on 5,429 of them — 99.8% — against a matched control of 1,974 activities handing off at a day boundary, of which 1,944 agree exactly, 98.5% (engine/oracle/corpus/MIDDAY-MECHANISM.md).

The ceiling was measured by a failed attempt to breach it, which is why it is worth more than an assertion. A derivation built deliberately stronger than any engine could be — carrying the offset exactly in minutes, and choosing the driving predecessor using P6's own stored dates, an advantage this engine does not have — recovers 70.0% of the affected rows while misfiring on 14.2% of the rows currently correct. That defeats the fix as specified. It is not a proof that no derivation exists, and the owning document does not claim one.

Two qualifications. The mechanism is not a diagnosis of the gap: in the file where it was found it accounts for 15.5% of the unstarted rows, and the largest single unexplained thing in the corpus is 230 forward-pass origins in that same file whose predecessors all agree. And a bound this project published for months turned out to be false and was replaced by a measured one (docs/LIMITATIONS.md §1).

7. What should make you look further, and what should make you walk away

Walk away if you need a validated recomputation engine. 67.85% is not a qualification for work an opposing expert will cross-examine, part of the remaining gap has a measured ceiling rather than a fix date, and no customer has ever run this.

Walk away if the venture argument does not survive. docs/POSITIONING.md §6 states the argument against at full strength — the buyer is a person who signs a report, not a computation; the part that genuinely automates is commoditised at a few hundred dollars a year; refusal discipline hands the expert back precisely the questions they were being paid to answer. It then concedes what its own rebuttal costs: the response moves the venture off high-value forensic work onto specification conformance, where the nine-of-nine method claim is not what is being bought. So the strongest form of the argument is not "this cannot be sold" but "the thing that is differentiated and the thing that is saleable are not the same thing", and that tension is unresolved. If that is your question, read §6 before anything else here.

And the failure mode the project names for itself. docs/STATE-OF-PLAY.md §6: the likeliest way this fails is that it never becomes a product and becomes an artefact — the work stays excellent and inward. It sets a checkable sign: if by 15 September 2026 no file in the tree records a conversation with a named practitioner, the diagnosis is confirmed.

Look further if what you need is the conformance layer. 265 of 351 rules read the file rather than the arithmetic, all nine methods run, precedence is governed rather than assumed, and the report refuses to decide what it cannot decide. That layer is not capped by 67.85%. It is capped by importer fidelity, which is now measured at 98.76% against MPXJ on the same bytes, over 80 of the 84 projects on disk — so the thing to ask for is not a better agreement number but what the remaining 24,186 disagreements are, and engine/oracle/FIDELITY.md partitions them.

Look further if the discipline is what you are buying. The evidence is behavioural. A leak was found where the tool read P6's own computed finish back in as an input; removing it dropped agreement on one file and raised it thirty points on another, and the fall was kept and published. Four mutation scores were withdrawn when the instrument was caught flattering itself. A plausible fix that raised the number was falsified and refused. And two defects this project published against its own kernel turned out not to be defects — both withdrawn by measurement rather than by argument, one of them after the fix was built and thrown away because measuring it said not to (§4). Note which way that last one cuts: it means a published "urgent, open" defect stood in five documents for a week on the strength of a disagreement nobody had re-measured. The discipline is real and it is not fast. That is the only real differentiator here.

8. Checking any of this yourself

All of it from engine/, after pip install -e ".[dev]":

python check.py    # the gate: unit suite, oracle suite, import contracts, P6
python oracle/harness.py oracle/cases/p6-23.12-xval.oracle.xer   # the 156/160
pytest oracle/ && ls oracle/cases/*.json    # the independent worked examples
pytest tests/test_rule_dependence.py        # the 265/30/56 partition, derived
python quality/ledger.py --markdown         # every mutation score's arithmetic
python -m forensic check oracle/cases/update-chain-02-update.xer --jurisdiction us_federal
python -m forensic analyse oracle/cases/update-chain-01-baseline.xer \
    oracle/cases/update-chain-02-update.xer \
    oracle/cases/update-chain-03-update.xer --method 3.3 --baseline 0

The last two lines were corrected 6 September 2026 and the correction is this page's own subject. They read update-07.xer and update-06.xer — names this repository has never held — so a sceptic following the section titled checking any of this yourself was answered update-07.xer: No such file or directory and exit 2 on the two commands that exercise the product rather than the test suite. The files above are in the clone. --baseline 0 is on the second because MIP 3.3 refuses to guess which file is the contract baseline, and --method 3.3 needs at least two updates to have a window between them. Both exit 1 here, which is a report with findings and not a failure to run.

The corpus figure. The files are gitignored, so this fetches all 68 by pinned commit and verifies every digest before measuring:

cd oracle/corpus && python fetch_corpus.py --verify && python gapshape.py

Exit code 0 from the CLI means no blocking failure was found, which — given the coverage the report prints — is a weaker claim than conforms; READING-A-REPORT.md explains the difference.

Where to go next. LIMITATIONS.md in full, POSITIONING.md (POSITIONING.md) §6 for the argument against the venture, and OPEN-ITEMS.md (OPEN-ITEMS.md) for everything recorded anywhere here as unfinished, unverified, deferred or known-wrong. This page is a route into those, not a substitute for them.

Source: docs/IS-THIS-REAL.md. Source commit date: 2026-09-06.

See it in practice

Follow the evidence, from the schedule to the finding.

Explore the worked example