Forensic schedule analysis is litigation evidence. A delay claim filed in 2026 may be reopened on appeal in 2030, cited as comparable in 2032, or re-examined by a successor expert in 2036. The artifact has to still work.

Most forensic tools quietly fail that test. A 2018 React dashboard already breaks in 2026 browsers because two of its npm packages got abandoned. A 2020 PDF generated with a remote Google Fonts call goes silent the day the font URL is restructured. An "interactive" report served by a 2017 cloud vendor disappears the day the vendor sunsets the product line.

Critical Path Partners runs a discipline on every artifact we ship to keep this from happening to the records our clients rely on. We call it the Forensic Record Archival Certification. There are six elements. Each is enforceable. Each is verifiable by an opposing expert. We publish it as a standard because we want it adopted.

The test

Disconnect from the internet. Open the file. Does it render identically? If yes, the artifact survives the next ten years.

1. System fonts only

Local font stacks, no remote font hosts

Requirement
Every artifact declares fonts via local system stacks: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif. No @import url(...). No <link> to fonts.googleapis.com, fonts.gstatic.com, or use.typekit.net.
Why it matters in litigation
When a typeface is fetched from a remote CDN, the rendering of the exhibit depends on a third-party host staying online and the URL contract staying stable. CDNs reorganize. Hosts go dark. When that happens, the exhibit reflows: line breaks shift, page numbering drifts, signature blocks move. A judge reading the same PDF in 2032 doesn't see what your expert signed.
How CPP implements it
Every HTML output, every blog post, every static demo page on mcp.criticalpathpartners.ca uses system-font stacks only. DOCX outputs declare Calibri (universally installed) and decline to embed third-party fonts.
How an opposing expert can verify
Open developer tools, Network tab, reload the page with cache disabled. Zero font requests should fire. grep the source for fonts.googleapis, fonts.gstatic, typekit. Zero matches.

2. Zero CDN

Inlined or local-served — no external assets of any kind

Requirement
No external CSS. No external JavaScript. No analytics scripts. No tracking pixels. No remote SVG icon libraries. Everything inlined or local-served.
Why it matters in litigation
A 2018 Bootstrap CDN URL no longer resolves in 2026. A jQuery script that loaded fine when an expert signed the report doesn't load when opposing counsel re-checks it in 2031. The exhibit either degrades silently (worst case — layout looks plausible but is wrong) or fails to render at all. Either way, the record is broken.
How CPP implements it
HTML artifacts inline all CSS in a <style> block. JavaScript, when present, is inlined or local-served from the same origin. No third-party calls of any kind. The cpm-engine.js runtime on /try is loaded from the same MCP server that serves the page.
How an opposing expert can verify
Disconnect from the internet. Open the file. Everything renders identically.

3. SHA-256 topology fingerprint

Deterministic hash of the canonical-form schedule, embedded in every output

Requirement
Every dashboard, every DOCX, every PDF carries a topology hash computed from the canonical-form schedule data. The hash is computed deterministically: same XER pair plus same engine version equals same hash, byte for byte.
Why it matters in litigation
Tamper detection. If a dashboard claims it was generated by cpm-engine v2.8.0 but its embedded hash doesn't match the v2.8.0 reference hash for that schedule pair, the artifact has been altered post-generation. Opposing counsel can prove it without access to the original file.
How CPP implements it
The CPM engine (cpm-engine.js, MIT, github.com/danafitkowski/cpp-cpm-engine) emits a manifest containing the topology hash. The hash appears in the DOCX footer, in the HTML dashboard's manifest panel, and in the FRE 707 disclosure exhibit. The SHA-256 of the engine itself is bit-identical-verifiable across the four deployment surfaces (npm package, Railway-hosted MCP, GitHub releases, local skill bundle).
How an opposing expert can verify
Run the same XER pair through the same engine version. Compare the topology hash. Identical input plus identical engine version equals identical hash.

4. Embedded provenance footer

Methodology documentation embedded in the artifact, not external

Requirement
Every output carries: engine_version, jurisdiction, working_days, holidays_observed, generation_timestamp, source_xer_filename, source_xer_sha.
Why it matters in litigation
FRE 702 reliability and proposed FRE 707 disclosure obligations both turn on methodology documentation. When methodology lives in a separate document that may or may not travel with the exhibit, the exhibit is vulnerable on Daubert grounds. When it's embedded in the artifact itself, the methodology is right there, every time.
How CPP implements it
Every HTML dashboard renders a manifest panel. Every DOCX/PDF renders a footer block. The fields are populated from the same engine manifest that emits the topology hash. No drift between artifact and methodology.
How an opposing expert can verify
Open any CPP artifact. The manifest is visible without scrolling past the analysis. The engine version listed in the artifact equals the engine version disclosed in the FRE 707 exhibit.

5. 10-year render stability

Plain HTML plus plain CSS plus minimal vanilla JavaScript — no frameworks

Requirement
Outputs are static HTML plus static CSS plus, when essential, minimal vanilla JavaScript. No React. No Vue. No Angular. No framework dependencies. No build step that bundles a 2026 framework version into the artifact.
Why it matters in litigation
A plain HTML file from 2008 still renders correctly in 2026. A 2018 React app that depends on React 16 and a deprecated build tool may already require a virtualized environment to view. The forensic record has to survive technology cycles. Plain HTML survives.
How CPP implements it
Every published artifact is plain HTML plus inlined CSS. When client-side interactivity is needed (the /try page's live CPM panel), it's vanilla JavaScript in the same file or a single sibling .js file from the same origin. No bundler. No transpilation step that hides the source.
How an opposing expert can verify
Right-click and view source. The file is human-readable. The CSS is in the <style> block. The JavaScript, if any, is plain ES5/ES2018 in a <script> block or referenced .js file. No minification that prevents reading.

6. Reproducibility manifest

Inputs sufficient to re-generate the artifact, documented in the artifact

Requirement
Every output documents inputs sufficient to re-generate it: source files, command-line arguments, engine version, jurisdiction calendar, deterministic seed values where applicable.
Why it matters in litigation
Independent verifiability is the floor of expert reliability. An exhibit that cannot be reproduced by an opposing expert running the same engine on the same data is, by definition, not reproducible.
How CPP implements it
Every artifact carries a manifest listing source XER filenames and SHA-256 hashes, the engine version, the jurisdiction-calendar identifier (e.g., US-FED 2026, ON 2026), and the generation timestamp. Monte Carlo outputs additionally carry the seed value used.
How an opposing expert can verify
Read the manifest. Run the engine. Get the same numbers.
This is a standard. CPP applies it to every output. Other vendors are welcome to adopt it. The CPM engine that drives these disciplines is open source at github.com/danafitkowski/cpp-cpm-engine — MIT.

See the discipline in action

Drop a baseline plus current XER into the live engine. Every output you get carries the topology hash, engine version, jurisdiction calendar, and reproducibility manifest. Zero CDN. System fonts only.

Try It Live →