From b764760b5651e88bd844897ae3d9996bdb96fbad Mon Sep 17 00:00:00 2001 From: "David E. Weekly" Date: Fri, 18 Sep 2026 14:01:38 -0700 Subject: [PATCH 1/5] docs: scope README branding and measured coverage badges --- docs/NEXT-SPRINT.md | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/docs/NEXT-SPRINT.md b/docs/NEXT-SPRINT.md index 1aec2e0..777a29e 100644 --- a/docs/NEXT-SPRINT.md +++ b/docs/NEXT-SPRINT.md @@ -1,7 +1,19 @@ -# Sprint checkpoint +# README identity and coverage contract -No new feature implementation is authorized by this checkpoint. +Add the existing project logo and truthful CI, Codecov, release, and license badges +to the README. Supply Codecov with measured Linux workspace test coverage, including +the CLI subprocesses exercised by the oracle suite. -Select the next researcher outcome from [ROADMAP.md](../ROADMAP.md) and record a -new contract before beginning it. No supported-target promotion or 1.0 release is -authorized here. +Scope: `README.md`, `CONTRIBUTING.md`, `CHANGELOG.md`, this checkpoint, +`.github/workflows/coverage.yml`, and `scripts/coverage.sh`. Reuse `site/logo.png`, +the pinned Rust toolchain, official compiler installer, and existing tests. + +Use a separate coverage workflow on hosted Linux, with path filters and a job timeout. +Do not change existing correctness gates, release publication, product behavior, or +support claims. Coverage is a development metric, not semantic qualification. + +Evidence: render the README; resolve badge/image targets; lint the workflow and shell; +run the coverage command against a clean candidate with the required compilers; verify +a nonempty report includes CLI and library sources; verify Codecov accepts the upload; +require existing aggregate CI. Do not substitute an invented percentage for a missing +report. Stop after integration and verification of the README and coverage badge. From 9a5291a7d2205864ead07bb6435aefd3ac7c00e6 Mon Sep 17 00:00:00 2001 From: "David E. Weekly" Date: Fri, 18 Sep 2026 14:03:53 -0700 Subject: [PATCH 2/5] Add README logo and badges with Rust coverage reporting --- .github/workflows/coverage.yml | 65 ++++++++++++++++++++++++++++++++++ CHANGELOG.md | 4 +++ CONTRIBUTING.md | 24 +++++++++++++ README.md | 23 +++++++++--- scripts/coverage.sh | 22 ++++++++++++ 5 files changed, 133 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/coverage.yml create mode 100644 scripts/coverage.sh diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 0000000..a5817d0 --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,65 @@ +name: Coverage + +on: + push: + branches: [main] + paths: + - 'crates/**' + - 'tests/**' + - 'scripts/**' + - 'Cargo.toml' + - 'Cargo.lock' + - 'rust-toolchain.toml' + - '.github/workflows/coverage.yml' + pull_request: + branches: [main] + paths: + - 'crates/**' + - 'tests/**' + - 'scripts/**' + - 'Cargo.toml' + - 'Cargo.lock' + - 'rust-toolchain.toml' + - '.github/workflows/coverage.yml' + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: coverage-${{ github.ref }} + cancel-in-progress: true + +jobs: + coverage: + name: Linux line coverage + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + toolchain: 1.97.1 + components: llvm-tools-preview + - name: Install cargo-llvm-cov + uses: taiki-e/install-action@4076c08d76dba979c11a7285295b0716c1d67908 # v2 + with: + tool: cargo-llvm-cov@0.9.1 + - name: Install official Lua compilers + run: bash scripts/install_ci_compilers.sh + - name: Measure workspace and CLI subprocess coverage + run: bash scripts/coverage.sh "${RUNNER_TEMP}/lcov.info" + - name: Retain coverage report + uses: actions/upload-artifact@v4 + with: + name: linux-coverage + path: ${{ runner.temp }}/lcov.info + if-no-files-found: error + retention-days: 7 + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: ${{ runner.temp }}/lcov.info + disable_search: true + fail_ci_if_error: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 596f30d..b0dee14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ is promoted to a supported tier and no interface carries a compatibility promise ## Unreleased +- Add the project logo and CI, Codecov, release, and dual-license badges to the README. + Publish measured Linux line coverage from the workspace suite and instrumented CLI + subprocesses through a separate coverage workflow. + - Delimit negative process-group IDs with `--` when the contributor tripwire invokes `kill`. Linux procps-ng could misparse the previous command and signal unrelated processes, including the CI runner. A signal-0 regression checks the target group diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 71a0000..9aaf326 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,6 +37,30 @@ update package metadata, CI evidence, release documentation, and the changelog t `scripts/check.sh` runs the aggregate repository checks. It is necessary before handoff, but it is not proof that oracle-backed claims are correct; each work package must also pass its canonical gate. +### Line coverage + +The separate [Coverage workflow](.github/workflows/coverage.yml) runs on hosted Linux +for code, fixture, toolchain, or coverage-workflow changes. It installs the required +official Lua compilers and runs the entire workspace test suite with LLVM +instrumentation, including the CLI subprocesses exercised by integration tests. +It uploads an LCOV report through `codecov/codecov-action@v5`, using the repository's +`CODECOV_TOKEN` Actions secret, and retains a copy as an Actions artifact. Upload +failures fail the coverage job rather than silently leaving stale data. + +For a local report, install the `cargo-llvm-cov` version pinned in that workflow, add +`llvm-tools-preview` to the repository's Rust toolchain with `rustup component add +llvm-tools-preview`, and run: + +```console +bash scripts/coverage.sh +``` + +The report is `artifacts/coverage/lcov.info`. It includes the CLI and libraries; +the `luad-oracle` tooling crate and cargo-llvm-cov's default test/dependency exclusions +are omitted from the report, while their tests still run. The badge measures Linux +line coverage, not branch coverage, semantic correctness, or supported-target status. +Coverage tooling is optional for contributors and does not change `scripts/check.sh`. + Dependency changes must also pass the pinned `cargo-deny` policy: ```console diff --git a/README.md b/README.md index 01eb090..a030380 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,17 @@ -# `luad` +

+ + luad: a smiling crescent moon inside a magnifying glass + +

+ +

luad

+ +

+ CI + Codecov coverage + Latest release + License: MIT OR Apache-2.0 +

`luad` reads compiled Lua bytecode and tells you what is in it: the exact format it was built for, the instructions, the constants, the closure bindings, and where every one of @@ -248,18 +261,18 @@ delete the document in the same change and update this index. | Document | Purpose | Fresh as of | Revalidate or delete when | |---|---|---:|---| -| [`README.md`](README.md) | What `luad` is, install, first commands, honest limitations, and the documentation index. | 2026-09-17 | Public scope, support status, setup, primary commands, or the documentation set changes. | +| [`README.md`](README.md) | What `luad` is, install, first commands, honest limitations, and the documentation index. | 2026-09-18 | Public scope, support status, setup, primary commands, or the documentation set changes. | | [`AGENTS.md`](AGENTS.md) | Binding repository instructions, product-batch boundaries, and safety constraints for coding agents. | 2026-08-27 | Development workflow, proof policy, current priority, or repository invariants change. | | [`ARCHITECTURE.md`](ARCHITECTURE.md) | Crate responsibilities, model boundaries, trust layers, and architectural invariants. | 2026-08-27 | Crates, ownership boundaries, core representations, or evidence layers change. | -| [`CHANGELOG.md`](CHANGELOG.md) | Backward-facing record of released and unreleased user-visible changes. | 2026-09-17 | Every user-visible change or release; never use it as a forward plan. | -| [`CONTRIBUTING.md`](CONTRIBUTING.md) | Contributor verification commands, test taxonomy, fixture provenance, and definition of done. | 2026-09-17 | Toolchain, test commands, gates, fixture policy, or contribution workflow changes. | +| [`CHANGELOG.md`](CHANGELOG.md) | Backward-facing record of released and unreleased user-visible changes. | 2026-09-18 | Every user-visible change or release; never use it as a forward plan. | +| [`CONTRIBUTING.md`](CONTRIBUTING.md) | Contributor verification commands, test taxonomy, fixture provenance, and definition of done. | 2026-09-18 | Toolchain, test commands, gates, fixture policy, or contribution workflow changes. | | [`PRD.md`](PRD.md) | Product users, firmware-tree workflows, factual analysis boundary, requirements, non-goals, and release outcomes. | 2026-09-06 | Product scope, target users, supported workflows, factual-analysis boundary, or product-level requirements change. | | [`ROADMAP.md`](ROADMAP.md) | Release completion boundary, future researcher outcomes, sequencing, and target support boundaries. | 2026-09-17 | Release scope, dependencies, parallel ownership, acceptance criteria, support boundaries, or exclusions change. | | [`SECURITY.md`](SECURITY.md) | Supported-version policy, the planned 1.0 target matrix, vulnerability reporting, and hostile-input threat model. | 2026-09-16 | Support policy, the planned target matrix, reporting channel, trust boundary, or threat model changes. | | [`docs/ROADMAP-1.0.md`](docs/ROADMAP-1.0.md) | The full qualification program a future 1.0 would need: milestones, evidence gates, target promotion, and release acceptance. | 2026-09-16 | The 1.0 destination, milestone order, release acceptance, or the qualification lifecycle changes. | | [`docs/BRINGUP.md`](docs/BRINGUP.md) | Setup for a developer machine, a self-hosted Actions runner, and a release builder, with the owning file for every tool pin. | 2026-09-02 | A tool pin, its owning file, the doctor's checks, runner labels or security boundary, or the release dry-run and rehearsal entry points change. | | [`docs/DEVELOPMENT-WORKFLOW.md`](docs/DEVELOPMENT-WORKFLOW.md) | Customer-outcome batches, separate product and qualification CI lanes, proportional evidence, process budgets, and agent orchestration. | 2026-08-27 | Planning artifacts, CI lanes, customer cadence, agent roles, evidence policy, process budgets, provider interfaces, or sprint-advance mechanics change. | -| [`docs/NEXT-SPRINT.md`](docs/NEXT-SPRINT.md) | No-feature-work checkpoint; select the next researcher outcome and contract separately. | 2026-09-17 | A stage replaces it with its contract: a qualification stage through a dedicated planning change, any other stage in the first commit of its own pull request. | +| [`docs/NEXT-SPRINT.md`](docs/NEXT-SPRINT.md) | No-feature-work checkpoint; select the next researcher outcome and contract separately. | 2026-09-18 | A stage replaces it with its contract: a qualification stage through a dedicated planning change, any other stage in the first commit of its own pull request. | | [`docs/EMBEDDED-FIRMWARE-REQUIREMENTS.md`](docs/EMBEDDED-FIRMWARE-REQUIREMENTS.md) | Present factual-tool requirements derived from the TP-Link/OpenWrt reverse-engineering use case. | 2026-08-27 | New corpus evidence changes target authority, fact boundaries, or workflows, or all unique requirements move into the PRD. | | [`docs/PRIOR-ART-AND-CORPORA.md`](docs/PRIOR-ART-AND-CORPORA.md) | External tools, datasets, and bytecode-emitting ecosystems evaluated against the product scope, candidate fixture sources with license and provenance constraints, and the fidelity gaps they expose. | 2026-09-06 | A listed project changes license or status, a candidate corpus or vendor profile is adopted or rejected, or the PRD prior-art table is revised. | | [`docs/MACHINE-INTERFACE.md`](docs/MACHINE-INTERFACE.md) | Machine formats, schemas, identities, commands, diagnostics, and exit behavior. | 2026-08-27 | Any public command, schema, record, stable ID, diagnostic, or exit contract changes. | diff --git a/scripts/coverage.sh b/scripts/coverage.sh new file mode 100644 index 0000000..e8c438c --- /dev/null +++ b/scripts/coverage.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "${repo_dir}" +report="${1:-${repo_dir}/artifacts/coverage/lcov.info}" +mkdir -p "$(dirname "${report}")" + +# Apply instrumentation to both the test executables and the CLI they spawn. +coverage_env="$(cargo llvm-cov show-env --sh)" +eval "${coverage_env}" +cargo llvm-cov clean --workspace +cargo build --locked -p luad-cli --bin luad +target_dir="$(cargo metadata --locked --no-deps --format-version 1 | jq -r .target_directory)" +export CARGO_BIN_EXE_luad="${target_dir}/debug/luad" +cargo test --locked --workspace +cargo llvm-cov report --lcov --exclude-from-report luad-oracle --output-path "${report}" + +test -s "${report}" +grep -Eq '^SF:.*crates/luad-cli/src/' "${report}" +grep -Eq '^SF:.*crates/luad-core/src/' "${report}" +grep -Eq '^LH:[1-9][0-9]*$' "${report}" From a20157bf4d16b19e4992786220090ffc1d5d1c49 Mon Sep 17 00:00:00 2001 From: "David E. Weekly" Date: Fri, 18 Sep 2026 14:04:34 -0700 Subject: [PATCH 3/5] docs: retain the no-feature checkpoint after README work --- docs/NEXT-SPRINT.md | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/docs/NEXT-SPRINT.md b/docs/NEXT-SPRINT.md index 777a29e..1aec2e0 100644 --- a/docs/NEXT-SPRINT.md +++ b/docs/NEXT-SPRINT.md @@ -1,19 +1,7 @@ -# README identity and coverage contract +# Sprint checkpoint -Add the existing project logo and truthful CI, Codecov, release, and license badges -to the README. Supply Codecov with measured Linux workspace test coverage, including -the CLI subprocesses exercised by the oracle suite. +No new feature implementation is authorized by this checkpoint. -Scope: `README.md`, `CONTRIBUTING.md`, `CHANGELOG.md`, this checkpoint, -`.github/workflows/coverage.yml`, and `scripts/coverage.sh`. Reuse `site/logo.png`, -the pinned Rust toolchain, official compiler installer, and existing tests. - -Use a separate coverage workflow on hosted Linux, with path filters and a job timeout. -Do not change existing correctness gates, release publication, product behavior, or -support claims. Coverage is a development metric, not semantic qualification. - -Evidence: render the README; resolve badge/image targets; lint the workflow and shell; -run the coverage command against a clean candidate with the required compilers; verify -a nonempty report includes CLI and library sources; verify Codecov accepts the upload; -require existing aggregate CI. Do not substitute an invented percentage for a missing -report. Stop after integration and verification of the README and coverage badge. +Select the next researcher outcome from [ROADMAP.md](../ROADMAP.md) and record a +new contract before beginning it. No supported-target promotion or 1.0 release is +authorized here. From 7c889df6c37f0c34941698c949bd17f4fe41e9d8 Mon Sep 17 00:00:00 2001 From: "David E. Weekly" Date: Fri, 18 Sep 2026 14:46:56 -0700 Subject: [PATCH 4/5] fix: use supported filename exclusion for LCOV reports --- scripts/coverage.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/coverage.sh b/scripts/coverage.sh index e8c438c..0537fd4 100644 --- a/scripts/coverage.sh +++ b/scripts/coverage.sh @@ -14,7 +14,8 @@ cargo build --locked -p luad-cli --bin luad target_dir="$(cargo metadata --locked --no-deps --format-version 1 | jq -r .target_directory)" export CARGO_BIN_EXE_luad="${target_dir}/debug/luad" cargo test --locked --workspace -cargo llvm-cov report --lcov --exclude-from-report luad-oracle --output-path "${report}" +cargo llvm-cov report --lcov \ + --ignore-filename-regex '(^|/)crates/luad-oracle/' --output-path "${report}" test -s "${report}" grep -Eq '^SF:.*crates/luad-cli/src/' "${report}" From e73f3dd68526c88ae534a573f9b2a77dbf48af35 Mon Sep 17 00:00:00 2001 From: "David E. Weekly" Date: Fri, 18 Sep 2026 14:54:39 -0700 Subject: [PATCH 5/5] Handle interrupted profiles from containment tests explicitly --- CONTRIBUTING.md | 3 +++ scripts/coverage.sh | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9aaf326..346065d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -59,6 +59,9 @@ The report is `artifacts/coverage/lcov.info`. It includes the CLI and libraries; the `luad-oracle` tooling crate and cargo-llvm-cov's default test/dependency exclusions are omitted from the report, while their tests still run. The badge measures Linux line coverage, not branch coverage, semantic correctness, or supported-target status. +Containment tests deliberately terminate child processes, so some coverage writes can +be incomplete. Report merging warns about invalid profiles and retains the valid ones; +it fails if none can be merged. Counters from interrupted processes may be absent. Coverage tooling is optional for contributors and does not change `scripts/check.sh`. Dependency changes must also pass the pinned `cargo-deny` policy: diff --git a/scripts/coverage.sh b/scripts/coverage.sh index 0537fd4..84fbaaf 100644 --- a/scripts/coverage.sh +++ b/scripts/coverage.sh @@ -14,8 +14,11 @@ cargo build --locked -p luad-cli --bin luad target_dir="$(cargo metadata --locked --no-deps --format-version 1 | jq -r .target_directory)" export CARGO_BIN_EXE_luad="${target_dir}/debug/luad" cargo test --locked --workspace +# Containment tests deliberately kill children, which can interrupt profile writes. +# Retain valid profiles; LLVM still fails if none can be merged. cargo llvm-cov report --lcov \ - --ignore-filename-regex '(^|/)crates/luad-oracle/' --output-path "${report}" + --failure-mode all --ignore-filename-regex '(^|/)crates/luad-oracle/' \ + --output-path "${report}" test -s "${report}" grep -Eq '^SF:.*crates/luad-cli/src/' "${report}"