Reading a report

The report is ordered the way it is on purpose, and the ordering cannot be changed. This document explains what each part is claiming, and — for two sections in particular — what it obliges you to do next.


1. Why the assumptions come before the findings

Every Construct report emits, in this fixed order:

  1. Method
  2. Governing documents (and where they disagree)
  3. Choices that could have gone the other way
  4. Assumptions
  5. Limitations
  6. Principles relied on
  7. Findings

There is no parameter to reorder it. A report that opens with its conclusion and buries its assumptions in an appendix has the emphasis exactly backwards for its purpose: the assumptions are what the other side will attack, and burying them reads as concealment even where nothing was concealed.

The commercial argument is the same as the evidentiary one. AACE RP 29R-03 §1.1 states that the practice exists to eliminate "black box" analyses, and §1.2(d) states as a premise that every method is subject to manipulation through analyst judgment. A report presenting any method as mechanical is misrepresenting the standard it cites.

The reporting layer computes nothing. Every value it prints was decided elsewhere and passed in. That is deliberate: a reporting layer able to compute would be able to disagree with the analysis it reports, and the first time those two diverge the report is worthless.


2. Three things that look similar and are not

Disclosure — a choice that could have gone the other way

A disclosure is not any parameter. A report listing four hundred settings is a black box with an appendix: the reader cannot tell which of them mattered, so they check none. A disclosure meets all three of:

  1. It could have gone the other way. Retained logic or progress override is a choice. The number of days in a week is not.
  2. The other way gives a different answer. If both settings produce the same dates on this schedule, the choice did not matter here, and saying so is more useful than listing it.
  3. A published document leaves it open, or two documents disagree. Then the citation goes in the report, because the reader's objection is not "you chose wrongly" but "you chose without saying" — and a citation answers it.

Each disclosure carries what was chosen, the alternative, the reason, the source, and — where it was computed — what the alternative would have given. Naming the alternative's result is what turns a disclosure from an admission into evidence of diligence.

Disclosures are split into material and immaterial. Immaterial ones are listed in one line each, "recorded so the reader need not verify that".

Read the materiality claim carefully in command-line reports. The python -m forensic command marks every disclosure material without establishing it, because computing materiality would mean rescheduling every file under every combination of settings — which is the analysis rather than a footnote to it. The rendered heading therefore says "N of N choices below would change the result on this schedule" when what the tool actually established is "N choices were made and none was tested for materiality". Treat the list as complete rather than as filtered. See LIMITATIONS.md §9.

Assumption — a gap in the evidence, filled in order to proceed

An assumption is not a choice between two defensible readings. It is something taken as true that was not established. Conflating the two understates the gaps: a reader skimming a list of "methodological choices" will not register that one of them means "we did not have the baseline".

Each assumption carries: what was assumed, why the analysis could not establish it, what would resolve it, and what it affects. An assumption with no route to resolution is not an assumption — it is a limitation, and belongs in the other list.

Limitation — something the analysis cannot do at all

Stated before anyone asks. Each carries what it is, the consequence, and — where anything would — what would remove it.

One limitation applies to every report this engine produces today: "This engine's results are not validated against Primavera P6." Stating it costs a paragraph. Having it discovered in cross-examination costs the analysis.


3. DETERMINISTIC, HYBRID and JUDGMENT

Every conformance finding carries a determinism class. It comes from the AACE implementation survey's own classification of the procedures in RP 29R-03, and it is the most useful thing in that document for anyone building software. It is a required field on every rule, and ~~the report prints it~~ --json carries it on every finding; the Markdown and HTML reports do not print it at all — corrected 6 September 2026, by grepping both outputs of one run for all three class names and finding none of them outside ordinary prose.

What those two forms print per finding instead is the other partition, dependence: from your file or from our arithmetic, which says whether the verdict rests on this engine's CPM calculation. The two are different questions and neither substitutes for the other. Until the class is printed, the way to read this section against a Markdown report is by grouping: REFERRED is a JUDGMENT rule and nothing else is, and an abstention naming a terms[...] key is a HYBRID rule saying which term it wanted. DETERMINISTIC and HYBRID are not distinguishable in the Markdown at all where both decided, and that is a gap in the report rather than in the model.

DETERMINISTIC — the tool decided

The rule computes its own answer from the schedule. "Every activity except the first and last has a predecessor and a successor" is a fact about a graph.

What you do differently: check the evidence list, not the verdict. The verdict is arithmetic. If you disagree with it, you disagree with the parse or with the clause reading, not with the computation.

HYBRID — the tool decided, given an input you supplied

The rule computes an answer given something the schedule does not contain. "No activity exceeds the maximum duration" needs the specification's maximum.

What you do differently: check that the term supplied was the right one. A HYBRID PASS is only as good as the number you fed it. If contract_completion_date was wrong by a week, every rule that reads it is wrong by a week, and the finding will look identical either way.

When the term was not supplied the rule does not pass and does not fail. It reports NOT_EVALUATED naming the key. No industry default is ever substituted — a default silently applied is a specification the reviewer never agreed to, and it is worse here than elsewhere because the report looks identical either way.

There is one pattern that recovers many HYBRID rules without any term at all. Many clauses read "X is prohibited unless the Contracting Officer approved it." Without the approval log such a rule looks undecidable — but when the schedule contains no X at all, there is nothing to approve, and the rule is decided. So these rules PASS on a clean schedule and report NOT_EVALUATED, with the offending items already named as evidence, on a dirty one. You are then reading "these three constrained activities need an approval record", which is the actual work item, rather than "could not evaluate".

JUDGMENT — a person decides, and it is you

The rule cannot be decided by computation at all. "The logic is reasonable" is not a computation.

A JUDGMENT rule cannot return PASS. That is refused structurally, not by convention. A Finding that claims a JUDGMENT PASS raises where it is built — but Finding.determinism is written by the rule author, so the constructor alone would catch only an author who labelled the finding honestly. run() therefore rebuilds every finding with the determinism the rule was registered under, so the refusal is against the registration. A rule registered JUDGMENT that labels its finding DETERMINISTIC loses its verdict to NOT_EVALUATED naming the reason; it cannot print a green tick. A green tick against "the logic is reasonable" is a lie told in the one document whose reader is entitled to assume otherwise, and a rule pack that reclassified a judgment rule to raise its automation percentage would make the tool untrustworthy in exactly the setting where trust is the entire product.

A JUDGMENT rule returns REFERRED, and a REFERRED finding must state a question — that too is enforced at construction.

What you do differently: answer the question. That is the whole point. The tool's job on a judgment clause is to turn "consider whether the lags are reasonable" into "consider these four lags, which total 46 days across the driving path" — which is most of the reviewer's work, and the part software can actually do. A referred finding that names no activities has done nothing.


4. The five verdicts

Verdict Meaning Counts toward score?
PASS The rule ran and the schedule satisfied the clause Yes
FAIL The rule ran and the schedule breached the clause Yes
OBSERVATION The rule ran and found something worth looking at, which the specification does not make a failure No
NOT_EVALUATED The rule could not run. missing says what would let it No
REFERRED JUDGMENT rules only: the evidence is assembled, the question stated, and a person must answer it No

OBSERVATION exists because a report that cannot separate "breaches the spec" from "is worth a look" trains its reader to ignore both.

Severity is orthogonal to verdict. A rule can fail on a trivial point and pass on a load-bearing one, so ranking a report by verdict alone puts a missing activity code above a schedule with no critical path. The four levels are CRITICAL, MAJOR, MINOR, INFO, and blocking means a FAIL at CRITICAL or MAJOR — the failures a reviewer would reject the submission over.

A rule that crashes is reported as a NOT_EVALUATED finding naming the exception, at MAJOR severity, and does not abort the run. A reviewer with 40 of 41 rules and one named crash is better served than one with a traceback, and the crash stays visible in the report rather than being swallowed. A rule that yields nothing is likewise reported as NOT_EVALUATED: a silent rule is indistinguishable from a rule that crashed.


5. Score and coverage are two different statements

score    = passed / (passed + failed)
coverage = (passed + failed) / total findings

Not-evaluated, referred and observation findings are excluded from the score's numerator and denominator, and coverage tells you how much the score is worth.

Abstaining cannot raise the score. An abstention is removed from the fraction entirely — it is in neither the numerator nor the denominator — so a schedule does not become more conformant because a check could not be performed on it. What an abstention does instead is lower coverage, which is why the two numbers are always printed together and neither is fit to quote alone.

An earlier version of this page said "skipped checks leave the score's denominator", which contradicted the correct sentence three lines above it and described arithmetic nothing performs. Leaving them in the denominator would mean scoring them as failures, which would be a different lie.

Compare two reports on the same 41-clause pack:

38/41, coverage 100% 38/41, coverage 60%
Clauses decided 41 25
Clauses that could not be decided 0 16
What the 38 means 38 of the 41 clauses that govern this submission were satisfied 38 of the 25 clauses the tool could reach were satisfied — and 16 clauses were never assessed at all
What you can say to a Contracting Officer "This submission was checked against the whole section and fails three clauses." "This submission was checked against three-fifths of the section. Three of the clauses reached fail. Nothing is known about the rest."

The second report is a narrower claim, not a weaker version of the first. Its score is a statement about a subset you did not choose — the subset happens to be "whichever clauses need no contract terms", which is systematically the easier clauses. Reading it as 93% conformant is the single most common way to misuse this tool.

When nothing at all could be decided, score is None, not 0.0 and not 1.0. Both of those are claims. "We could not assess this schedule" is the truth, and it needs its own value. The report prints "No clause could be decided on the material supplied. The score is not zero; there is no score."

Confidence

Each findings section carries a confidence: computed, computed_unvalidated, assumed, or judgment. The report prints the weakest one across all its sections, because a conclusion is only as strong as the weakest step supporting it — a summary must not present a chain of reasoning as computed when one link in it was judgment.

~~The command-line conformance section labels itself computed_unvalidated whenever coverage is below 100%. Read that as "coverage is incomplete", not as "the inputs were unvalidated".~~

Corrected 6 September 2026, and the correction had been sitting in LIMITATIONS.md §9 item 4 — which this note already cited — since the code was fixed. The label is set unconditionally, and it means exactly what the enum says: computed from inputs that could not be validated, which is true of every run of check regardless of coverage, because check does not perform the Source Validation Protocols. Measured: a run restricted to one deterministic clause with --rule ASCE-67-17-5.1 reports coverage 1.0 and is still labelled computed_unvalidated. Tying it to coverage is the defect that was removed — it labelled a fully-covered run as validated when nothing had been validated. Run validate for the thing this label says was not done.


6. What NOT_EVALUATED obliges you to do

It obliges you to do the check yourself, or to supply the input. It does not mean the clause passed, and it does not mean the clause is unimportant. It means the tool refused to guess.

Each NOT_EVALUATED finding names exactly what would let it run — every one of the 79 abstentions in the §7 sample run carries a non-empty missing. What it names falls into three families. ~~There are three shapes~~ — corrected 6 September 2026: the sentence read as three fixed strings, and one no-terms run across the thirteen packs emits forty distinct wordings outside family 1. Match on what the line asks for, not on its exact words.

  1. A contract term. Usually needs terms['some_key'] -- what it is. Supply it in the --terms JSON file and rerun. The ASCE pack writes the bare key insteadneeds asce.delay_events, with no terms[...] wrapper and no explanation — so searching a report for terms[ misses fourteen of them. CONFORMANCE.md §5 explains what each key means for three of the thirteen packs; the run itself is the only complete list, and unanswered groups it by the input rather than by the clause.
  2. More schedule material. The commonest is needs a prior schedule submission to compare against — pass more files, oldest first. Also in this family: needs a snapshot marked as the baseline (Snapshot.is_baseline), which wants --baseline N and not another file; needs two calculated schedules, needs at least three schedule versions, and needs in-progress activities, which want a schedule that has actually been statused. The sentence after the dash says which.
  3. A defect in the tool. needs a finding from the rule; a silent rule cannot be scored or needs a fix to the rule implementation — that is not in the schedule. Report it. These are the only two fixed strings in the list, because they are written once in rules.run rather than by each rule.

A report where a third of the clauses are NOT_EVALUATED is the correct output for a submission whose contract terms were never provided. Printing a confident score instead would be the single most damaging thing this tool could do. But it is a work item, not a result: for each one, either fill the term or perform the check by hand and record that you did.


7. A worked example, annotated

This is a real run against a three-activity file, under --jurisdiction us_federal with no --terms and no --baseline. It is deliberately a bad case, because a bad case is what you need to be able to read.

python -m forensic sample.xer --jurisdiction us_federal

Method

## Method

No method has been declared for this analysis. Under AACE RP 29R-03 the
method is itself an argument to be made and defended, so this report
cannot be presented as a delay analysis until one is stated.

Annotation. This is a conformance review, not a delay analysis, so no MIP was declared. The report says so rather than leaving the section blank. If you see this heading on something presented as a delay analysis, that analysis has not named its method and cannot be defended under 29R-03.

Governing documents

1. UFGS 01 32 01.00 10
2. ANSI/ASCE/CI 67-17
3. AACE RP 29R-03

### Where the governing documents disagree

**which standard governs the analysis on US federal work**

- Followed, per ANSI/ASCE/CI 67-17: UFGS 01 32 01.00 10 §3.8.4 makes
  ANSI/ASCE/CI 67-17 the governing standard for schedule delay analysis on work
  adopting the section
- AACE RP 29R-03 instead holds: AACE 29R-03 is the more widely cited taxonomy and
  is frequently applied by default, including on federal work where it does not
  govern

Annotation. No assumed warning here, because --jurisdiction us_federal was stated. Had it been omitted, this section would open with "No governing document was established for this project."

The conflict block is the reason this section exists. If the expert on the other side has run an AACE 29R-03 analysis on federal work, this is the paragraph you cite.

Choices that could have gone the other way

3 of 3 choices below would change the result on this schedule.

### Out-of-sequence progress
- **Chosen:** retained_logic
- **Alternative:** the other two progress modes
- **Reason:** read from the schedule as computed, not from the covering letter
- **Source:** UFGS 01 32 01.00 10 §3.3.17

### Lag calendar
- **Chosen:** predecessor
...
### Data date convention
- **Chosen:** through
- **Source:** AACE RP 10S-90

Annotation. Three settings, each of which moves dates. The progress mode was read from the file's own recorded scheduling options, not chosen by the tool — which is the only correct behaviour for a conformance check, because the question is what the submitter scheduled with. See CONCEPTS.md §4 and §3 for what each one does.

The "3 of 3 would change the result" heading overstates what was established — see §2 above.

Assumptions

### No schedule was identified as the contract baseline
- **Why assumed:** --baseline was not given, and the earliest file is often a
  superseded plan
- **Resolved by:** the executed baseline acceptance, and --baseline naming that file
- **Affects:** ASCE-67-17-10.1, ASCE-67-17-10.2, … ASCE-67-17-4.5

### No contract terms were supplied
- **Why assumed:** --terms was not given
- **Resolved by:** a JSON file of the thresholds the specification states
- **Affects:** 47 rules that could not be decided

Annotation. Both are work items. The tool did not promote the earliest file to baseline — which is a contractual fact, not a modelling one, and the earliest file is very often a superseded plan. The Affects line names the rules that went undecided as a result, so you can see the cost of not supplying it.

Limitations

- **This engine's results are not validated against Primavera P6** — The
  scheduling logic is internally consistent, deterministic and property-checked,
  but no held-out corpus pairs real schedules with P6's own computed answers, so
  agreement with P6 has not been measured. Figures here should be reconciled
  against the source software before they are relied on
  - Removed by: a validation corpus of real XER files carrying P6's stored
    computed dates and floats

Annotation, and the excerpt above is stale. A limitation like this appears on every report and must not be removed from a deliverable — but its text has moved, and in the direction that matters. The version above says "agreement with P6 has not been measured". It has been: the report now names the corpus figure, interpolated from disclosure.P6_AGREEMENT rather than typed, and states which four movements produced it. A reader who trusted this page's excerpt would quote a report we no longer print. See LIMITATIONS.md.

Findings

Stale as of 2026-09-02, and not repaired here. The excerpt below predates three changes to the report: the score and its coverage are now one sentence (they were separable, and a score that quotes without its coverage is DEPOSITION.md attack 8); the completeness assurance says "read" rather than "loaded and cross-checked", because there is nothing to cross-check one file against; and the verdict-class labels are #### headings carrying their own counts rather than bold paragraphs. The annotations under each block are readings of particular figures, so re-deriving the digits without rewriting the readings would produce the failure CLAUDE.md records under "Derive the number, but never the sentence about it". demo/outputs/ is generated from a real run on every commit and is the live example until somebody reads this page through.

The weakest step in the reasoning below is *computed_unvalidated*. No conclusion
drawn from it is stronger than that.

### Schedules considered
- **XV01** — data date 2026-01-05, 3 activities, 2 relationships

Every file supplied was loaded and cross-checked, including any the chosen
method does not consume (AACE RP 29R-03 §1.5.B principle 7).

### Specification conformance

**22 passed, 4 failed** of 26 clauses that could be decided — 85%.

Coverage: 31% of 83 applicable clauses were decided. 47 could not run and
6 need a person.

Annotation — the two most important numbers in the report.

85% is a statement about 26 clauses. It is not a statement about the submission. Fifty-three of the eighty-three applicable clauses were never reached.

Eighty-three was UFGS (48 rules) plus ASCE 67-17 (35 guidelines), because us_federal put both authorities in the precedence when this transcript was captured. It is 120 today — AACE 29R-03's 37 rules were registered, tested and wired to nothing until the authority map was made total, and uk_scl went from 0 rules to 72 in the same fix. The reading above is unchanged and the arithmetic under it is not: change the jurisdiction and the denominator changes — see CONFORMANCE.md §2 for the current four.

The correct summary of this report is: "Of the clauses that can be checked without contract terms or a comparison schedule, four fail — two of them blocking. Nothing has been established about the other 53."

**Blocking failures**

- `UFGS-034` §3.3.8.1 — the schedule contains 0 activities titled
  'NTP Acknowledged'; §3.3.8.1 requires exactly one
- `UFGS-035` §3.3.8.2 — the schedule contains 0 activities titled 'End Project';
  §3.3.8.2 requires exactly one
- `UFGS-041` §3.3.11 — 2 open-ended logic defects under §3.3.11
  - 9200 '01-fs-chain A' opens the schedule; §3.3.11 requires that to be
    'NTP Acknowledged'
  - 9202 '01-fs-chain C' closes the schedule; §3.3.11 requires that to be
    'End Project'
- `UFGS-098` §3.12.f — the file does not define critical activities as the
  longest path; §3.12.f requires Longest Path rather than total float
  - sched_open_critical_flag = N
  - sched_float_type = FT_FF

Annotation. Every failure names the offending items. A finding that says "17 activities have no predecessor" without naming them is a number you have to reproduce by hand, which is the work the tool was supposed to remove. Evidence lists are truncated at 50 items with an exact "…and N more" tail — the truncation is lossy, the count is not.

UFGS-098 is worth reading closely: the tool read sched_float_type out of the file's own scheduling options. This is a finding about how the submitter configured P6, not about how the tool computed anything.

**Referred — the tool assembled the evidence and will not conclude**

- `UFGS-016` §3.3.1 — Is this level of detail sufficient for the work, per
  §3.3.1? The clause gives an open list of characteristics and no threshold, so
  the officer's judgment cannot be pre-empted -- only supplied with the figures.
  - activities: 3 (3 work, 0 milestones)
  - relationships: 2
  - median original duration: 3 days
  - longest: 9200 '01-fs-chain A' 5d

Annotation. This is what a JUDGMENT rule looks like when it is working. It has not passed, it has not failed, and it will never do either. It has handed you the figures the clause is about and asked the question in the clause's own terms. Your answer goes in your review; the tool records that it did not answer it.

**Not evaluated — one input away from deciding**

- `UFGS-011` §3.2 — needs terms['pay_period_thru_date'] -- the 'Pay Period Thru'
  date on the payment request
- `UFGS-046` §3.3.14 — needs a prior schedule submission to compare against
- `UFGS-060` §3.4.1 — needs terms['ntp_ack_date'];
  terms['preliminary_submission_date']
- `ASCE-67-17-8.1` §8.1; cf. AACE RP 29R-03 §4.1 — needs asce.delay_events
  …

Annotation. This is your to-do list, and it is the most useful part of a first-pass report. Three of the four shapes appear here: a missing contract term, a missing comparison schedule, and a missing analysis input.

UFGS-011 — the data-date-to-pay-period check — is one JSON line away from deciding, and it is the clause that ties schedule conformance to the payment the specification conditions on it.


8. What a passing report does not mean

A passing conformance report means the clauses this tool could reach, on the material you supplied, were satisfied. It does not mean the schedule complies with the specification. CONFORMANCE.md §4 lists, by clause number, what the packs do not check and why.


9. One snapshot and two: the same project, measured

§6 tells you to pass more files. This is what the second file is worth, measured on one project rather than asserted.

harbour-point-24.12 is a public P6 export held in the oracle corpus as a baseline and an as-built of the same project (58 and 59 activities; engine/oracle/corpus/MANIFEST.json carries the commit and digest). Both runs below are on the same engine, the same day, with no --terms and no --jurisdiction.

validate check
baseline alone 0 passed, 0 failed of 3 checks 10 passed, 1 failed of 11 decidable clauses — 10% of 107
baseline + as-built, --baseline 0 3 passed, 1 failed of 16 checks 14 passed, 2 failed of 16 decidable clauses — 15% of 109

The second snapshot does not improve the score; it changes how many checks exist at all. Source validation goes from three checks of which none could be evaluated, to sixteen of which four decided. That is structural: every protocol under AACE RP 29R-03 §2.3.B compares one dated snapshot against another, so with one file there is nothing for them to read, and they correctly report NOT_EVALUATED rather than passing vacantly.

What the pair produced that the single file could not:

--baseline 0 is not optional to this. Without it the earliest file is not assumed to be the baseline — §2.1.B's protocols are the ones that validate the baseline, so assuming which file it is would decide the question they exist to ask.

For a first run, hand it two dated snapshots and name the baseline. A single file yields an honest report with the source-validation section empty, and the emptiness is the correct answer to what was supplied, not a defect to work around.

10. Reading the HTML report with a screen reader

The HTML report was built with accessibility in mind and, until now, none of it was tested. engine/tests/test_html.py covered tag balance, one h1 with no skipped levels, the provenance dl, an ol for the governing documents, and a nested list inside its parent li. engine/tests/test_report_accessibility.py adds the rest, each check written as a predicate that a deliberately broken control document must trip, so a check that cannot fire is visible as one.

What is now tested, and the mutation each was watched to fail against:

Property Mutation that fails it
One <main>, all content inside it remove the wrapper, or emit the h1 before it
The ol items are the precedence the engine computed, in order, for every jurisdiction reverse governance.precedence
Nothing tabular arrives as a layout table or as a line of pipes put a Markdown table in a section body
No verdict carried by a glyph, and the stylesheet declares no colour render a pass as a tick; add color: red
Source order is reading order — no float, position, order, direction add float: right
The reader's zoom and font size win — no px/pt font size, no locked viewport font-size: 12px; user-scalable=no
Every finding names its clause and says what was found, in its own text render a finding as its id and verdict alone
The report contains no links (a tripwire: the first one added forces a review of its link text) add an <a>

What could not be honestly tested. Whether the headings describe the structure is a reading, not a property — a test for it would assert that headings exist, which they do, and pass for the wrong reason. Whether a <th> carries the right scope cannot be tested on a document that contains no tables; the check is written so that the day one appears it must have headers, but today it is the control document, not the report, that exercises it.

Four defects the checks above found and do not yet fail on, because fixing them changes the renderer:

  1. **Blocking failures**, **Referred ...** and **Not evaluated ...** are emitted as <p><strong>...</strong></p> — bold paragraphs, not h4. They are the only signposts inside the conformance section, so a listener navigating by heading arrives at "Specification conformance" and then has no way to reach the failures except by reading everything between. The same applies to the conflict subject line under "Where the governing documents disagree".
  2. Emphasis inside a line is not converted: *from your file* and *from our arithmetic* reach the document as literal asterisks. html.py's _EM matches only a line that is entirely emphasised.
  3. The confidence marker renders as <p><em>computed</em></p> — one italicised word with no label. Read aloud after a heading it is the word "computed" and nothing else; it needs to say what is computed, e.g. "Confidence: computed".
  4. <dl aria-label="Report provenance"> is the only labelled region in the document. That is right, and the point is the contrast: every other block is reachable only through the heading above it.

None of these makes the report unusable. A screen-reader user can open it, hear the title, walk the h2s, hear the provenance as label-and-value pairs, hear the governing documents numbered in precedence order, and read any finding as a self-contained sentence naming its rule id, its clause and what was found. The defects are navigation cost inside the findings section, not lost information.

Source: docs/READING-A-REPORT.md. Source commit date: 2026-09-06.

See it in practice

Follow the evidence, from the schedule to the finding.

Explore the worked example