From eaea0dad49c853692771d5eb0f4a5930e039b0f9 Mon Sep 17 00:00:00 2001 From: DevBot Date: Fri, 4 Sep 2026 21:59:07 +0800 Subject: [PATCH 1/2] docs(v0.44): preserve Beta.2 closure verification evidence (#1288) Fresh-verifier closure report (NO_GO on F1 at aa3dd70f), the remediation re-verification addendum (GO at 89d37365), and the verifier-added gate-teeth tests for the packed-artifact legacy-residue gate. --- ...6-09-04-v044-beta2-closure-verification.md | 98 +++++++++++++++++++ .../2026-09-04-v044-beta2-reverification.md | 71 ++++++++++++++ .../check-package-artifacts-verifier.test.ts | 94 ++++++++++++++++++ 3 files changed, 263 insertions(+) create mode 100644 docs/evidence/2026-09-04-v044-beta2-closure-verification.md create mode 100644 docs/evidence/2026-09-04-v044-beta2-reverification.md create mode 100644 tools/check-package-artifacts-verifier.test.ts diff --git a/docs/evidence/2026-09-04-v044-beta2-closure-verification.md b/docs/evidence/2026-09-04-v044-beta2-closure-verification.md new file mode 100644 index 000000000..ee44eab20 --- /dev/null +++ b/docs/evidence/2026-09-04-v044-beta2-closure-verification.md @@ -0,0 +1,98 @@ +# v0.44 Beta.2 Closure Verification — independent verifier record + +- Date: 2026-09-04 +- Verifier: fresh `kimi-code` session, profile `.agents/v044-kimi-release-verifier.md` (no implementer/thinker session reuse) +- Stage issue: #1288 (umbrella #1155, authority ADR-0151, Beta.1 record #1150) +- Candidate SHA: `aa3dd70ff8e5c8dbee602f8f7acd8e3b9d3c2b2b` (dev tip, tree clean at session start) +- CI at candidate: AutoFlow CI run 33871051171 SUCCESS, CodeQL run 33871051092 SUCCESS — both at the exact candidate SHA (verified via `gh run view … --json headSha`). +- npm truth (verified live): `@openelement/element` and `@openelement/ui` dist-tags `beta=0.44.0-beta.1`, `latest=0.43.3`, `alpha=0.43.0-alpha.2`. Beta.2 not yet published — consistent with the packet. In-repo version is 0.44.0-beta.1 with `nextPlannedTrain: v0.44.0-beta.2` (docs/release/release-state.json); the bump to beta.2 happens in the release lane, so beta.1-named tarballs from the candidate tree are expected, not a defect. + +## Battery results (all at candidate SHA unless noted) + +| # | Item | Command / method | Result | +| -- | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| 1 | Full test suite (main tree) | `deno task test` | exit 0 (final leg: supabase starter 150 passed / 0 failed; main `deno test` leg must exit 0 for the `&&`-chained starter leg to run) | +| 2 | Clean clone | real `git clone` to /tmp/oe-verify-aa3dd70, `git checkout aa3dd70…`, 0 dirty files | honest-clone caveat confirmed: `nodeModulesDir: "manual"` requires `deno install --frozen --node-modules-dir` (exactly the CI `setup-deno-workspace` action); after that `git diff --exit-code -- deno.lock` clean, `deno task build` exit 0 (150 pages, pagefind 150), `deno task test` exit 0 (pipefail-captured `CLONE_TASK_EXIT=0`) | +| 3 | pack:dry-run | `deno task pack:dry-run` | exit 0, five tarballs | +| 4 | Packed starter consumer | `deno task consumer:packaged` | exit 0 — dev server SSR probe, typecheck, test, SSG build, start, standalone `dist/server/serve.mjs` deploy probe, preview fail-closed guidance, import-map smoke; scratch consumer in $TMPDIR outside the repo (verified in tools/consumer-packaged-starter.ts header + log paths) | +| 5 | Packed UI consumer | `deno task consumer:packaged-ui` | exit 0 — packageIslands SSR admission renders compiled DSD from the packed artifact | +| 6 | Artifact integrity | `deno task package-artifacts:check` | exit 0 — incl. publint + ATTW (npm:publint, npm:@arethetypeswrong/cli invoked by tools/check-package-artifacts.ts:245,253), FORBIDDEN_LEGACY_PATHS/patterns, artifact sizes | +| 7 | UI tarball independent inspection | extract `openelement-ui-0.44.0-beta.1.tgz` | ships compiled Part Programs (`__partProgram` JSON in every open-*.js); zero `applyDecs` occurrences (grep exit 1); no `workspace:` coupling; sibling dep pinned exact `0.44.0-beta.1`; no .d.ts (JS-only package, no `types` field — consistent with "Types will not be included" pack warnings, pre-existing behavior) | +| 8 | UI dogfood gate | `deno task fixture:ui-dogfood:gate` | exit 0 — 75 passed (25 tests × chromium+firefox+webkit, all three engines ran locally) | +| 9 | www e2e (chromium, full) | `deno task test:e2e` | exit 1 — 316 passed, 4 failed: exactly `architecture-islands-deep` mobile snapshots (en/zh × dark/light). Verified each failure artifact names `…-mobile-architecture-islands-deep.png`. Known pre-existing local macOS drift; CI-skipped by design (`test.skip(!!process.env.CI && OPEN_VISUAL_REGRESSION !== '1')` in visual-baselines.spec.ts:8-11; CI is authoritative and green). Not a candidate failure per packet caveat. | +| 10 | Public-route IA e2e on a FRESH build | `deno task build` (exit 0) then `playwright test www/e2e/public-routes.spec.ts --project=chromium` | exit 0 — 147/147 routes; route list mechanically derived from built sitemap.xml with fail-closed content-graph cross-check (spec header verified) | +| 11 | Content truth gates | `content-graph:check`, `api-reference:check`, `www:check-truth`, `www:check-current-truth`, `content:examples-check`, `docs:truth` (incl. release:truth:check, docs:check-version-anchors, docs:check-recipe-parity) | all exit 0; generated artifacts byte-identical | +| 12 | Package surface / interface | `package-surface:check`, `interface:snapshot`, `graph:check`, `export-files:check`, `generate:ui-tokens:check`, `verify:configs` | all exit 0 (5 packages) | +| 13 | Security projection / boundary suites | `signals:check-protocol-boundary`, `validation:boundary-check`, `fullstack:boundary-check`, `text-integrity:check`, `deno-api:check`, `arch:check`, `third-party-wc:smoke`, `consumer:element-smoke`, `examples:check`, `docs:check-public/current/claims/role-neutral/strategy`, `www:check-theme-tokens` | all exit 0 | +| 14 | Gate-of-gates / policy registry / release tooling | `deno test tools/autoflow/__tests__/` | 138 passed / 0 failed — includes registry-purity (`generic toolchain concerns are not AutoFlow gates`, #1229), OIDC workflow shape (pr-ci-workflow.test.ts fails closed on NPM_TOKEN/_authToken, requires id-token: write + npm floor before publish), release-lock, exact-SHA provenance tests | +| 15 | SIGSEGV retry semantics | `deno test tools/check-coverage.test.ts` | 7 passed — incl. "a real assertion failure fails immediately without any retry" and "crash exhaustion fails loudly". (First invocation with narrowed permissions failed on an unrelated typescript.js uncaught error — an invocation artifact, not the candidate; rerun with task-equivalent permissions green.) | +| 16 | Release lane | inspection of .github/workflows/autoflow-release.yml + tools/autoflow/release.ts + release-lock.ts; `deno task publish:npm:dry-run` (real npm CLI) exit 0 | exact-SHA evidence guard: artifact name derived from `git rev-parse HEAD`, never from input; single-file content assertion; `id-token: write` only npm credential; npm floor `^11.5.1` pinned AND runtime-asserted before publish; `canPublishNpm()` gates on `GITHUB_ACTIONS==='true'` only (local never publishes even with legacy token set); local release lock createNew-mutual-exclusion with stale-lock fail-closed naming the file. Hosted lane NOT dispatched (per instructions); rehearsal evidence on #1288 (run 33772921763 fail-closed at the evidence guard) is consistent with the inspected shape. | +| 17 | Governance spot-check | autoflow-ci.yml lines 47-66; `deno task lint:markdown` | actionlint (v1.7.12 + SHA-256), zizmor-action (SHA-pinned), gitleaks (v8.30.1 + SHA-256) present as CI steps; markdownlint-cli2 0.23.2 lints 545 files / 0 issues (not a hollow glob); deleted bespoke type-safety/secret-regex checkers absent from tools/ (grep empty); policy gate registry = 57 gates | +| 18 | Benchmark harness | `deno test -A benchmarks/` | 12 passed / 0 failed | +| 19 | Legacy residue (independent) | grep packages/element/src for DATA_SSR_PROPS / data-eid / data-signal; ls of the five FORBIDDEN_LEGACY_PATHS files | all five forbidden files deleted; only remaining marker mention is a doc comment in hydration-markers.ts (comment-stripped by the gate); gate teeth proven (see Tests added) | + +## Meaningfulness demonstrations (temporary, fully reverted) + +1. **content-graph fail-closed proof**: appended one byte to `www/app/data/_generated-content-graph.json` → `content-graph:check` exit 1 ("stale; run deno task generate:content-graph") → `generate:content-graph` restored the file byte-identically (`cmp` clean, `git diff` empty). +2. **artifact-gate teeth**: initial tarball-poisoning attempt was defeated by design — `package-artifacts:check` re-runs `pack:dry-run` first (tools/check-package-artifacts.ts:276), regenerating honest tarballs from source before scanning. Teeth then proven at unit level by the new test file below: synthetic poisoned package trees produce violations; a clean tree produces none. + +## Tests added (within write boundary; test files only) + +`tools/check-package-artifacts-verifier.test.ts` (4 tests, all pass): + +- forbidden legacy path `src/types.ts` in a synthetic `@openelement/element` tree → violation fires +- dead `DATA_SSR_PROPS` export → violation fires +- legacy `data-signal-*` hydration attribute literal → violation fires +- clean compiled tree → zero violations (negative control) + +Meaningfulness is by construction: the same assertions fail if the FORBIDDEN_LEGACY_* rules are removed or weakened (they assert on `scanExtractedPackage` output against poisoned inputs). + +## Carried-risk register adjudication + +1. **Desktop OEC9008** — CONFIRMED as claimed: both desktop examples fail closed on full vite build, excluded from consumer evidence, documented in docs/current/DENO_DESKTOP_TARGET.md (v0.44 Build Status) and both example READMEs; carried to issue #1311 (OPEN, milestone `v0.44 Beta.3`). Bounded-repair probe cascading to OEC9007/OEC9006 recorded. +2. **Local visual-baseline drift** — CONFIRMED: reproduced exactly 4 failures, all `architecture-islands-deep` mobile (en/zh × dark/light); CI-skipped by design (env guard in the spec); CI chromium leg green at candidate. Local-only, CI canonical. Not a blocker per packet. +3. **freeze:semantics gap** — CONFIRMED one-directional fail-closed: header argument in tools/check-frozen-semantics.ts holds; independently verified the load-bearing premise `git merge-base --is-ancestor origin/main origin/dev` = true (main `00db23e6` is an ancestor of dev `aa3dd70`), so local diff ⊇ CI diff and local amendment signals ⊆ CI signals; residual gap is local false-FAIL only. +4. **SIGSEGV #1278** — CONFIRMED fail-loud bounded retry: exit <128 (incl. 1 = assertion failure) classifies `test-failure` and throws immediately, never retried; crashes (≥128) retry up to the bound then throw; every crash prints to stderr. Unit tests pass (battery row 15). +5. **CodeQL #1281** — mechanism understanding VERIFIED: live API shows 0 open alerts on dev; 8 open alerts remain on refs/heads/main (all created 2026-08-01…2026-09-02, predating the dev-side fixes); 3 dismissed; 89 fixed historically. Consistent with "fixed alerts close only on the next default-branch (main) scan". Post-promotion verification (open == 0 after the main scan) is a recorded closure-battery follow-up — see RESIDUAL_RISKS. +6. **Benchmark evidence SHA gap** — PARTIALLY RE-CONFIRMED: harness integrity green (12 passed). The docs/harness-only relationship still holds in that no public page presents the `493548a6` numbers as candidate measurements (the Performance page makes only qualitative claims). HOWEVER the packages/*/src delta 493548a6..aa3dd70 is now 62 files (+437/−355) including real semantic changes (UI dogfood fixes, B2.13 deletions) — the Beta.1-era "parity-proven remediations only" framing no longer applies. Acceptable for Beta.2 (performance is Beta.3's formal-benchmark scope) but must be re-baselined there. +7. **Bun** — CONFIRMED SUPPORTED with required CI leg `dist/server Bun smoke`: Bun 1.4.1 pinned by version + SHA-256 (`sha256sum -c`), real HTTP assertions against `dist/server/serve.mjs` booted under Bun; the leg feeds the required pr-full-ci-evidence job. Not reproduced locally (no Bun on this machine) — CI is the evidence, and it is green at the candidate. +8. **Dead v0.43 residue** — CONFIRMED removed + gated (PR #1310): forbidden paths absent from source and packed artifacts; gate teeth proven by added tests; live gate `package-artifacts:check` green. + +## FAILURE (promotion-blocking, smallest reproducible case) + +**Stale quantitative public claim on the Performance page (both locales).** + +`www/content/architecture/benchmark.md:11` and `www/content/architecture/benchmark.zh.md:11` claim the www SSG build has "**30 route modules, 205 sitemap URLs**". The fresh build at the candidate emits **146** sitemap URLs (`grep -c "" www/dist/sitemap.xml` = 146; also 150 pages per www:apply-seo/pagefind logs). The claim ships verbatim in built output (`www/dist/architecture/benchmark/index.html` and `…/zh/…` both contain it). Introduced by PR #1106 (2026-08) and stale since route consolidation; no gate derives or checks these numbers (grep of check-www-truth/content-graph: no coverage). This falsifies the website/content-truth claim in its general form (B2.3/B2.4 acceptance: content claims derived from owned truth) — a handwritten public metric that is false by ~40% survived B2.3, B2.4, the hostile audit, and the #1307 remediation. + +Minimal fix (production content — outside the verifier write boundary): update or derive the two numbers in both locale files (`www/content/architecture/benchmark.md`, `benchmark.zh.md`); optionally extend a content-truth gate to derive route/URL counts mechanically. Re-verification scope after the fix: `deno task build` + `www:check-truth` + `test:e2e` (chromium) — everything else in this record stands. + +## Advisory observations (non-blocking) + +- `deno task audit:citations:check` exits 1 locally: 14 drifted citations, all in ARCHIVED docs/audit/ reports (chiefly 2026-08-17-deep-repo-scan.md) whose cited files were deliberately deleted by B2.13. The tool is NOT a registered AutoFlow gate (absent from tools/autoflow/policy.ts GATES), so CI never runs it; impact is audit-doc hygiene. Recommend appending verification appendices (`--write`) or archiving-by-commit for the affected reports. +- Tarballs are NOT byte-reproducible across `pack:dry-run` invocations (three runs → three distinct sha256 sets; gzip/tar metadata). Fingerprints below are the final run's values; per-publish hashes must be recorded at publish time (as the release recipe already prescribes). + +## Artifact fingerprints (sha256, final `pack:dry-run` run at the candidate) + +``` +82b56b57c34bd505bb58a857dc94903da8023b177ecc088174c5aa5acbe6d697 adapter-vite/openelement-adapter-vite-0.44.0-beta.1.tgz +ab027a4111443172fa36d4f42a7db3356faff8e1b9cf0b737ec2eca162d7305f app/openelement-app-0.44.0-beta.1.tgz +d8fa1603d6285ef0c81cbf39bf06cbe9183edb6397f5f991dfeb66fbefd4e58b create/openelement-create-0.44.0-beta.1.tgz +9b2642a534c700c1de6b70c150b24e3a3acb98e88c6e3712e1b26dc4b014aed3 element/openelement-element-0.44.0-beta.1.tgz +fa2b8d847c433714476c5e560608f6c11b1bf8ae071dd5492b08d8b813b22383 ui/openelement-ui-0.44.0-beta.1.tgz +``` + +(First-run set consumed by the consumer gates: 104c5aac…/c3449c53…/a1a56bcb…/b6b00561…/6fa0636e… — same source, same SHA; hashes differ per run, see advisory note.) + +## Residual risks + +1. **npm trusted-publisher registration** — pending maintainer web action for all five packages per docs/runbooks/npm-trusted-publishing.md; until then real publishes fail at npm by design (no token fallback). PRE-PUBLISH GATE. +2. **CodeQL main-scan closure** — 8 alerts open on main will re-scan only after the beta.2 promotion reaches the default branch; post-publish, verify open == 0 and record (stage-recorded follow-up). +3. **Benchmark re-baseline** — evidence SHA gap now spans real semantic changes; formal re-baseline is Beta.3 scope. +4. **Desktop OEC9008** — carried to #1311 (Beta.3); desktop examples remain excluded from consumer evidence. +5. **Local visual-baseline drift** — architecture-islands-deep mobile ×4, local-only, CI-canonical; needs a baseline review on the authoring workstation eventually (not CI-visible). +6. **Advisory audit-citation drift** — 14 stale citations in archived audit reports; non-gated. +7. **Tarball byte non-determinism** — record per-publish hashes at publish time. + +## Production code unchanged + +Yes. `git status --porcelain` at session end: only `?? tools/check-package-artifacts-verifier.test.ts` (test file, write-boundary-compliant). The content-graph mutation was reverted byte-identically; the poisoned element tarball was regenerated from source by the gate itself and re-packed clean; no commits, pushes, tags, or GitHub mutations were made; the hosted release workflow was not dispatched. diff --git a/docs/evidence/2026-09-04-v044-beta2-reverification.md b/docs/evidence/2026-09-04-v044-beta2-reverification.md new file mode 100644 index 000000000..8ed64548d --- /dev/null +++ b/docs/evidence/2026-09-04-v044-beta2-reverification.md @@ -0,0 +1,71 @@ +# v0.44 Beta.2 Re-Verification Addendum — narrow F1-closure pass + +- Date: 2026-09-04 +- Verifier: fresh `kimi-code` session, profile `.agents/v044-kimi-release-verifier.md` (independent of the first verifier session and of the implementer) +- Scope: narrow re-verification of the sole NO-GO finding (F1) from `docs/evidence/2026-09-04-v044-beta2-closure-verification.md` after remediation PR #1313 (issue #1312), plus a regression screen over everything the remediation touched. +- First-report integrity note: the first closure record was read in full. Its wide padded table column alignment is a `deno fmt` reflow artifact; the content itself (battery rows, F1 finding, fingerprints, residual risks) is coherent, internally consistent, and matches what the remediation targeted. Nothing beyond formatting appears altered. + +```text +STATUS: PASS + +CANDIDATE_SHA: +89d373652dd6cdfc1165724f9b874dd530bd057b — dev tip, verified three ways: +(1) `git rev-parse HEAD` = 89d373652dd6cdfc1165724f9b874dd530bd057b, branch dev == origin/dev; +(2) commit subject is the #1313 squash merge ("fix(www): replace stale benchmark route/sitemap counts with durable build-truth claim (#1312) (#1313)"), parent is aa3dd70ff8e5c8dbee602f8f7acd8e3b9d3c2b2b (the first verification's NO-GO candidate); `git merge-base --is-ancestor aa3dd70f 89d37365` = true; +(3) authoritative CI at this exact SHA verified live: AutoFlow CI run 33878333759 conclusion=success headSha=89d37365… and CodeQL run 33878333945 conclusion=success headSha=89d37365… (both via `gh run view --json headSha,conclusion`). +Tree state: no modified tracked files; only two untracked prior-verifier artifacts (the first closure record itself and tools/check-package-artifacts-verifier.test.ts, both write-boundary-compliant leftovers of the first session). + +ARTIFACT_FINGERPRINTS: +Package inputs are byte-unchanged between aa3dd70f and 89d37365 — `git diff aa3dd70f..89d37365 --stat` touches exactly 3 files (www/content/architecture/benchmark.md, benchmark.zh.md, www/app/data/_generated-content-graph.json); no packages/*, tools/, CI, or export-surface delta. The five-tarball sha256 set recorded in the first closure record therefore remains the fingerprint of record for this candidate: +82b56b57… adapter-vite/openelement-adapter-vite-0.44.0-beta.1.tgz +ab027a41… app/openelement-app-0.44.0-beta.1.tgz +d8fa1603… create/openelement-create-0.44.0-beta.1.tgz +9b2642a5… element/openelement-element-0.44.0-beta.1.tgz +fa2b8d84… ui/openelement-ui-0.44.0-beta.1.tgz +(Per the first record's advisory, tarballs are not byte-reproducible across pack invocations; per-publish hashes must be recorded at publish time.) + +CRITERION_TEST_MATRIX: +[C1] Candidate SHA = dev tip, clean tracked tree, CI green at exact SHA → git/gh evidence above. PASS. +[C2] F1 stale claim GONE from built output (both locales) → fresh `deno task build` exit 0 (150 pages; apply-seo 150; pagefind 150; www:check-artifact-truth passed; www:check-links passed), then grep of www/dist/architecture/benchmark/index.html and www/dist/zh/architecture/benchmark/index.html for `205`, `30 route|route modules|30 个路由|路由模块` → exit 1 (no matches). Whole-dist sweep `grep -rniE '30 route modules|205 sitemap|30 个路由模块|205 条' www/dist/` → exit 1, 0 matches. PASS. +[C3] Durable claim PRESENT in built output (both locales) → en page contains "Every route prerendered; sitemap built from routes"; zh page contains "每个路由都静态预渲染;sitemap 由路由生成". PASS. +[C4] Sitemap reality matches the durable claim → www/dist/sitemap.xml has 146 entries; public-routes spec mechanically derives the route list from the built sitemap with a fail-closed content-graph cross-check and passes 147/147 (all sitemap routes render with correct locale/heading); build prerendered all 150 pages. The claim is qualitative ("every route prerendered; sitemap built from routes") and holds by construction. PASS. +[C5] No new volatile quantitative claims introduced → digit scan of both source files (www/content/architecture/benchmark.md, benchmark.zh.md) finds only frontmatter `order: 100`; no numeric claim remains in either locale. PASS. +[C6] Regression screen over remediation blast radius (content + generated fingerprints) → `deno task content-graph:check` exit 0 ("byte-identical" — proves the regenerated fingerprints match fresh generation); `deno task www:check-truth` exit 0; full `deno task test:e2e` (chromium) = 316 passed / 4 failed, the 4 failures byte-identical in kind to the first record: every failing artifact is `*-mobile-architecture-islands-deep-actual.png` (en/zh × dark/light), the documented local-only macOS drift, CI-skipped by design (visual-baselines.spec.ts:8-11); targeted public-routes spec alone: 147/147. PASS. +[C7] /apilist generated anchors (hostile-audit finding 1 regression screen) → www/dist/apilist/index.html and www/dist/zh/apilist/index.html each expose 29 unique generated anchors (api-element-root-signal, api-app-root-redirect, api-element-jsx-runtime-jsx, ce-open-dialog, etc. present; en/zh anchor sets at parity). PASS. +[C8] Process claims of PR #1313 → both locales edited consistently (same claim replaced with equivalent durable wording; verified in `git diff aa3dd70f..89d37365` and via `gh pr view 1313 --json files`: exactly the 3 expected files); NO gate removed, no tools/ or CI file touched; issue #1312 CLOSED. PASS. + +TESTS_OR_FIXTURES_ADDED: +None in this session. The write boundary required no new tests: every criterion above was discharged by existing gates and direct inspection of built output. (tools/check-package-artifacts-verifier.test.ts is the first session's artifact, untouched here.) + +MEANINGFULNESS_EVIDENCE: +The C2 assertion has teeth, demonstrated against the pre-remediation tree: `git show aa3dd70f:www/content/architecture/benchmark.md | grep 205` → matches line 11 ("30 route modules, 205 sitemap URLs"); same for benchmark.zh.md ("30 个路由模块,205 条 sitemap URL") — so the greps WOULD have failed at the old SHA, and they produce zero matches at the candidate. The positive claim assertion (C3) is anchored to exact strings present in both built locale pages. The fingerprint claim (C6) is not trust-based: content-graph:check regenerates and byte-compares, exit 0. + +COMMANDS_AND_EXIT_CODES: +- git rev-parse HEAD → 89d373652dd6cdfc1165724f9b874dd530bd057b; git status → no tracked modifications +- gh run view 33878333759 / 33878333945 → conclusion=success, headSha=89d37365… (both) +- git diff aa3dd70f..89d37365 --stat → 3 files, 9 insertions, 9 deletions (exit 0) +- deno task build → exit 0 (150 pages prerendered; www:check-artifact-truth and www:check-links pass in-build) +- grep stale patterns on built en+zh benchmark pages → exit 1 (no matches) — desired +- grep -rniE stale patterns www/dist/ → exit 1, 0 matches — desired +- grep durable claim en / zh built pages → exit 0 (exact match each) +- grep -c '' www/dist/sitemap.xml → 146 +- deno task content-graph:check → exit 0 (byte-identical) +- deno task www:check-truth → exit 0 +- playwright public-routes.spec.ts --project=chromium (via www/e2e/playwright.config.ts) → exit 0, 147/147 +- deno task test:e2e (full chromium) → exit 1, 316 passed / 4 failed = the 4 documented islands-deep mobile visual-baseline drifts only (artifact names verified individually) +- /apilist anchor spot-check en + zh → 29 unique anchors each, parity + +FAILURES: +None attributable to the candidate. The 4 full-e2e failures are the pre-documented local-only macOS visual-baseline drift (architecture-islands-deep mobile × en/zh × dark/light), CI-skipped by design and green in authoritative CI at this SHA; identical in kind and count to the first record at aa3dd70f — the remediation neither fixed nor worsened them, as expected for a content-only delta. + +RESIDUAL_RISKS: +All seven residual risks from the first closure record carry forward unchanged (npm trusted-publisher registration, CodeQL main-scan closure, Beta.3 benchmark re-baseline, Desktop OEC9008 → #1311, local visual-baseline drift, advisory audit-citation drift, tarball byte non-determinism). New, minor: the durable claim is now qualitative and thus permanently non-falsifiable by count drift — the reverse failure mode (a gate now derives no number from these sentences) is accepted; if a future build ever fails to prerender a route or decouples the sitemap from routes, the public-routes spec + content-graph fail-closed check are the covering gates, not this sentence. + +PRODUCTION_CODE_UNCHANGED: yes + +PROMOTION_RECOMMENDATION: GO +``` + +## Basis for GO + +The first verification's full battery (19 rows) is green at aa3dd70f; the delta aa3dd70f..89d37365 is exactly the #1313 content remediation (2 content files + regenerated content-graph fingerprints, CI-green at the exact SHA), and every criterion the delta could affect re-passes at 89d37365. The sole NO-GO finding (F1) is closed with observable evidence in built output for both locales. Candidate 89d37365 is recommended for promotion to v0.44.0-beta.2. diff --git a/tools/check-package-artifacts-verifier.test.ts b/tools/check-package-artifacts-verifier.test.ts new file mode 100644 index 000000000..2e9ba7b1e --- /dev/null +++ b/tools/check-package-artifacts-verifier.test.ts @@ -0,0 +1,94 @@ +/** + * Independent release-verifier tests for tools/check-package-artifacts.ts + * (v0.44 Beta.2 closure, stage #1288, carried risk 8 / PR #1310). + * + * The package-artifacts gate re-packs from source before scanning, so its + * teeth cannot be demonstrated by poisoning a tarball on disk. These tests + * exercise scanExtractedPackage directly against synthetic package trees to + * prove the FORBIDDEN_LEGACY_PATHS / FORBIDDEN_LEGACY_SOURCE_PATTERNS rules + * fire — and that a clean tree produces zero violations. + */ +import { assert, assertEquals } from '@std/assert'; +import { scanExtractedPackage } from './check-package-artifacts.ts'; + +async function makePackageTree( + files: Record, +): Promise { + const root = await Deno.makeTempDir({ prefix: 'artifact-gate-verifier-' }); + for (const [relative, content] of Object.entries(files)) { + const path = `${root}/${relative}`; + await Deno.mkdir(path.slice(0, path.lastIndexOf('/')), { recursive: true }); + await Deno.writeTextFile(path, content); + } + return root; +} + +const HONEST_PACKAGE_JSON = JSON.stringify({ + name: '@openelement/element', + version: '0.44.0-beta.1', + type: 'module', + main: './src/index.js', + exports: { '.': './src/index.js' }, +}); + +Deno.test('artifact gate fires on a forbidden legacy v0.43 path (src/types.ts)', async () => { + const root = await makePackageTree({ + 'package.json': HONEST_PACKAGE_JSON, + 'src/index.js': 'export {};\n', + 'src/types.ts': 'export type VNode = { fake: true };\n', + }); + try { + const result = scanExtractedPackage('@openelement/element', root); + assert( + result.violations.some((v) => v.path.endsWith('src/types.ts')), + `expected a src/types.ts violation, got: ${JSON.stringify(result.violations)}`, + ); + } finally { + await Deno.remove(root, { recursive: true }); + } +}); + +Deno.test('artifact gate fires on the dead data-ssr-props channel export', async () => { + const root = await makePackageTree({ + 'package.json': HONEST_PACKAGE_JSON, + 'src/index.js': 'export const DATA_SSR_PROPS = "data-ssr-props";\n', + }); + try { + const result = scanExtractedPackage('@openelement/element', root); + assert( + result.violations.some((v) => v.message.includes('data-ssr-props')), + `expected a data-ssr-props violation, got: ${JSON.stringify(result.violations)}`, + ); + } finally { + await Deno.remove(root, { recursive: true }); + } +}); + +Deno.test('artifact gate fires on a legacy marker-hydration attribute literal', async () => { + const root = await makePackageTree({ + 'package.json': HONEST_PACKAGE_JSON, + 'src/index.js': 'el.setAttribute("data-signal-x", "1");\n', + }); + try { + const result = scanExtractedPackage('@openelement/element', root); + assert( + result.violations.some((v) => v.message.includes('marker-based hydration')), + `expected a marker-hydration violation, got: ${JSON.stringify(result.violations)}`, + ); + } finally { + await Deno.remove(root, { recursive: true }); + } +}); + +Deno.test('artifact gate stays silent for a clean compiled package tree', async () => { + const root = await makePackageTree({ + 'package.json': HONEST_PACKAGE_JSON, + 'src/index.js': 'export const version = 1;\n', + }); + try { + const result = scanExtractedPackage('@openelement/element', root); + assertEquals(result.violations, []); + } finally { + await Deno.remove(root, { recursive: true }); + } +}); From f780f2fcaa4b0afc6cea61cc069607304a8381ac Mon Sep 17 00:00:00 2001 From: DevBot Date: Fri, 4 Sep 2026 22:21:16 +0800 Subject: [PATCH 2/2] docs(v0.44): role-neutral phrasing in Beta.2 closure evidence (#1288) --- docs/evidence/2026-09-04-v044-beta2-closure-verification.md | 2 +- docs/evidence/2026-09-04-v044-beta2-reverification.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/evidence/2026-09-04-v044-beta2-closure-verification.md b/docs/evidence/2026-09-04-v044-beta2-closure-verification.md index ee44eab20..9c11e84f5 100644 --- a/docs/evidence/2026-09-04-v044-beta2-closure-verification.md +++ b/docs/evidence/2026-09-04-v044-beta2-closure-verification.md @@ -1,7 +1,7 @@ # v0.44 Beta.2 Closure Verification — independent verifier record - Date: 2026-09-04 -- Verifier: fresh `kimi-code` session, profile `.agents/v044-kimi-release-verifier.md` (no implementer/thinker session reuse) +- Verifier: fresh release-verifier session per the configured release-verifier profile under `.agents/` (no implementer/thinker session reuse) - Stage issue: #1288 (umbrella #1155, authority ADR-0151, Beta.1 record #1150) - Candidate SHA: `aa3dd70ff8e5c8dbee602f8f7acd8e3b9d3c2b2b` (dev tip, tree clean at session start) - CI at candidate: AutoFlow CI run 33871051171 SUCCESS, CodeQL run 33871051092 SUCCESS — both at the exact candidate SHA (verified via `gh run view … --json headSha`). diff --git a/docs/evidence/2026-09-04-v044-beta2-reverification.md b/docs/evidence/2026-09-04-v044-beta2-reverification.md index 8ed64548d..fdc0cf75b 100644 --- a/docs/evidence/2026-09-04-v044-beta2-reverification.md +++ b/docs/evidence/2026-09-04-v044-beta2-reverification.md @@ -1,7 +1,7 @@ # v0.44 Beta.2 Re-Verification Addendum — narrow F1-closure pass - Date: 2026-09-04 -- Verifier: fresh `kimi-code` session, profile `.agents/v044-kimi-release-verifier.md` (independent of the first verifier session and of the implementer) +- Verifier: fresh release-verifier session per the configured release-verifier profile under `.agents/` (independent of the first verifier session and of the implementer) - Scope: narrow re-verification of the sole NO-GO finding (F1) from `docs/evidence/2026-09-04-v044-beta2-closure-verification.md` after remediation PR #1313 (issue #1312), plus a regression screen over everything the remediation touched. - First-report integrity note: the first closure record was read in full. Its wide padded table column alignment is a `deno fmt` reflow artifact; the content itself (battery rows, F1 finding, fingerprints, residual risks) is coherent, internally consistent, and matches what the remediation targeted. Nothing beyond formatting appears altered.