Darwin-only code is never compiled, linted, or tested by CI, including both hardware-backed unlockers #50

Open
opened 2026-08-09 03:46:49 +02:00 by clawbot · 0 comments
Collaborator

A structural blind spot rather than a single defect. It came up as a caveat in every one of the 1.0 surveys and in the PR #29 review, which explicitly could not verify behavior preservation for these files.

Problem

CI runs on Linux. Every Darwin-gated file is therefore invisible to it — not compiled, not vetted, not linted, not tested:

  • internal/secret/keychainunlocker.go (583 lines)
  • internal/secret/seunlocker_darwin.go (385 lines)
  • internal/secret/helpers_darwin.go
  • internal/macse/macse_darwin.go plus its .h and .m sources
  • the corresponding test files

That is roughly a thousand lines of Go plus Objective-C, covering both hardware-backed unlockers — Keychain and Secure Enclave — which the README presents as headline features and which are the ones users are most likely to trust with a long-term vault key.

The practical consequences are already visible across this milestone:

  • A green CI is not evidence for any change touching these files. Several issues on this milestone (#36, #38, #42, #47) modify them, and each carries a manual "state how you verified this" clause purely to compensate.
  • The two longest functions in the codebase, CreateKeychainUnlocker (136 lines) and CreateSecureEnclaveUnlocker (101 lines), live here and are exempt from funlen, cyclop, and everything else.
  • TODO.md already records that these files contain lines over the 88-column limit that will surface the moment lint runs on macOS — meaning the tree is known-not-lint-clean and CI cannot say so.
  • A missed import in a build-tagged file during the #43 module rename would produce a green CI and a broken macOS build.

The gap is widest exactly where the security stakes are highest: keychainunlocker.go is the file in #36 that holds a vault-key passphrase as a plain string, and it is the file no automated check has ever examined.

Definition of done

Something in CI type-checks and lints the Darwin sources on every push. In rough order of preference:

  • A GOOS=darwin cross-compile check plus a golangci-lint run configured for the Darwin build tags, both from a Linux runner. This catches compile errors, vet failures, and lint violations without needing a Mac. Cgo is the complication — internal/macse links against Objective-C and Apple frameworks — so this may cover the pure-Go Darwin files while internal/macse stays excluded. Partial coverage is a real improvement and is an acceptable outcome, provided what remains uncovered is stated explicitly rather than left implicit.
  • Failing that, a documented manual verification checklist that any PR touching these files must complete, referenced from REPO_POLICIES.md or the README.

Also required:

  • The known 88-column violations in these files are fixed, so that whatever check is added starts green.
  • A new make target or script/ entrypoint wraps whatever check is chosen, so contributors can run it locally the same way CI does. Policy: the Makefile is the single source of truth for how operations are run.
  • The gate is wired into script/check or the CI workflow so it cannot be skipped by forgetting.
  • TODO.md updated in the same commit; its existing note about unlinted Darwin files is resolved or narrowed to whatever genuinely remains uncovered.

Implementation requirements

  • Cross-compiling with CGO_ENABLED=0 will not build internal/macse. Establish what is achievable before designing the gate, and report the finding on this issue if the answer is "less than hoped" — an honest partial gate beats a broken full one.
  • If a macOS runner is available to this Gitea instance, that is the better answer and changes the shape of this work entirely. If you do not know whether one exists, ask on this issue rather than assuming — the answer determines the design.
  • Do not disable or loosen any linter to make these files pass. Fix the code. If a violation cannot be fixed without a behavior change, note it and leave it.
  • Do not attempt to also fix the substantive defects in these files. #36, #38, #42, and #48 own those, and each becomes materially safer once this gate exists — which is an argument for sequencing this earlier rather than later among the Darwin-touching work.
A structural blind spot rather than a single defect. It came up as a caveat in every one of the 1.0 surveys and in the PR #29 review, which explicitly could not verify behavior preservation for these files. ## Problem CI runs on Linux. Every Darwin-gated file is therefore invisible to it — not compiled, not vetted, not linted, not tested: - `internal/secret/keychainunlocker.go` (583 lines) - `internal/secret/seunlocker_darwin.go` (385 lines) - `internal/secret/helpers_darwin.go` - `internal/macse/macse_darwin.go` plus its `.h` and `.m` sources - the corresponding test files That is roughly a thousand lines of Go plus Objective-C, covering **both hardware-backed unlockers** — Keychain and Secure Enclave — which the README presents as headline features and which are the ones users are most likely to trust with a long-term vault key. The practical consequences are already visible across this milestone: - A green CI is not evidence for any change touching these files. Several issues on this milestone (#36, #38, #42, #47) modify them, and each carries a manual "state how you verified this" clause purely to compensate. - The two longest functions in the codebase, `CreateKeychainUnlocker` (136 lines) and `CreateSecureEnclaveUnlocker` (101 lines), live here and are exempt from `funlen`, `cyclop`, and everything else. - `TODO.md` already records that these files contain lines over the 88-column limit that will surface the moment lint runs on macOS — meaning the tree is known-not-lint-clean and CI cannot say so. - A missed import in a build-tagged file during the #43 module rename would produce a green CI and a broken macOS build. The gap is widest exactly where the security stakes are highest: `keychainunlocker.go` is the file in #36 that holds a vault-key passphrase as a plain string, and it is the file no automated check has ever examined. ## Definition of done Something in CI type-checks and lints the Darwin sources on every push. In rough order of preference: - A `GOOS=darwin` cross-compile check plus a `golangci-lint` run configured for the Darwin build tags, both from a Linux runner. This catches compile errors, vet failures, and lint violations without needing a Mac. Cgo is the complication — `internal/macse` links against Objective-C and Apple frameworks — so this may cover the pure-Go Darwin files while `internal/macse` stays excluded. **Partial coverage is a real improvement and is an acceptable outcome**, provided what remains uncovered is stated explicitly rather than left implicit. - Failing that, a documented manual verification checklist that any PR touching these files must complete, referenced from `REPO_POLICIES.md` or the README. Also required: - The known 88-column violations in these files are fixed, so that whatever check is added starts green. - A new `make` target or `script/` entrypoint wraps whatever check is chosen, so contributors can run it locally the same way CI does. Policy: the Makefile is the single source of truth for how operations are run. - The gate is wired into `script/check` or the CI workflow so it cannot be skipped by forgetting. - `TODO.md` updated in the same commit; its existing note about unlinted Darwin files is resolved or narrowed to whatever genuinely remains uncovered. ## Implementation requirements - Cross-compiling with `CGO_ENABLED=0` will not build `internal/macse`. Establish what is achievable before designing the gate, and report the finding on this issue if the answer is "less than hoped" — an honest partial gate beats a broken full one. - If a macOS runner is available to this Gitea instance, that is the better answer and changes the shape of this work entirely. **If you do not know whether one exists, ask on this issue rather than assuming** — the answer determines the design. - Do not disable or loosen any linter to make these files pass. Fix the code. If a violation cannot be fixed without a behavior change, note it and leave it. - Do not attempt to also fix the substantive defects in these files. #36, #38, #42, and #48 own those, and each becomes materially safer once this gate exists — which is an argument for sequencing this earlier rather than later among the Darwin-touching work.
clawbot added this to the 1.0.0 milestone 2026-08-09 03:46:49 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/secret#50