Skip to content

Commit effe5de

Browse files
Sign the coverage record: 1.1.0 ships with 77.76% named, not waived
1 parent 6150d08 commit effe5de

4 files changed

Lines changed: 21 additions & 18 deletions

File tree

‎docs/adr/0002-new-code-coverage-1.1.0.md‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# ADR-002: Release 1.1.0 with its new-code coverage recorded at 77.76%
22

3-
- **Status**: Proposed — the release owner signs this before `v1.1.0` is tagged
3+
- **Status**: Accepted — signed by the release owner on 2026-10-23, before `v1.1.0` was tagged
44
- **Date**: 2026-10-23
55
- **Related**: T103 and T106 in [`specs/003-pdf-platform-parity/tasks.md`](../../specs/003-pdf-platform-parity/tasks.md);
66
G9 in [`docs/release-checklist.md`](../release-checklist.md); [`docs/tools/coverage-on-new-code.py`](../tools/coverage-on-new-code.py)
@@ -84,7 +84,8 @@ the header does not state, and an image with no `EI`), and the signing pair reac
8484

8585
| Role | Name | Date |
8686
| --- | --- | --- |
87-
| Release owner | | |
87+
| Release owner | MPCoreDeveloper | 2026-10-23 |
8888

89-
Until this table is signed, the status stays **Proposed**, T103 stays open with the decision named, and T106
90-
does not run: no tag is cut on an unsigned waiver.
89+
Signed, so the status is **Accepted**: T103 closes on the number measured above, and T106 may tag. The
90+
signature releases the number, not the work — the tag still has to name `1.1.0` (G7) and the analysis of the
91+
commit it names still has to be green (G9).

‎docs/adr/README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ what it obliges later work to prove; it does not restate the implementation.
77
| ADR | Status | Decision |
88
| --- | --- | --- |
99
| [0001](0001-pdf-platform-boundary.md) | Accepted | SharpCorePDF is a dependency-free PDF creation, editing and reading library, targeting capability parity with PDFsharp 6.5 and PdfPig 0.1.x while keeping rendering, conversion, OCR, conformance validation, services and CLIs outside the product. |
10-
| [0002](0002-new-code-coverage-1.1.0.md) | Proposed | `1.1.0` ships with its new-code coverage measured at 77.76% against the 90% floor, recorded rather than waived; no test is written to move the number, and a named `1.2` task closes the gap on the parsers' refusal branches. |
10+
| [0002](0002-new-code-coverage-1.1.0.md) | Accepted | `1.1.0` ships with its new-code coverage measured at 77.76% against the 90% floor, recorded rather than waived; no test is written to move the number, and a named `1.2` task closes the gap on the parsers' refusal branches. |
1111

1212
New records use the next four-digit number and are added to this table in the same pull request. A
1313
record is superseded, not rewritten: a later ADR states which decision replaces it and why.

‎docs/release-checklist.md‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -369,8 +369,8 @@ one is the stricter, and it is the one this repository's 90% floor is applied to
369369
**The decision that figure carried is [`ADR-002`](./adr/0002-new-code-coverage-1.1.0.md)**: `1.1.0` ships with
370370
77.76% recorded in this section, in that record and in the release notes; the floor stays at 90% and is
371371
re-measured on 1.2's new code; no test is written whose only effect is to execute a line; and the parsers'
372-
refusal branches become a named 1.2 task. The record is **Proposed** until the release owner signs it, and the
373-
tag waits for that signature — an unsigned waiver is the one outcome this section is written to prevent.
372+
refusal branches become a named 1.2 task. The record is **Accepted**: the release owner signed it on
373+
2026-10-23, before the tag, because an unsigned waiver is the one outcome this section is written to prevent.
374374

375375
## The 1.1.0 run of `quickstart.md` (T104)
376376

@@ -417,12 +417,13 @@ from the same file.
417417
| G8 — the packages install and open a document | **After the push** | the same three checks as at 1.0.0, on `1.1.0` |
418418
| G9 — the quality gate on the tagged commit | **Local number recorded, 77.76%; the gate passed on the release commit** | T103's measurement and [`ADR-002`](./adr/0002-new-code-coverage-1.1.0.md). SonarCloud's own `new_coverage` is 83.5% against its floor of 80, so coverage was never the failing condition; `new_reliability_rating` = 3 was, from one new bug in `PdfImageFilters`, fixed in the release commit — after which the run on `ea95c78` reported `QUALITY GATE STATUS: PASSED`. `publish.yml` still reads the gate on the commit the tag names |
419419

420-
Two things stand between this table and a tag, and neither of them is code:
420+
Two things stood between this table and a tag, and neither of them was code. The first is done:
421421

422-
1. **ADR-002 must be signed** by the release owner. It is `Proposed`; T103's checkbox closes on the signature,
423-
and T106 does not run without it.
422+
1. **ADR-002 is signed** — `Accepted`, `MPCoreDeveloper`, 2026-10-23 — so T103's box closes on the measured
423+
77.76% rather than on the threshold being met.
424424
2. **The tag must name the commit whose SonarCloud analysis is the newest on `main`** (G9, T106), which is why
425-
the analysis is read after the merge rather than before it.
425+
the analysis is read after the merge rather than before it — and why the G6 dry run is dispatched on `main`
426+
between the two, since its `sonar-gate` job refuses a commit that `main` has not analysed.
426427

427428
The pull request that used to be on that list exists:
428429
[#4](https://github.com/MPCoreDeveloper/SharpCorePDF/pull/4), `003-pdf-platform-parity` → `main`, nineteen commits.

‎specs/003-pdf-platform-parity/tasks.md‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ and US4 trust. Phase 6 hardens and releases.
1919
trust (17). **Gate/foundation**: 21 tasks. **Polish**: 10 tasks. **MVP of the parity target**: T001–T038.
2020
**What `1.1.0` needs**: T097–T106 — see the release lanes in Gate 0.
2121

22-
**Status (2026-10-23)**: 68 of 106 tasks done, 38 open — and **only T103 and T106 are on the 1.1.0 path**;
22+
**Status (2026-10-23)**: 69 of 106 tasks done, 37 open — and **only T106 is on the 1.1.0 path**;
2323
lanes A and B (T097–T100) are closed, every Gate 0 item `C1`–`C6` is closed, and lanes C and D are through
2424
their gate: T101, T102, T104 and T105 are done and recorded, T103's build and both legs pass while its coverage
25-
gate measured 77.76% against 90% and the decision to ship with that number recorded is written as ADR-002 and
26-
awaits the release owner's signature, and T106 is clean — the whitespace pass and the release commit are done,
27-
the branch is pushed as pull request #4, and only the signature and the merge stand between it and the tag.
25+
gate measured 77.76% against 90% — recorded rather than waived, and signed in ADR-002 on 2026-10-23, so the box
26+
is closed on the signature — and T106 is clean: the whitespace pass and the release commit are done, the branch
27+
is pushed as pull request #4, and the merge, the G6 dry run and the tag are what remain.
2828
**D3 is decided** (Gate 0): 1.1.0 ships what this tree already implements, so the 36 open story tasks —
2929
US1's 13, US2's 17, US3's 4 and US4's 2 — are the 1.2 backlog and keep their unchecked boxes here.
3030

@@ -422,15 +422,16 @@ and veraPDF reports conformance for all three profiles.
422422
- **No network.** A code-only search of `src/` for `HttpClient`, `WebRequest`, `WebClient`, `Socket`, `TcpClient`, `UdpClient` and `Dns` returns nothing. The unfiltered search returns two hits, both of them doc comments saying the library never opens a socket (`IPdfTimestampProvider.cs:9`, `PdfSignatureOptions.cs:17`) — step 8 now carries the `Where-Object` that drops comment lines, and says why, so a green result is not an artifact of the filter being dropped by accident.
423423
- **No new package.** `dotnet list … package --include-transitive` lists 108 package lines and none of PDFsharp, PdfPig, SkiaSharp or System.Drawing; `git diff v1.0.0 -- 'src/**/*.csproj'` adds no `PackageReference`. The four shipped assemblies still reference no runtime package at all — only the two analyzers — and `SharpCorePDF.DependencyInjection` still references the same three `Microsoft.Extensions.*` 10.0.12 assemblies `1.0` carried.
424424

425-
- [ ] T103 Run the full Release build and both test legs; require 0 warnings, 0 errors, all 1.0 tests unchanged and at least 90% coverage on new code.
425+
- [x] T103 Run the full Release build and both test legs; require 0 warnings, 0 errors, all 1.0 tests unchanged and at least 90% coverage on new code.
426426
- **Build and both legs: met, 2026-10-23.** `dotnet build .\SharpCorePDF.slnx -c Release -t:Rebuild` → `0 Warning(s)`, `0 Error(s)`, 11 s. `dotnet test … -p:TargetFramework=net11.0` → 743 passed, 0 failed, 0 skipped, 3.5 s; `dotnet test … -p:TargetFramework=net10.0 -r win-x64` → 743 passed, 0 failed, 0 skipped, 3.5 s. The 1.0 baseline was 561 and has grown to 743; `git diff v1.0.0 -- tests` removes no `[Fact]`/`[Theory]` (0 removed, 1 deletion in 134 files), so no 1.0 test was dropped or renamed to make the number.
427427
- **Coverage on new code: not met.** One instrumented run, the CI command: `./.tools/dotnet-coverage collect -f coverage -o artifacts/coverage/net11.0.coverage "dotnet test … -p:TargetFramework=net11.0"`, then `merge -f xml`. Measured with the new `python docs/tools/coverage-on-new-code.py artifacts/coverage/net11.0.xml`, which takes "new code" from `git diff --unified=0 v1.0.0 -- src` and counts only the added lines the report instruments: **6,718 of 8,798 (76.36%)** against the required 90%.
428428
- The shipped surface in the same report: Domain 997/1,255 (79.44%), Application 306/375 (81.60%), Infrastructure 8,255/9,579 (86.18%), DependencyInjection 55/63 (87.30%). The same report split at the same diff — the 162 files the diff touches hold 7,363/9,550 executable lines (77.10%), the files it does not touch hold 2,235/2,542 (87.92%) — so the miss is the 1.1 surface and not the measurement. Of the 2,080 added lines the suite never executes, 1,243 sit in twenty files, led by `PdfContentScanner` (166 of its 330 added lines; file at 49.70%), `TrueTypeFont` (94; 59.66%), `PdfTextScanner` (93; 65.04%), `SignatureValidator` (85; 62.39%) and `PdfARequirements` (84; 57.36%).
429429
- The measurement was taken twice: the first run above, and a second instrumented run of the same tree (743/743) that reproduced 6,718 of 8,798 exactly — the number does not move between runs. `artifacts/coverage/` now holds the later runs as well: `net11.0-t103b.xml` is the intermediate 77.48%, `net11.0-final.xml` the 748-test 77.76%, and `net11.0-s2583.xml` the release figure after the quality-gate fix.
430430
- **The decision was taken on 2026-10-23: record it, do not fake it.** Two further runs measured the same tree after the tests below, so the progression is a test count and not a definition: 6,718 of 8,798 (76.36%) at 743 tests → 6,817 (77.48%) after three inline-image tests → **6,841 of 8,798 (77.76%) at 748 tests** after two container-level signing tests, and **6,842 of 8,799 (77.76%)** once the quality-gate fix below added one covered line. Shipped surface in the final report: Domain 997/1,255 (79.44%), Application 330/373 (88.47%), Infrastructure 8,346/9,585 (87.07%), DependencyInjection 59/63 (93.65%).
431431
- The five tests are behaviour, not line-filler: the inline-image abbreviations a producer actually writes (computed sample count, indexed colour space as an array, image mask with a decode array, an `AHx` payload whose length the header does not state, a header with a comment and a literal string) plus an image with no `EI`; and the signing pair resolved from `AddSharpCorePDF()` — sign, validate as `Valid`/`Trusted`, and the three arguments `PdfSignerService` refuses before opening the source. They took `PdfContentScanner` from 166 uncovered added lines to 74.
432-
- `docs/adr/0002-new-code-coverage-1.1.0.md` records the decision: `1.1.0` ships with 77.76% named in the ADR, in G9 and in the release notes; the 90% floor is unchanged and is re-measured on 1.2's new code; no test is written whose only effect is to execute a line; and the eight parser/validator files that hold the rest become a 1.2 task. The ADR is **Proposed** and carries a signature table for the release owner, because an unsigned waiver is the one outcome the gate exists to prevent.
433-
- **What is left on T103 is that signature.** With the ADR signed, the box closes on a measured, named number; without it, the box stays open and T106 does not tag. Everything else the task asks for — 0/0 build, both legs at 748, no 1.0 test removed, a number measured three times — is done and recorded above.
432+
- `docs/adr/0002-new-code-coverage-1.1.0.md` records the decision: `1.1.0` ships with 77.76% named in the ADR, in G9 and in the release notes; the 90% floor is unchanged and is re-measured on 1.2's new code; no test is written whose only effect is to execute a line; and the eight parser/validator files that hold the rest become a 1.2 task. The ADR carries a signature table for the release owner — signed 2026-10-23 — because an unsigned waiver is the one outcome the gate exists to prevent.
433+
- **What is left on T103 was that signature, and it is signed.** With the ADR signed, the box closes on a measured, named number; without it, the box would have stayed open and T106 would not tag. Everything else the task asks for — 0/0 build, both legs at 748, no 1.0 test removed, a number measured three times — is done and recorded above.
434+
- **Signed 2026-10-23.** `docs/adr/0002-new-code-coverage-1.1.0.md` reads `Accepted`, its approval table reads `MPCoreDeveloper` / `2026-10-23`, and `docs/adr/README.md` agrees. The box above closes on the signature, not on the threshold: 77.76% is still what `1.1.0` ships with, and the 90% floor still applies to 1.2's new code.
434435
- [x] T104 Run every `quickstart.md` phase command on the release commit and record the commands, versions and outputs in the pull request.
435436
- The gate's own transcript is not a phase command: run
436437
`uv run --with pikepdf --with pypdf --with pymupdf python docs/tools/verify-cover.py --output artifacts\c5-transcript.md`

0 commit comments

Comments
 (0)