feat(v0.9.0): author grounded first-corpus test plans (PR #2) - #121
Conversation
Guided Fault Finding cycle, slice 2 of 5 (Tier A, data-only). 11 branching test plans under community/testplans/, every step cited to an in-repo source (opinions / oracle / stories / research dim01+dim04 / TECH_SPECS): 2A82, 29E0, 29E1, 29E2, 30FF, 29CC, 2E81, 2E82, P0171, P0300, P0420. - P0171 uses the N55/S55 fuel-trim DIDs 0x1201 (LTFT) / 0x1202 (idle adaptation) from TECH_SPECS § 5 for did-measurement steps. - P0420 ends at 'diagnose the leak or the cat' — readiness-monitor masking is a permanent exclusion (v0.9.0 plan). - Coolant-pump plans (2E81/2E82) never auto-fire a write; activation hands off to the service-function UI. - docs/testplans.md: corpus table + known-missing list (2A99, wastegate 30FF branch, P0011/P0014, P0087, P0128, VANOS timing family). All 11 pass shipped_testplans_branch_integrity; lint-toml clean (35 files); data-only, no production code change.
|
ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d27981247d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| measurement = { kind = "manual", question = "Does 29E2 return after the drive cycle?" } | ||
| on_pass = "s4" | ||
| on_fail = "s5" |
There was a problem hiding this comment.
Route returning 29E2 to the failure branch
For the case where the user answers yes to Does 29E2 return after the drive cycle?, the plan currently goes to s4, whose conclusion says the fault did not return; a no answer goes to s5, which says the code returns. This reverses the diagnostic outcome and will tell users to monitor an unresolved recurring sensor fault instead of replacing/escalating it.
Useful? React with 👍 / 👎.
| measurement = { kind = "did", did = "0x1201", label = "Long-term fuel trim (Bank 1)", expected_min = -10.0, expected_max = 10.0 } | ||
| on_pass = "s2" | ||
| on_fail = "s3" | ||
| source = "docs/TECH_SPECS.md" |
There was a problem hiding this comment.
Point fuel-trim sources at the in-repo spec
This source path does not exist in the repo (TECH_SPECS.md is at the repository root, not under docs/), and the same bad path is used again for s5. Because the schema's honesty contract says each step source must point at an in-repo file, these P0171 steps will have broken citations/cross-links once source validation or the loader consumes them.
Useful? React with 👍 / 👎.
| [[step]] | ||
| id = "s3" | ||
| instruction = "No vacuum leak found. Read fuel rail pressure under load and compare against the expected rail-pressure range for the engine. A failing HPFP drops rail pressure under high demand." | ||
| measurement = { kind = "did", did = "0x5AC3", label = "Fuel rail pressure", expected_min = 40.0, expected_max = 200.0 } |
There was a problem hiding this comment.
Use the profiled rail-pressure DID
The N55 live-data profile exposes HPFP rail pressure as did:44F0 (community/profiles/n55.toml lines 147-152), while the cited research marks 22 5AC3 as low-confidence/not found in fetched OBDb repos (research/bmw_diag_dim04_uds_dids.md lines 402-427). When the walkthrough deep-links DID measurements into Live Data, this 29E0/29E1/29E2 branch will send users to an unprofiled rail-pressure DID instead of the shipped one, so the measurement may be unavailable even on the target N55 profile.
Useful? React with 👍 / 👎.
| [[step]] | ||
| id = "s1" | ||
| instruction = "Read long-term fuel trim (Bank 1). A large positive trim means the DME is adding fuel to compensate for unmetered air or a fuel shortfall. On N55/S55, LTFT is DID 0x1201. (On other engines use the standard OBD-II fuel-trim PID.)" | ||
| measurement = { kind = "did", did = "0x1201", label = "Long-term fuel trim (Bank 1)", expected_min = -10.0, expected_max = 10.0 } |
There was a problem hiding this comment.
Scope fuel-trim DIDs to N55/S55 plans
When this generic P0171 plan is shown for non-N55/S55 profiles, the first step can only deep-link to UDS DID 0x1201; the instruction mentions a standard OBD-II fallback, but the schema stores only this did measurement. The shipped profiles explicitly omit 1201/1202 outside the N55/S55 family (for example community/profiles/b48.toml lines 24-26), so users on those generic lean-code cases will be blocked before the smoke-test branch.
Useful? React with 👍 / 👎.
| measurement = { kind = "manual", question = "Is the downstream O2 sensor switching abnormally (mirroring the upstream sensor)?" } | ||
| on_pass = "s4" | ||
| on_fail = "s5" |
There was a problem hiding this comment.
Diagnose mirroring post-cat O2 as catalyst failure
In the no-exhaust-leak path, a downstream O2 trace that mirrors the upstream sensor is the failed catalyst-efficiency symptom this DTC is about, but on_pass sends that answer to s4, which tells the user to replace a lazy downstream sensor; on_fail then condemns the catalyst when the sensors are described as switching correctly. This swaps the two outcomes and can make users replace the sensor before diagnosing the cat.
Useful? React with 👍 / 👎.
| measurement = { kind = "manual", question = "Is the sensor connector/wiring damaged or corroded?" } | ||
| on_pass = "s4" | ||
| on_fail = "s5" | ||
| source = "community/dtc_texts.toml" |
There was a problem hiding this comment.
Cite an actual procedure for wiring inspection
For the path where the 29E1 pressure signal reads plausibly, this step asks the user to inspect connector pins and wiring damage, but the cited file only contains the label 29E1 = "Fuel pressure sensor signal" (community/dtc_texts.toml line 111), not a connector or harness procedure. That violates the source rule these plans are meant to enforce, so this diagnostic action remains ungrounded even though the source field is non-empty.
Useful? React with 👍 / 👎.
| [[step]] | ||
| id = "s3" | ||
| instruction = "No vacuum leak found. Read fuel rail pressure under load and compare against the expected rail-pressure range for the engine. A failing HPFP drops rail pressure under high demand." | ||
| measurement = { kind = "did", did = "0x5AC3", label = "Fuel rail pressure", expected_min = 40.0, expected_max = 200.0 } |
There was a problem hiding this comment.
Normalize rail-pressure thresholds to live-data units
These rail-pressure thresholds appear to be in bar (40–200 bar), but the shipped N55 rail-pressure channel is displayed in MPa with a 0–25.5 range (community/profiles/n55.toml lines 147-154). When the walkthrough compares the decoded live-data value, a normal 5–20 MPa reading would fall below this 40.0 minimum and incorrectly send the user to the HPFP-failure branch.
Useful? React with 👍 / 👎.
ROADMAP v0.9.0 'Guided Fault Finding' moves Planned -> In progress. PRs #1/#2/#3/#4 (#120/#121/#122/#123) marked Done; PR #5 (validation harness + contribution path) remains Ready/Not yet dispatched. Footer refreshed to 2026-07-19. Doc-only, no code change. Tier A per CLAUDE.md. Co-authored-by: hermes-agent <ohgeeceee@users.noreply.github.com>
v0.9.0 "Guided Fault Finding" — slice 2 of 5 (Tier A, data-only)
Authors the first grounded corpus of branching test plans against the PR #1 schema. Zero code changes — every file is a
community/testplans/*.tomlplan or a doc, so it lands autonomously perCLAUDE.mdTier A.11 plans, every step sourced in-repo
Honesty guardrails (v0.9.0 plan "What we will NOT do")
[UNVERIFIED]gating.docs/testplans.mdlists 2A99, the 30FF wastegate branch, P0011/P0014, P0087, P0128, and the VANOS timing family as ungrounded rather than shipping stub plans.Verification
shipped_testplans_branch_integrity— all 11 plans pass (branches resolve, a conclusion is reachable froms1, every step sourced, dtc==filename, acyclic).node scripts/lint-toml.js— clean, 35 files.cargo test/node --test/ pytest counts unchanged.Protected paths
None.