Skip to content

Fix coverage source inventories and preserve nested c8 counters (re-land of #134 onto main) - #140

Merged
unbraind merged 2 commits into
mainfrom
fix/pm-ops-coverage-source-inventory-reland
Oct 4, 2026
Merged

unbraind merged 2 commits into
mainfrom
fix/pm-ops-coverage-source-inventory-reland

Conversation

@unbraind

@unbraind unbraind commented Oct 4, 2026 •

Copy link
Copy Markdown
Owner

Coverage scopes now derive a sorted unique source inventory and independently verify the package denominator. Each c8 invocation isolates its counters/reports, invalidates shared evidence at start or failure, validates a fresh report before atomic publication, and cleans its own artifacts. Real concurrent c8, omitted-source, stale-report, directory-order and failed-publication regressions cover the failure paths. Stacked on #132.

Owner ops-cl0o at this head records the decisions and append-only verification history.

Validation at 881af8bc4c2c87fba557f1e24f5d63053a3041ea: npm run release:check passes (457 tests, 455 pass, 2 skips); strict local PM health with required merge drivers, fresh committed-dist comparison, the PM-linked focused test and bun install --no-save pass. Thresholds and gates are unchanged.

Configured c8 coverage measures 100/100/100/100 across 23 files. Two existing opt-in fleet tests remain skipped in the default CI gate. Broader documentation, Trivy/ShellCheck and native Bun core #1349 evidence remain separate from these passing checks.

Fresh exact-head CI and substantive reviewer results remain required. This PR remains open for the orchestrator to assess; nothing is merged, published or deployed.


Re-land note: #134 was stacked on the #132 branch and its merge landed on that branch after #132 had already been squashed into main, so none of it reached main. This PR cherry-picks that exact squash (2109bd8) onto main unchanged: same 10 files, +594/-177. Every finding from the #134 review rounds is already addressed in this content.


Summary by cubic

Re-lands the package coverage gate rework onto main — the #134 squash landed on a branch that never reached main. The gate now derives a sorted, unique source inventory from coverageGate.sources for both the c8 includes and the report-presence check, replacing hand-maintained fixture lists, so adding a source file can no longer break the gate silently.

Each c8 invocation gets its own report and counter directories, the shared LCOV is invalidated before measuring and on every failure, and a validated report is atomically published only on success, so concurrent or nested runs can't corrupt one another's data.

  • Pins @unbrained/pm-cli to 2026.9.29.
  • Adds real c8 regression tests covering concurrent runs, unimported modules, stale reports, directory ordering, and a locked report destination.
  • Thresholds and exemptions are unchanged; coverage stays 100/100/100/100 across 23 files.

Written for commit 3338ce8. Summary will update on new commits.

Review in cubic

Summary by Sourcery

Harden the package coverage gate so every c8 run measures the complete source inventory and publishes only fresh, validated evidence.

Bug Fixes:

  • Ensure coverage source inventories are complete, deterministic, and free of duplicate entries so the measured denominator matches the package.
  • Prevent concurrent, nested, failed, or stale c8 runs from corrupting shared coverage evidence or leaving misleading reports available.
  • Fail closed when coverage report publication cannot complete, while preserving clear diagnostics for omitted sources and runner failures.

Enhancements:

  • Document the package coverage gate’s source inventory, isolation, publication, and failure semantics.
  • Update the required @unbrained/pm-cli compatibility version to 2026.9.29.

Documentation:

  • Add user-facing documentation describing the package coverage denominator, thresholds, and report lifecycle.

Tests:

  • Add regression coverage for overlapping source roots, real c8 discovery, concurrent runs, nested counters, stale reports, omitted modules, failed publication, and artifact cleanup.

Chores:

  • Record the associated PM issue and append-only verification history.

* Keep the coverage source inventory unique and preserve nested run counters

Deduplicate and sort source roots before forming c8 includes and checking
reported file presence. Replace three hard-coded fixture inventories with
reports derived from runner arguments. Independent real-c8 fixtures verify
new-module discovery, unimported-file failure and preservation of parent data.

Pin c8 raw counters to the measured repository instead of inheriting a parent
NODE_V8_COVERAGE directory that c8 cleans. Update the approved CLI/SDK pin and
lockfile to published 2026.9.29 without changing coverage thresholds/exemptions.

Validation: 456 tests, zero skips with real pm-slack/pm-csv selections; c8
reports per-file 100 statements/branches/functions/lines over 23 runtime and
tooling files. PM-linked snapshot checks pass 11 tests. npm ci, types, lint,
duplication, selected docstrings, production/full audits and release gates pass.

ops-cl0o remains blocked for full internal documentation (ops-0c8k), default
CI opt-in skips and required reviews. No publication or deployment is included.

* Isolate every c8 run and independently verify the package source scope

Give each coverage invocation unique report and counter directories. Validate
its own fresh LCOV, then publish the successful report atomically and clean only
that invocation. Preserve a parent using c8's default coverage/tmp.

Add two real concurrent same-repository c8 processes, stale-report rejection,
cleanup checks, and an independent fast-glob package inventory. A controlled
index.ts omission fails the inventory assertion. Factor shared include parsing
to retain the zero-duplication gate.

Regenerate the existing September 29 changelog heading with pm-changelog after
refreshing published tags; this reproduces and fixes the fresh-checkout CI
failure without weakening the check or creating a release.

Validation: 456 passed, zero failed/skipped/TODO; c8 100 statements, branches,
functions and lines per-file across 23 runtime/tooling/template files; PM-linked
none/snapshot 11 passed; strict types/lint, duplication, selected docstrings,
full/production audits, package allowlist and release contract gates pass.

Addresses Sourcery 4137899586/4137911348, CodeRabbit 4137928843 and Greptile
4137938933. Full documentation remains incomplete at 582/1883 declarations,
22/23 modules under ops-0c8k. Parent PR132 and exact-head reviews remain required.
No publication, deployment or production data changes. Owner: ops-cl0o.

* Invalidate shared coverage evidence when a gate starts or fails

The gate previously retained the last successful canonical LCOV after failing.
The actual assurance provider could therefore report the earlier 100% result
after only tests changed. Invalidate the shared report before measuring and at
every failure exit, including preflight. Unexpected failures invalidate in
finally; validated successes publish atomically from their private run directory.
Peer raw counters remain isolated. Document the generated paths and state.

The real-provider regression first measures 100 from c8, changes only a test,
observes failure, and requires the provider to refuse the old report. It fails
against f801740 and passes with this fix. Existing concurrency, default-parent
counter preservation, unimported-module and independent-inventory regressions pass.

Validation: full release:check with real pm-slack/pm-csv selections passes
456/456 with zero skips/TODOs, all four c8 columns at 100 per-file across 23
runtime/tooling/template modules; linked PM none/snapshot acceptance passes 11.
Strict types/lint, zero duplication, selected documentation, audits, artifact
allowlist, changelog/date, attestation and lifecycle contracts pass.

Full documentation remains 590/1887 declarations and 22/23 modules. Bun strict
health independently reproduces existing upstream1349 with extensions disabled;
imports, real ops execution and all five adapter configurations pass. Keep
ops-cl0o blocked and unclaimed pending these gates, parent PR132 and reviews.
Addresses Greptile 4138181201. No publication or deployment. Blocker: ops-0c8k.

* Sort coverage directory listings in coverage gate tests

readdirSync does not guarantee lexical order on every filesystem (XFS and
tmpfs return hash or creation order), so the three directory assertions in
test/coverage-gate.test.ts compared an unsorted listing against an ordered
array and could fail on a correct gate. Sort each listing before the
deepStrictEqual comparison; single-entry checks stay equivalent. CodeRabbit
finding 4138483396.

Rebased onto pm-ops#132 head f3e66c3 (main now includes releases 2026.9.28-1
and 2026.9.29). Full release:check passes: 456 tests, 0 failures, 2 existing
opt-in real-data skips; coverage 100/100/100/100 across 23 sources.

* Record the sorted directory-listing fix and gate evidence on ops-cl0o

* Clarify the pm-run timeout against the directly verified gate evidence on ops-cl0o

* Route a locked coverage report publish through the gate exit

Cubic 4168720026: renameSync failures escaped failRun and the injected
exit boundary. A throwing publisher now fails closed with the gate
diagnostic. Also record the default-suite skip-count clarification.

* Record the cubic skip clarification evidence and release the ops-cl0o claim

* Explain the 457-test total in the ops-cl0o land-pass note

CodeRabbit 4169890374: the extra test is the failed-publish path.
The two default-suite skips are unchanged.

* docs(ops): record resumed PR #134 verification

* docs(ops): retain verified parent schema disposition

---------

Co-authored-by: unbraind <1153461+unbraind@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: d08e442d-e5d3-44a2-a643-0e6b2328903b
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai sourcery-ai 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.

Sorry @unbraind, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 1 day and 23 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@sourcery-ai

sourcery-ai Bot commented Oct 4, 2026

Copy link
Copy Markdown

Reviewer's Guide

The PR reworks the coverage gate around a sorted, unique package source inventory and per-run c8 isolation, invalidating stale evidence and atomically publishing only fresh validated LCOV reports. It adds extensive real and controlled regressions for concurrency and failure paths, updates the PM CLI pin, documents the behavior, and records PM verification history.

Sequence diagram for isolated concurrent c8 coverage runs

sequenceDiagram
    participant RunA as Coverage run A
    participant RunB as Coverage run B
    participant C8 as c8
    participant ADir as run-A directory
    participant BDir as run-B directory
    participant Canonical as canonical lcov.info

    RunA->>Canonical: invalidateReport()
    RunB->>Canonical: invalidateReport()
    RunA->>ADir: mkdtempSync()
    RunB->>BDir: mkdtempSync()
    RunA->>C8: spawn(... --reports-dir ADir, --temp-directory ADir/tmp)
    RunB->>C8: spawn(... --reports-dir BDir, --temp-directory BDir/tmp)
    C8-->>ADir: write fresh LCOV and counters
    C8-->>BDir: write fresh LCOV and counters
    RunA->>ADir: readFileSync(lcov.info)
    RunB->>BDir: readFileSync(lcov.info)
    RunA->>Canonical: publishReport(ADir/lcov.info, canonical)
    RunB->>Canonical: publishReport(BDir/lcov.info, canonical)
    RunA->>ADir: cleanupRun()
    RunB->>BDir: cleanupRun()
Loading

Flow diagram for the isolated coverage gate

flowchart TD
    A["Discover coverageGate.sources"] --> B["Collect sorted unique source inventory"]
    B --> C["Invalidate canonical coverage/lcov.info"]
    C --> D["Create isolated coverage/run-* directory"]
    D --> E["Run c8 with isolated report and counter paths"]
    E --> F{"Runner succeeded?"}
    F -- No --> G["Remove run artifacts and leave canonical report unavailable"]
    F -- Yes --> H["Validate fresh LCOV and required source presence"]
    H --> I{"Report complete?"}
    I -- No --> G
    I -- Yes --> J["Atomically publish validated LCOV"]
    J --> K{"Publication succeeded?"}
    K -- No --> G
    K -- Yes --> L["Remove temporary run directory"]
Loading

File-Level Changes

Change Details Files
Make the coverage denominator deterministic and self-consistent with the configured source inventory.
  • Collect sources from configured roots, deduplicate overlapping paths, and sort them.
  • Use the resulting required-file list for both c8 include arguments and LCOV completeness checks.
  • Document the package coverage scope, exclusions, thresholds, and inventory behavior.
scripts/coverage-gate.ts
README.md
test/coverage-gate.test.ts
Isolate c8 runs and fail closed when producing or publishing coverage evidence.
  • Create per-invocation report and V8 counter directories, including an explicit c8 temp directory.
  • Invalidate the canonical LCOV before a run and on every failure.
  • Validate the fresh report before atomically publishing it, then remove only the invocation's artifacts.
  • Route publication errors through the gate's diagnostic and exit boundary while preserving peer-run data.
scripts/coverage-gate.ts
test/coverage-gate.test.ts
Expand regression coverage for source discovery, concurrency, stale evidence, and publication failures.
  • Add real c8 tests for newly imported and unimported modules, concurrent runs, inherited counters, failed runs, and stale-report invalidation.
  • Add controlled tests for overlapping source roots, directory ordering, isolated report paths, missing reports, and locked publication destinations.
test/coverage-gate.test.ts
Update the pinned PM CLI compatibility floor.
  • Advance the development dependency and compatibility test expectation from 2026.9.28 to 2026.9.29.
  • Refresh the lockfile resolution.
package.json
package-lock.json
test/compatibility-floor.test.ts
Record the re-land's PM issue and append-only verification history.
  • Add the related issue record and verification history entries.
  • Update the existing PM-linked record with the implementation and validation decisions.
.agents/pm/history/ops-0c8k.jsonl
.agents/pm/history/ops-cl0o.jsonl
.agents/pm/issues/ops-0c8k.toon
.agents/pm/issues/ops-cl0o.toon

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@greptile-apps

greptile-apps Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[High risk] Dependency bump and coverage gate refactor with concurrent-safety changes.

The PR appears safe to merge; no blocking issue was established.

What we checked:

  • Nested runs use separate reports: The outer gate checks its private lcovPath. Nested runs can change the shared report, but cannot replace that private report.
  • Cleanup cannot skip failure invalidation: Even if cleanup throws inside failRun(), the surrounding finally attempts to remove the shared report before cleaning again.

Summary

The PR makes coverage sources sorted and duplicate-free, gives each c8 run separate reports and counters, and publishes the shared report only after a successful check.

  • Adds an independent package inventory and real-c8 regression tests.
  • Removes shared coverage evidence when a run starts or fails.
  • Keeps coverage thresholds unchanged and pins the development CLI to 2026.9.29.
  • No new actionable issue was established. No numbered previous findings were supplied.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Start coverage gate] --> B[Remove shared report]
  B --> C[Collect sorted unique sources]
  C --> D[Create private run directory]
  D --> E[Run c8 with private counters and reports]
  E --> F{Tests and thresholds pass?}
  F -->|No| G[Remove shared report and private artifacts]
  F -->|Yes| H{Fresh report contains every required source?}
  H -->|No| G
  H -->|Yes| I[Atomically publish shared report]
  I --> J[Remove private artifacts]
Loading

Reviews (2) · Last reviewed commit: "Merge branch 'main' into fix/pm-ops-cove..."

@unbraind

unbraind commented Oct 4, 2026

Copy link
Copy Markdown
Owner Author

Re-land acknowledged: Greptile 5/5 with no findings, Sourcery's reviewer guide matches the content reviewed across three rounds on #134. CodeRabbit's auto-review skip and Sourcery's budget notice are quota notices (down-voted, no finding). All required checks green; merging.

@unbraind
unbraind merged commit 3844710 into main Oct 4, 2026
8 checks passed
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