Skip to content

Implementation plan

Companion to AUDIT.md. Finding IDs (CI-01, TST-03, ...) refer to the findings table there. Nothing in this plan is started. Each phase ends with a stop and a report, and the next phase begins only on approval.

Sizing. S under half a day, M 1 to 2 days, L 3 days or more, as relative effort, not a promise. One PR per logical change, Conventional Commits, never push to main.

Decisions I need from you

These change the plan, so I ask once here instead of in every phase. Defaults are what I will do if you do not answer.

# Question Default
Q1 What name should appear as author in pyproject.toml and LICENSE (now "contested-nav contributors"), and with which git identity should I commit? History will not be rewritten, so older commits stay under the existing name. Keep metadata as is until you answer.
Q2 CONSTRAINTS.md S4 says "No employer or defence-sector framing in any public artefact", yet docs/defense/ exists and the README links it. Amend S4 to match the positioning you want (my suggestion: "no employer framing; defense relevance is discussed only in docs/defense/, unclassified and source-cited")? Amend as suggested, in its own PR.
Q3 The existing docs contain 407 em dashes. Rewrite only the files I touch, or every file? Rewriting everything produces a large, low-value diff. Only files I touch.
Q4 docs/architecture/demo.html is 11 MB. Regenerate it smaller, or remove it from git and attach it to a release? Regenerate under about 1 MB if feasible, otherwise move to a release.
Q5 Replace the hand-written docs/index.html with an MkDocs Material site (your Phase 4)? This couples to scripts/check_doc_tables.py, which currently verifies cells inside docs/index.html, so the checker must be updated first. Yes, with the checker ported in the same PR.

Mapping to the attached audit's tasks

Audit task Where it lands Change from the audit
T-01 stabilise baseline Phase 1A Reframed: the real blocker is a red main, not stray files. No secret in the tree, key rotated.
T-02 harden local and CI gates Phase 3 Adds the demo-test fix first. Local ruff is currently failing.
T-03 requirements matrix Phase 5 Extend the existing SRS identifiers and add a checked link to tests. No parallel REQ-SYS scheme.
T-04 interface contracts Phase 2 Config and result-JSON schema doc, generated from the typed config.
T-05 scenario harness, fault docs Phase 2 Scenarios and fault injection already exist (configs/, degrade/). Adds an FMEA-lite doc and the outage-timing sweep.
T-06 security scanning, SBOM Phase 3 CodeQL and Dependabot already exist. Adds dependency review, pip-audit, SBOM, SHA pins.
T-07 README rewrite Phase 4 As specified.
T-08 PM package Phase 5 WBS, RAID, readiness assessment, decision log. Trade study exists already.
T-09 release v1.0.0 Phase 5 Target changed to v0.2.0. The project is Alpha and ships its headline feature disabled.
T-10 interview package Phase 6 As specified.

Phase 1: stabilise, then clean up

1A. Quick wins (unblock main)

PR Items Size Acceptance
1 TST-01, TST-02, CI-02: demo tests generate into tmp_path; add artifacts/ to .gitignore; fix 33 ruff findings; format S A fresh clone passes pytest with 0 failures; ruff check, ruff format --check, mypy clean; all 7 CI jobs green on the PR
2 DOC-01, 03, 04, 05, 06: correct false and stale statements (test counts, 99.3%, ROADMAP Track C, CONSTRAINTS B2 and B3, SRS wording) S check_doc_tables.py passes; every number quoted has a command beside it
3 SEC-02, SEC-04: pin actions to SHAs with version comments; fix two contradictory comments S CI green; Dependabot still proposes updates
4 SEC-05, SEC-06, REPO-05, CODE-02, PM-02: neutral platform wording, S4 amendment (Q2), author metadata (Q1), name the 225.0 constant, index the old audit snapshots in docs/audit/README.md (not moved, to keep inbound links valid). Delivered as three PRs, plus the index in this PR S No weapon-class platform named; the index explains the snapshots

After PR 1 is merged and main is green, merge Dependabot PR 5 (ruff 0.16.10, mypy 2.4.0) if CI passes with it.

1B. Refactor and performance (behaviour preserving)

Dependencies: 1A PR 1.

ID Work Size Depends on Acceptance
P1-1 TST-03: golden snapshot test of the full benchmark output (timing fields stripped) and of both sweeps at 3 seeds S PR 1 Fails when any metric changes in the 6th significant digit; passes on 3.11, 3.12, 3.13
P1-2 CODE-01: split _update into gate, inflate, cross-check and apply steps M P1-1 Golden test unchanged, bit for bit; coverage ratchet holds
P1-3 CODE-03: split fdir_manager.py along its existing seams M P1-1 As above
P1-4 REPO-01, REPO-02: navkit console entry point (run, sweep, figures) wrapping existing script logic; use uv.lock in CI or delete it M P1-1 navkit run --case outage_visual reproduces the README row; old script paths still work
P1-5 PERF-01: benchmarks/ script and docs/PERFORMANCE.md with measured before numbers; optimise trajectory interpolation only if the measurement justifies it M P1-1 Before and after numbers from the committed script, on the same machine and Python version, with variance reported

Risks. A refactor shifting a number silently (mitigated by P1-1). The audit found no algorithmic bottleneck, so I will not promise a speedup; if the measured gain is small, the performance doc will say that.

Phase 2: simulation quality

Much of this phase already exists: seeded and deterministic runs, 7 named scenarios in configs/benchmark.yaml, NEES, coverage and ATE metrics, bootstrap intervals, a 10-seed and an 8-scene sweep, and noise, dropout and fault injection in degrade/. I propose no new realism features. The work is the gaps.

ID Work Size Depends on Acceptance
P2-1 Hypothesis property tests: covariance symmetry and PSD, rotation orthonormality, no NaN, NEES non-negativity M P1-1 Tests run in CI under a fixed Hypothesis seed profile, under 60 s added
P2-2 Outage start and duration sweep (closes the open item at README.md:411), with bootstrap intervals and a results CSV M P1-4 One command writes the table and figure; CI runs a reduced version twice and diffs
P2-3 SIM-01: macOS and Windows test legs with a documented tolerance policy for floating point M PR 1 Matrix green; any tolerance is justified in an ADR
P2-4 Model assumptions page: units, frames, time stepping, seeding, limits. Config and result-JSON contract generated from the typed config (T-04). FMEA-lite for the fault modes already implemented M none Every config key has a unit and default shown; checked against EskfConfig by a test
P2-5 Visuals: one hero figure, a short GIF or MP4 under 5 MB, consistent palette, regenerated by one command; resolve REPO-04 per Q4 M P1-4 navkit figures rebuilds every committed image; sizes listed in the PR
P2-6 "Limitations and path to real systems" section: how the interfaces would map to ROS 2 topics and where the sim-to-real gap sits. A note only, since the roadmap marks a ROS bridge out of scope S none Reviewed against docs/defense/LIMITATIONS.md for consistency

Acceptance for the phase. One command regenerates every figure and table in the docs from scratch, and CI fails if the committed copies differ.

Phase 3: CI and quality gates

Existing: ci.yml (7 jobs), codeql.yml, pages.yml, dependabot.yml. Baseline CI wall time from the last green run on main (78df5df, run 36775590074, workflow dispatch): about 11 minutes end to end; the three test jobs took roughly 1 to 2 minutes each in the failing run for ef23a72.

ID Work Size Acceptance
P3-1 .pre-commit-config.yaml mirroring CI (ruff, ruff format, mypy), Makefile (install test lint docs bench demo repro), Dockerfile or devcontainer M make install && make test works from a fresh clone and in the container
P3-2 security.yml: dependency review on PRs, scheduled pip-audit, secret scan including a custom rule for the freellmapi- key shape, CycloneDX SBOM as an artifact M Workflows green; a test PR adding a known-vulnerable pin fails dependency review
P3-3 Governance files: CODEOWNERS, PR template, three issue templates (bug, feature, roadmap item), CODE_OF_CONDUCT, updated CONTRIBUTING and SECURITY, CHANGELOG kept in Keep a Changelog format S Files present; templates render in the GitHub UI
P3-4 Link checker in CI for README and docs S Fails on a deliberately broken link in a test PR
P3-5 Branch protection recommendation as exact settings, for you to apply S Written in CONTRIBUTING.md; I change no repository setting
P3-6 Coverage: keep the project's tracer-based ratchet (constraint S1 forbids pytest-cov). No coverage badge unless a live source for it exists S Ratchet runs in CI; badge decision recorded

Demonstrating the gates. I will open a throwaway PR containing one deliberate lint error and one deliberate failing test, show the red checks, and close it unmerged. I will ask before opening it.

Phase 4: README, docs site, GitHub Pages

Depends on Phase 2 (hero figure, repro command) and Phase 3 (live badges).

ID Work Size Acceptance
P4-1 README rewrite to the structure you specified. Headline result and hero figure in the first screen. Short "Scope and responsible use" section. Only live badges (CI, license, Python versions, docs) M A 60-second read yields problem, result and limit; every number passes check_doc_tables.py; quickstart timed from a fresh clone and recorded
P4-2 MkDocs Material site (Q5): Getting Started, Concepts, Scenarios, API reference from docstrings, Evaluation, Performance, Roadmap, ADRs, Risks, FAQ, Changelog. Dark and light, Mermaid, copy buttons. Port check_doc_tables.py first L mkdocs build --strict passes; deployed to Pages by workflow; link checker green
P4-3 ADRs: 8 exist. Add two: determinism and seeding policy; CI and supply chain strategy S Standard ADR format, linked from the site
P4-4 Social preview image (1280x640) in docs/assets/, plus exact repo description and topics text for you to set S Image under 300 KB; text delivered in the phase report

Not verifiable from here. Whether Pages is currently live and which source it uses. I will check the settings page with you or via the workflow deployment URL.

Phase 5: roadmap, program layer, features, release

ID Work Size Acceptance
P5-1 Restructure ROADMAP.md into Now, Next, Later with a stated prioritisation framework (RICE or WSJF, inputs shown, no invented precision). Create labelled issues and milestones, and a board if the token allows. Ask before creating more than 15 issues M Every roadmap item links to an issue and every issue to a roadmap line
P5-2 docs/RISKS.md (RAID log), WBS, decision log, success metrics definition. A technology-readiness table only with evidence-backed levels, written conservatively M Each risk has likelihood, impact, mitigation, owner and status; reviewed with you
P5-3 Traceability check: SRS requirement IDs mapped to tests, enforced by a script in CI M CI fails if a requirement ID has no test or declared gap
P5-4 Implement the top 2 to 3 features (agree after seeing the RICE table). Candidates below L each Each has an ADR first, tests, docs, changelog, one PR, linked issue
P5-5 Release v0.2.0 with notes from the changelog, SBOM attached, after your approval S Tag and release notes match the changelog

Feature candidates. Chosen from items the repo itself already names, and excluding what it declares out of scope (ROS, learned models, real drivers).

Candidate Source Value Risk
Stochastic cloning spike for B1, behind a flag, with go/no-go AUDIT.md, ROADMAP.md Track B Only path to the headline fix May miss the gate; see audit section. Outcome is evidence either way
Make the ADR-0008 frozen-anchor cross-check reachable (N1) README.md:397, audit snapshot Closes a documented security gap Interacts with ADR-0007 hysteresis
Classify fault cause: multipath, spoofing, degradation ROADMAP.md:198-203 Moves FDIR from detection to diagnosis Needs measured detection and false-alarm rates

Phase 6: cold review

Fresh clone, follow only the README, record time to first demo; check CI, Pages, links, leftover debris; write docs/audit/FINAL_REPORT.md with before and after metrics; the 2-minute pitch and 10 interview questions grounded in the repo.

Plan risks

Risk Likelihood Impact Mitigation
Refactor changes a number Medium High P1-1 golden test lands first and gates every refactor PR
check_doc_tables.py couples to README and docs/index.html structure, so a docs rewrite breaks it High Medium Port the checker before the rewrite (Q5)
macOS and Windows floating-point differences make the matrix flaky Medium Medium Tolerance policy in an ADR; compare derived metrics, not raw bytes
B1 spike consumes the schedule Medium Medium Time-box, define the gate in advance, keep behind a flag
Large doc diffs from style changes bury real changes Medium Low Q3 default: rewrite only touched files
Residual key in history is found by a scanner Low Low Key is rotated; add a custom scan rule so it is flagged knowingly, not silently
Pages or repo settings differ from what the workflows assume Medium Low Verify with you in Phase 4