Skip to content

feat(v0.10.0): plan verification badge in walkthrough header (Tier A) - #127

Merged
ohgeeceee merged 1 commit into
mainfrom
feat/v0.10.0-plan-verified-badge
Jul 19, 2026
Merged

feat(v0.10.0): plan verification badge in walkthrough header (Tier A)#127
ohgeeceee merged 1 commit into
mainfrom
feat/v0.10.0-plan-verified-badge

Conversation

@ohgeeceee

Copy link
Copy Markdown
Owner

Summary

v0.10.0 — Plan verification badge (Tier A frontend + data loader). Completes the data contract PR #5 installed: the meta.verified marker in community/testplans/*.toml now flows all the way to the walkthrough header as a badge.

This PR is Tier A — frontend + an additive change to the non-protected testplans.rs data loader. No protected paths (transport/protocol/commands.rs) touched.

What it does

  • The walkthrough panel header now shows a badge based on each plan's meta.verified:
    • NEEDS VERIFICATION (amber) — the default "needs verification" state every plan ships with.
    • ✓ Verified (green) — once a real-car harness walk upgrades it (docs/validation/testplans.md).
    • No badge when the marker is absent (legacy/unknown plans).

Structure

Rust (src-tauri/src/testplans.rs) — additive:

  • PlanMeta gains verified: Option<String>; TestPlan gains verified: Option<String>; to_plan threads it through. No deny_unknown_fields, so plans without the marker still parse as None.
  • parse_roundtrip_maps_all_fields now asserts the marker threads through; shipped_testplans_branch_integrity and shipped_corpus_loads still green.

UI (src/js/main.js, src/index.html, src/css/app.css):

  • loadTestPlan reads plan.verified and renders #walkthrough-verified; plan_verified_state() maps the TOML string to label + class. Light + dark themes, matching the existing .unverified-tag amber convention.

Verification

  • cargo test --lib testplans5 passed (parse roundtrip, did range, shipped corpus load, case-insensitive query, branch-integrity gate).
  • node --test src/js/test/*.test.cjs56 passed (unchanged).
  • node scripts/lint-toml.js → 0 problems (35 files).
  • node --check src/js/main.js → exit 0.

Files

src-tauri/src/testplans.rs   | +verified field on PlanMeta + TestPlan, threaded via to_plan; test assertion
src/js/main.js              | loadTestPlan badge render + plan_verified_state()
src/index.html              | #walkthrough-verified span in the walkthrough head
src/css/app.css             | .walkthrough-verified (light + dark, unverified/verified)
CHANGELOG.md                | 0.10.0 section

Completes the data contract PR #5 installed: the plan's meta.verified marker now flows end-to-end and renders as a badge.

Rust (src-tauri/src/testplans.rs, additive, non-protected data loader):
- PlanMeta gains verified: Option<String>; TestPlan gains verified: Option<String>; to_plan threads it through. Legacy plans with no marker parse as None and render no badge.
- parse_roundtrip test asserts the marker threads through; shipped corpus + gate tests still green.

UI (src/js/main.js, src/index.html, src/css/app.css):
- loadTestPlan reads plan.verified and renders a header badge: NEEDS VERIFICATION (amber, default) or ✓ Verified (green). Absent marker => no badge. Light + dark themes.
- plan_verified_state() maps the TOC string to label+class.

CHANGELOG: 0.10.0 section.

Tier A (frontend + data loader; no protected path). Verification: cargo test testplans (5/5), node --test (56), lint-toml (0 problems).
@ecc-tools

ecc-tools Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR.

@ohgeeceee
ohgeeceee merged commit ec01b5b into main Jul 19, 2026
10 of 11 checks passed
@ohgeeceee
ohgeeceee deleted the feat/v0.10.0-plan-verified-badge branch July 19, 2026 15:18

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 914ff145d7

ℹ️ 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".

Comment thread src/js/main.js
// default on every plan; "verified" only after a real-car harness walk
// (docs/validation/testplans.md). Absent => no badge (pre-PR-#5 plans).
if (verifiedEl) {
const v = plan_verified_state(plan ? plan.verified : undefined);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Move badge rendering after the plan lookup

When any DTC row is clicked, this expression reads plan, but that binding exists only inside the later try block. It therefore throws ReferenceError: plan is not defined before get_test_plan is invoked and outside the error handler, causing loadTestPlan (and the surrounding Promise.all) to reject while the walkthrough remains stuck. Render the badge after the awaited plan has been retrieved.

Useful? React with 👍 / 👎.

Comment thread CHANGELOG.md
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
## [0.10.0]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep these changes unreleased until versions are bumped

Changing the heading to 0.10.0 declares these accumulated changes released, but package.json, src-tauri/Cargo.toml, src-tauri/tauri.conf.json, and the application entry in Cargo.lock all still identify the product as 0.6.0 (as does the README's latest-release section). Consequently, any artifact built from this commit is still packaged and reported as 0.6.0 despite the changelog claiming 0.10.0, which can break release identification and updater version comparisons. Retain the Unreleased heading here or perform the repository's standard coordinated release-version bump.

Useful? React with 👍 / 👎.

ohgeeceee added a commit that referenced this pull request Jul 19, 2026
Cargo.toml, package.json, and tauri.conf.json all still said 0.6.0 while the actual release line is at v0.9.0 (Guided Fault Finding, 5/5 slices merged) and v0.10.0 (plan verification badge, PR #127). Bumps the three build-version strings to 0.10.0 so the produced MSI/NSIS bundles carry the correct label. No code change.

Verified: npm run build compiles clean and now emits BeeEmUu_0.10.0_x64 bundles. Tier A (config-only).

Co-authored-by: hermes-agent <ohgeeceee@users.noreply.github.com>
ohgeeceee added a commit that referenced this pull request Jul 19, 2026
v0.10.0 follow-up to the plan verification badge (#127).

- The NEEDS VERIFICATION badge now opens the real-car validation harness doc (docs/validation/testplans.md) on click — the procedure to upgrade a plan. VERIFIED shows a static green tag. Uses the app's existing external-link pattern (window.open target=_blank noopener).
- Fixes a latent TDZ bug from #127: loadTestPlan previously read plan.verified before the plan was resolved (ReferenceError at runtime; unit tests never exercised loadTestPlan). The badge now renders after get_test_plan resolves, via a new renderPlanVerifiedBadge() helper.
- plan_verified_state() now carries the harness href + tooltip.
- Fixed the about modal's stale repo owner (ohjoncurrie -> ohgeeceee, the canonical owner confirmed via git remote + gh repo view + gh pr view).

Tier A. Verified: npm run build compiles clean; node --check main.js OK; node --test 56 pass.

Co-authored-by: hermes-agent <ohgeeceee@users.noreply.github.com>
ohgeeceee added a commit that referenced this pull request Jul 22, 2026
…147)

* feat(v0.12.0): recurring-DTC callout under the fault table (slice 5)

Slice 5 of v0.12.0 Fault Memory (docs/v0.12.0_plan.md):
the 'headline UI moment of the cycle'. After a successful DTC read,
if the local history has past occurrences of any code the user
just saw, surface a 'seen before' banner under the fault table.

Pure frontend Tier A — no Rust / commands.rs / transport / protocol
change.

Frontend:
  - New src/js/recurring_dtc.js pure-data module. computeCallout(
    currentDtcs, history, nowMs) returns either null (no banner)
    or a sorted list of CalloutEntry rows {code, occurrences,
    last_seen_iso, last_seen_human, first_seen_iso, first_seen_human,
    same_address}. Default lookback is 14 days. Multiple buckets for
    the same code across addresses collapse into one row with summed
    occurrences. Entries older than the window are filtered out.
    Includes a relativeTimeLabel helper (today / yesterday / Nd ago
    / YYYY-MM-DD) that prefers day-relative labels over hour-relative
    ones for the same-UTC-day case.
  - main.js renders the callout: renderHistoryCallout(dtcs) queries
    the history via window.beeemuuDtcHistory.queryDtcHistory(vin, null),
    hands the summary + current DTCs to computeCallout, and toggles
    a #fault-history-callout div under the fault table. Best-effort:
    any failure hides the banner silently rather than breaking the
    DTC read flow. Empty reads skip the query entirely.
  - index.html: new <div id="fault-history-callout" class="hidden">
    with a <ul id="fault-history-callout-list"> for the entries, plus
    the new <script src="js/recurring_dtc.js"> tag.
  - src/css/app.css: amber callout styling (matches the NEEDS
    VERIFICATION badge palette from v0.10.0 #127 so the visual
    language stays consistent: 'this needs your attention').

Tests: 26 new unit tests under node --test covering empty inputs,
no-match cases, 14-day window filter, custom windowMs override,
multi-address aggregation (same code, different modules collapses
into one row with summed occurrences), most-recent-last_seen
selection across buckets, same_address flagging, sort order,
unparseable timestamps, and the relativeTimeLabel helper's edge
cases (just now / Nm ago / today / yesterday / Nd ago / YYYY-MM-DD).
Caught + fixed 1 bug in my own implementation during the test
loop (skill #4 verify-then-claim): the original priority order
returned '11h ago' for an 11-hour-old timestamp on the previous
UTC day, but 'yesterday' carries more information. Fixed the
priority so day-relative labels take precedence over hour-relative
labels, and updated the corresponding test.

Verification:
  - node --check on all changed files: pass.
  - node --test 'src/js/**/*.test.js' 'src/js/**/*.test.cjs': 148
    pass, 0 fail (was 122 before this PR — the 26 new recurring_dtc
    tests).

Tier A — frontend only, no protected paths. Self-merge when CI
green.

* fix(v0.12.0): make DTC history commands async + spawn_blocking

PR #144's three new commands (record_dtc_read, query_dtc_history,
clear_dtc_history) shipped sync. The static allowlist test
(tests/async_commands.rs) caught this on PR #147's CI run: the
project invariant from CLAUDE.md §4 is 'any #[tauri::command]
that touches serial or network transport MUST be async fn, or
offload via spawn_blocking' — and the explicit allowlist is for
purely-local commands like export_text (grandfathered). New
commands that touch disk should follow the project direction,
not the grandfather.

Converting to async + spawn_blocking:
  - record_dtc_read -> async, spawn_blocking wraps
    record_dtc_read_impl. Per-line append is microseconds; the
    spawn_blocking cost is amortised over the whole batch.
  - query_dtc_history -> async, spawn_blocking wraps
    query_dtc_history_impl.
  - clear_dtc_history -> async, spawn_blocking wraps
    clear_dtc_history_impl.

The _impl fns stay sync (and the unit tests still pass against
them directly), matching the same pattern as discover_enet_targets
in commands.rs.

The JS-side wrapper (src/js/dtc_history.js) and the rest of
slice 5 (recurring_dtc.js, main.js wiring) are unchanged. The
wire surface from the renderer's perspective is identical — the
only difference is that the IPC call returns a Promise that
resolves after the spawn_blocking thread finishes.

Verification:
  - cargo test --lib: 124 passed, 0 failed.
  - cargo test --test async_commands: 1 passed, 0 failed
    (only_allowlisted_commands_may_be_sync now passes).
  - Full cargo test: 124 + 1 + doc-tests, all green.
  - npm run build: clean (MSI + NSIS bundles built).

No frontend changes — this is a Tier B fix on the slice 2
commands only, keeping the v0.12.0 Tier B surface area
minimal.

---------

Co-authored-by: Jon currie1 <ohgeeceee@users.noreply.github.com>
github-actions Bot pushed a commit that referenced this pull request Jul 29, 2026
…der claim (#182)

Two small doc-rot fixes from the same audit that found
the v0.15.1/v0.16.0/v0.16.3/v0.16.5 false claims in the
forward roadmap (PR #181):

1. community/testplans/README.md:33 — 'UI rendering lands
   in a follow-up' was wrong. The walkthrough verification
   badge is shipped in the desktop app (src/js/main.js
   renderPlanVerifiedBadge, PR #127) and in the standalone
   walkthrough HTML bundle (src/js/walkthrough_bundle.js
   buildBundleHtml, PR #127/#130). The README now points
   at both rendering sites.

2. community/freeze/README.md:68 — the reference to
   'docs/validation/freeze-frame.md harness (planned
   v0.14.1)' was stale: the doc didn't exist. v0.14.1
   shipped without it. This PR ships the missing harness
   doc + updates the README reference.

The new docs/validation/freeze-frame.md mirrors the
n62-real-car.md (PR #178) and can-broadcast.md (PR #164)
shape: 5 steps, copy-pasteable GitHub issue template, a
'Verification results' closeout, and explicit
cross-references. The per-ECU schema format (offset,
width, scale, bias) is already documented in
community/freeze/README.md and referenced verbatim.

The DME/DSC/FRM freeze-frame byte-0..2 convention (engine
speed u16 BE + coolant byte - 40) is the only portion
that's shared across all three simulator fixtures and
chassis-validated today; offsets 3-8 remain unverified
and the harness doc is explicit about the
'do-not-invent-meaning' discipline.

Tier A, no test impact, no code changes. Auto-merge on
CI green per CLAUDE.md rule 2.

Co-authored-by: ohgeeceee <ohgeeceee@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant