Skip to content

fix(connect): close review validation gates - #112

Merged
btspoony merged 11 commits into
mainfrom
fix/connect-review-gates
Sep 22, 2026
Merged

btspoony merged 11 commits into
mainfrom
fix/connect-review-gates

Conversation

@auto-wood

@auto-wood auto-wood commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Pin the public C header to LF and verify committed header/native hashes against provenance.
  • Refresh the Windows carrier and provenance from a genuine Windows CI build, with a fail-closed verification result and a usable refresh artifact.
  • Restore the complete publish-strategy evidence cell and document the current eight TypeScript runtime dependencies.
  • Store C++ carrier .dll and .dylib files in Git LFS, with hydrated CI checkouts and consumer instructions. Keep the import library and provenance in ordinary Git.
  • Run required validation on every pull request and retain push-side path filters. The main ruleset requires the current 22 app-bound validation contexts, strict up-to-date checks, and an empty bypass list.

Verification

Verified commit: b445521f4f0bdcade29d58b2bd20362e7db484b8.

  • All 22 required validation checks completed successfully, including Greptile Review, Cursor, and CodeQL. Greptile confidence: 5/5; both review threads are resolved.
  • Windows and macOS carrier verification, symbols, and C++ smoke: passed.
  • CI, Xcframework, CodeQL, and docs build: passed.
  • Fresh GitHub clone: LFS pointers hydrate to the recorded DLL/dylib hashes; core.autocrlf=true checkout retains the LF header hash.
  • Initial stale-provenance run produced the genuine Windows refresh artifact and retained its failed final verification result.
  • GitHub Pages deployment remains a post-merge action; its separate PR deployment job is skipped.

Delivery

This PR is ready for maintainer confirmation after acceptance review. Merge and any subsequent release require explicit approval. The existing v0.14.0 release and repository history remain unchanged.

The Windows carrier recorded a2cc9025… as headerSha256 while the committed
header hashes 7b4b4472… on every LF checkout: `core.autocrlf=true` handed the
build CRLF bytes and the build path wrote them into the committed record, so a
consumer could not verify the header the carrier documents.

- `.gitattributes` pins the header to `text eol=lf`. It is hashed into the
  published carrier record, so its checked-out bytes must not depend on the
  checkout's end-of-line conversion; `text` still normalizes CRLF to LF on
  commit, so a CRLF blob cannot reach the repository either.
- `tooling/connect/cpp-build.mjs --verify --target <triple>` is the read-only
  consumer check: it hashes the committed header and staged native and fails
  when the record no longer describes them. The build path cannot report this
  drift because it re-records whatever it just hashed.
- The binding README documents the check next to the provenance contract.

Evidence: throwaway repo, clone with `-c core.autocrlf=true` — without the
attribute the checkout is CRLF and hashes a2cc9025… (the recorded win-x64
value); with it the checkout is LF and hashes 7b4b4472…. `--verify` passes for
osx-arm64 and reports the win-x64 header mismatch (exit 1); that recorded hash
is refreshed by a genuine Windows rebuild, never by editing the record.
A required PR context can never be satisfied when the workflow that owns it is
filtered out of the PR, so `ci.yml` (paths-ignore), `cpp-connect.yml`,
`docs.yml` and `xcframework.yml` (paths) drop their pull_request filters. Push
filters, job names, job semantics and workflow_dispatch are unchanged, and the
workflow comments now state why the PR side is unfiltered.

The two carrier lanes additionally run the new read-only provenance check
(`cpp-build.mjs --verify` for their own RID) before anything rebuilds, so a
header/native byte drift fails the lane instead of being rewritten into the
record.

Note for the ruleset owner: `connect-identity` runs always but its proof step is
still gated on the changed-path diff, and `release.yml` reuses the
verify-codegen/typescript/rust/verify-version names on pull_request:closed only,
so it cannot supply those contexts before merge.
Line 190 of `.mstar/specs/connect-publish-strategy.md` had collapsed into a
literal ellipsis, dropping the "Current package reality" dependency list, the
"Session-core ownership" rationale and part of the criterion reference.

Restored verbatim from 54c97d6 (the commit before #110) with only the version
fact updated, `rust-libp2p 0.56` → `0.57`; the file now differs from 54c97d6 by
that single token on that single line.
The two committed carriers are ~6 MB each (`spoke_connect_capi.dll` 5.60 MB,
`libspoke_connect_capi.dylib` 6.25 MB) and every refresh rewrote them in full,
so `.gitattributes` now routes `bindings/cpp/native/**/*.dll` and `**/*.dylib`
through LFS the way the Swift xcframework already is. The staged blobs become
pointers whose oids are the previous blob hashes, so the binary content is
unchanged — no rebuild and no hand-edited artifact, and git history is not
rewritten.

The Windows import library (`spoke_connect_capi.dll.lib`, 151 KB) and
`provenance.json` stay ordinary blobs: they are small, and every checkout —
including the lanes that only read or diff the record — must resolve them
without an LFS fetch. Go / Kotlin / Python natives are untouched.

Both `cpp-connect.yml` lanes now check out with `lfs: true`, so the symbol
check, the C++ smoke, the provenance check and the uploaded refresh artifact
all see real bytes rather than pointers.
…gers

Consumer acquisition paths for the C/C++ channel — `README.md`/`README_CN.md`,
`docs/how-to/connect-cpp-binding.md`, `docs/how-to/connect-native-bindings.md`,
`docs/packages/quick-start.md` and each CN twin — now carry the
`git lfs install` / `git lfs pull` step and say which files stay plain git
objects; EN/CN heading parity is unchanged.

`CONTRIBUTING.md` gains the git-lfs prerequisite, a "Refreshing the C carrier
natives" section (CI artifact → `git add --renormalize` staging → `--verify`),
the current required-check set with the rule that a new PR validation check is
registered in the `main` ruleset required checks in the same round, and the
corrected xcframework trigger (every pull request, not only FFI-surface
changes). `.mstar/specs/connect-binding-channels.md` records both facts in its
packaging table and §3.6, and the binding README notes the LFS boundary beside
the committed natives.
…drift

A failing verify step cancelled the rest of the Windows lane, so a stale
`provenance.json` also blocked the build, the smoke and the uploaded
`spoke-connect-win-x64` artifact — exactly the input the record has to be
refreshed from.

`Verify committed provenance` now carries `id: provenance` +
`continue-on-error: true`, and a final `Fail on provenance drift` step reads
that step's raw *outcome* and throws unless it was `success`. So the lane still
goes red while the committed bytes disagree (fail-closed, nothing absorbed),
but the refresh artifact is produced in the same run and the record can be
replaced by a genuine rebuild rather than a hand-edit.

The macOS lane keeps a hard failure: it produces no artifact, so nothing
downstream has to run for the drift to be actionable.
`connect-identity` is a required PR check, but its proof step was gated on a
`git diff` of `tooling/connect-identity-proof/`, `packages/spoke-connect-ts/`
and `ci.yml` — on any other PR the context reported success without running the
proof, which is indistinguishable from a real pass. The gate step is removed
(along with the `fetch-depth: 0` checkout it needed), so the proof runs on
every pull request and on pushes to `main`.

The job README, the TS-route spec's identity-proof section and the identity
parity knowledge note described the removed path filter; they now state the
unfiltered rule and why it is deliberate.
Two knowledge notes still described the pre-fix triggers, so their facts now
contradicted the workflows. Minimal factual updates, `last_updated: 2026-09-22`:

- `ci-assembled-committed-native-artifacts.md`: part 1 is "Required-check CI
  assembly" — `xcframework.yml` runs on every pull request because `xcframework`
  is a required check, and only the push side keeps the FFI-surface filter; the
  re-verify note and the "Non-FFI PR" example say the same. Push-filter and
  dispatch facts are unchanged.
- `integrator-docs-site-ssot-links.md`: the docs build/deadlink gates run
  unfiltered on pull requests (`Build docs site` is required); the push side
  keeps the `docs/**` + `tooling/docs/**` filter.
… index

L2 review I-1: two directly affected knowledge surfaces still described the
required PR gates as path-filtered.

- `.mstar/knowledge/README.md`: the identity-parity row said the
  `connect-identity` job was "(Node 24, fail-open path filter)" and the
  native-artifact row said "path-filtered build". Both now state the current
  fact — every pull request for a required check — and keep the push-side
  filter where it is real. Row source cells record the 2026-09-22 revision.
- `tooling-decisions/connect-swift-xcframework-ios-matrix.md` (lines 44-45):
  the assembly sentence and the re-verify clause now distinguish unfiltered
  `pull_request` execution from the retained push-side FFI-surface filter;
  `last_updated: 2026-09-22`.

No tests/build/lint/format run; documentation-only facts, no executable
surface touched.

@cursor cursor 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.

Risk: medium. Approved. Cursor Bugbot and Cursor Security Agent were not present after the first check poll, no applicable approval policy required human review, and reviewers were not assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

@greptile-apps

greptile-apps Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

The PR appears safe to merge; both previous findings are fully addressed and no new actionable issue remains.

Fix All in CursorFindings

  1. P1 Windows provenance stays stale ▶
Fix with agent prompt
### Issue 1
tooling/connect/cpp-build.mjs:270-276
The required Windows carrier check cannot pass at this head. `.gitattributes` now forces `spoke_connect.h` to LF, producing SHA-256 `7b4b4472…`, but the committed `win-x64` provenance still records `a2cc9025…`. Therefore `--verify` fails on every Windows checkout, and the final outcome check intentionally keeps `windows-smoke` red even after creating the refresh artifact. Commit the regenerated Windows provenance and artifact before merging.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

The latest changes close the two previous review findings by committing a genuinely rebuilt Windows carrier with matching provenance and restoring the complete TypeScript dependency evidence.

  • Refreshes the Windows DLL and records its current artifact and LF-normalized header hashes.
  • Completes the publish-strategy dependency inventory.
  • Keeps provenance validation fail-closed while allowing CI to upload a replacement artifact after drift.
  • Ensures required pull-request checks are scheduled without path-filter suppression.
  • Hydrates Git LFS carrier binaries in workflows that inspect or execute them.

Reviews (2) · Last reviewed commit: "docs(spec): complete connect dependency ..."

Comment thread tooling/connect/cpp-build.mjs
Comment thread .mstar/specs/connect-publish-strategy.md Outdated
@btspoony
btspoony merged commit b050e0c into main Sep 22, 2026
23 checks passed
@btspoony
btspoony deleted the fix/connect-review-gates branch September 22, 2026 11:37
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.

2 participants