Skip to content

feat(governance): offload generic checks to mature OSS tooling (#1156 B2.6) - #1294

Merged
SisyphusZheng merged 3 commits into
devfrom
feat/1288-b26-oss-governance
Sep 3, 2026
Merged

feat(governance): offload generic checks to mature OSS tooling (#1156 B2.6)#1294
SisyphusZheng merged 3 commits into
devfrom
feat/1288-b26-oss-governance

Conversation

@SisyphusZheng

@SisyphusZheng SisyphusZheng commented Sep 3, 2026

Copy link
Copy Markdown
Member

Refs #1156 (Beta.2 slice of stage #1288; ADR-0144, ADR-0151). Beta.2 bar met for all replacement/deletion scope; adoption candidates with no prior custom machinery are adopted or deferred with reasons below — see "Beta.3 remainder". Not using "Closes" so the issue stays open for the recorded remainder.

Problem

The repo carried bespoke implementations of generic governance concerns: a hand-rolled regex scanner for explicit any (tools/check-type-safety.ts), a hand-rolled secret-content regex scan inside check-repo-hygiene.ts, and no mature coverage at all for Markdown structure, workflow linting, or workflow security — while ADR-0144 already assigns those concerns to pinned OSS tools.

Owner

Single owner per concern after this PR (no dual authority):

Concern Owner Custom machinery status
Explicit-any ban deno lint no-explicit-any (deno.json) deleted (check-type-safety.ts + test + task + AutoFlow gate, −210 LOC)
Secret content scanning gitleaks 8.30.1 (CI step, version + SHA-256 pinned, .gitleaks.toml) deleted (SECRET_CONTENT_PATTERNS scan in check-repo-hygiene.ts)
Markdown structure markdownlint-cli2 0.23.2 (lint:markdown task + AutoFlow gate) none existed; thin config only
Workflow lint actionlint 1.7.12 (CI step, version + SHA-256 pinned) none existed
Workflow security zizmor 1.30.0 via zizmorcore/zizmor-action@v0.6.3 (SHA-pinned, registered in ACTION_VERSION_PINS) none existed
Action pin/registry policy check-action-pins.ts (unchanged, OE-owned) kept — see why-not below
npm package quality publint + @arethetypeswrong/cli, pinned, inside check-package-artifacts.ts against packed tarballs already integrated; residual custom code is OE-only invariants (ESM-only scan, runtime-free host-API scan, adapter-vite fixture absence) — verified overlap, nothing further deleted
Security scanning CodeQL (codeql.yml), dependency-review-action already in place

Full checker inventory (classification)

(a) Generic, replaceable → action taken

Custom check Verdict
check-type-safety.ts (explicit-any regex scan) Replaced by deno lint no-explicit-any; file, test, task, gate deleted
SECRET_CONTENT_PATTERNS in check-repo-hygiene.ts Replaced by gitleaks (strictly broader rule set); scan deleted. The 4-line tracked-credential-filename tripwire stays: gitleaks does not flag a tracked-but-empty credential file

(b) OpenElement-specific invariants → stay project-owned

check-action-pins.ts (action SHA registry + version-comment audit trail + dependency-review presence), check-workflow-slimming.ts (workflow-count cap, removed-workflow absence), check-project-workflow.ts (governance doc anchors), check-repo-hygiene.ts remainder (removed-package/AutoFlow2 residue, tracked generated artifacts, tracked-ignored files, large binaries), check-architecture-contract.ts, check-signal-protocol-boundary.ts, check-deno-api-free.ts, check-frozen-semantics.ts (ADR-0122), check-package-graph.ts, check-package-surface.ts, check-public-interface-snapshot.ts, verify-package-configs.ts, check-docs-truth.ts family (public/strategic/current/claims/www/text/evidence), check-version-anchors.ts, check-release-truth.ts, check-release-state-machine.ts, check-evidence-freshness.ts, check-supabase-migrations.ts, check-supabase-recipe-parity.ts, check-fullstack-boundary.ts, check-www-theme-tokens.ts, check-visual-baseline-duplicates.ts, check-coverage.ts, check-critical-path-tests.ts, check-audit-citations.ts, check-static-output-freeze.ts, check-public-docs-integrity.ts, check-v044-* stage gates, AutoFlow release-lane machinery (B2.7/B2.9 own its shrink).

Per-tool verdicts (issue-named candidates)

Tool Verdict Reason
actionlint Adopted Clean on all 8 workflows today; CI step fails non-zero (probed)
zizmor Adopted Fixed all 11 artipacked findings (persist-credentials: false on every read-only checkout); 4 suppressions carry in-band reasons (release-lane tag-push credential, pinned npm-floor install, two GitHub-controlled template expansions); self-repository style audit disabled in .github/zizmor.yml because ./ local-action form is already audited by check-action-pins. Offline audits only — deterministic
markdownlint-cli2 Adopted Thin .markdownlint-cli2.jsonc (gitignore-scoped, 7 structure rules green repo-wide after fixing 5 trailing-space + 3 EOF-newline violations); AutoFlow gate on push/ci/release
lychee Defer → Beta.3 Network-sensitive (ADR-0144: separate from deterministic gates); needs its own scheduled workflow but check-workflow-slimming caps workflows at 8 and we are at exactly 8 — raising the cap is a policy decision; no custom link checker exists to retire, so it is pure addition against this stage's net-reduction bar
gitleaks Adopted Replaces the custom secret regexes; GitHub secret scanning/push protection is disabled on the repo (verified via API) — see maintainer action below. 3 historical findings triaged as false positives (Stripe placeholder fixtures + a docs variable reference) and allowlisted by value in .gitleaks.toml
GitHub secret protection Maintainer action (settings, not code) Recommend enabling secret scanning + push protection (free for public repos); gitleaks CI gate is the in-repo control either way
publint + Are The Types Wrong Already adopted Pinned inside check-package-artifacts.ts against packed tarballs; overlap verified — custom remainder is OE-specific
CodeQL Already adopted codeql.yml, alerts adjudicated under #1281
OpenSSF Scorecard Defer → Beta.3 Report-only posture (gating on a score is not violation-based and is impractical as a hard gate); requires a new workflow, colliding with the workflow-count cap; adds badge/surface while this stage's bar is net reduction
Renovate Not switched — maintainer decision See below

Renovate vs Dependabot (decision point, not executed)

Repo currently uses Dependabot (.github/dependabot.yml, github-actions ecosystem only). ADR-0144 names "Renovate Deno manager". Switching buys Deno/JSR dependency discovery Dependabot lacks, but it changes update PR cadence/grouping, requires installing the Renovate GitHub App (external state), and invalidates the existing Dependabot history/PR flow. This needs an explicit maintainer decision; nothing in this PR changes dependency automation.

Before / after (governance surface)

Metric Before After Δ
Custom check scripts (tools/check-*.ts incl. tests) 58 56 −2
Custom checker LOC (this concern set) ~210 (type-safety + secret scan) 0 −210
deno.json tasks 100 100 0 (1 custom task → 1 thin mature-tool runner)
AutoFlow policy gates 54 54 0 (1 custom gate → 1 mature-tool gate)
Workflow files / CI jobs 8 / unchanged 8 / unchanged 0 (new tools are steps in the existing autoflow-ci job)
Generic-concern policy owners 2 custom (type-safety, secret regexes) 0 custom (deno lint, gitleaks) −2
New pinned tool configs 3 (.gitleaks.toml, .markdownlint-cli2.jsonc, .github/zizmor.yml, 42 LOC total) thin config only, no wrappers

Net: strictly down in custom scripts/checkers/policy owners; flat in tasks/gates/jobs; zero new workflows.

Evidence

Local, on this branch (macOS, Deno workspace):

  • RED probes (replacement catches real violations):
    • deno lint --rules-include=no-explicit-any on a planted const x: any → exit 1
    • markdownlint-cli2@0.23.2 on planted MD012/MD042 violations → exit 1
    • gitleaks on a planted AWS-shaped key → exit 1; full history scan of this repo → 0 leaks
    • actionlint on a planted bad runner label → exit 1; on the real tree → exit 0
    • zizmor --offline on a planted ${{ github.event.issue.title }} expansion → exit 14; on the real tree → 0 findings, exit 0
  • deno task lint → 0 (887 files, no-explicit-any now enabled)
  • deno fmt --check → 0 (1562 files)
  • deno task typecheck → 0
  • deno task test → 0 (1767 passed, 105 steps; starter workspace 150 passed)
  • deno task arch:check, repo:hygiene, workflow:check, workflow:check-slimming, actions:check-pins, lint:markdown, docs:truth, text-integrity:check, www:check-current-truth → all exit 0
  • deno task pack:dry-run → 0; deno task package-artifacts:check → 0 (5 packages; note: deno.json is strict-JSON parsed by tools/publish-npm.ts, so the lint-rule comment had to live outside deno.json)
  • This PR's own AutoFlow CI run is the authoritative in-CI evidence: the three new steps (actionlint, zizmor-action, gitleaks) pass in the autoflow-ci job. Two CI-only discoveries were fixed in follow-up commits: actionlint's shellcheck integration (absent on macOS) reported 6 findings (4 unused loop counters → _, 2 intentional idioms documented with in-band disable comments), and zizmor-action's default collection also audits dependabot.yml, where the dependabot-cooldown finding was fixed with a 7-day update cooldown.

Scope

Touched: deno.json (lint rule, task swap), tools/autoflow/policy.ts (gate swap), tools/check-action-pins.ts (register zizmor-action pin), tools/check-architecture-contract.ts (drop stale exclusion), tools/check-repo-hygiene.ts (delete secret scan), deleted tools/check-type-safety.ts + test, 3 new tool configs, 7 workflow files (new steps + persist-credentials), 4 www/content/blog Markdown whitespace fixes. No frozen-semantics paths touched; no package source changed; no public API changed.

Risk

  • persist-credentials: false added to 11 checkouts: verified by grep that no affected workflow runs git push/git fetch/gh against the repo; the release lane (which pushes the immutable tag) keeps its credential via a reasoned zizmor suppression. Release-lane dry-run at the next stage boundary will confirm.
  • Blog Markdown fixes are whitespace-only; content-truth gates (www:check-current-truth, full build inside deno task test) green.
  • New CI steps download pinned binaries from GitHub releases (SHA-256 verified in-step) — network-dependent but fail-closed.

Beta.3 remainder (recorded on #1156)

  1. lychee link checking (needs workflow-cap decision + link triage).
  2. OpenSSF Scorecard report-only lane (needs workflow-cap decision).
  3. markdownlint rule expansion: MD034 (bare URLs, 81 existing), MD040 (fenced-code language, 122 existing), MD025 (single-H1, www/content blog frontmatter pattern) — each needs a dedicated content pass, not a governance-PR drive-by.
  4. Renovate-vs-Dependabot maintainer decision (above).
  5. CODEOWNERS (needs maintainer/team handle decision); issue forms + PR template already exist and are gated by check-project-workflow.
  6. GitHub-generated release notes: release-lane concern, owned by B2.7/B2.9 shrink.
  7. Maintainer settings action: enable GitHub secret scanning + push protection.

…B2.6)

ADR-0144 implementation slice:

- Replace the bespoke explicit-any checker (tools/check-type-safety.ts +
  test + task + AutoFlow gate) with deno lint's no-explicit-any rule
  (AST-based, stricter, green on all 887 linted files).
- Adopt markdownlint-cli2@0.23.2 for Markdown structure (thin
  .markdownlint-cli2.jsonc, gitignore-scoped, rule set green repo-wide;
  fixes 5 trailing-space + 3 EOF-newline violations in www/content/blog).
- Adopt gitleaks 8.30.1 (CI step, binary pinned by version + SHA-256) for
  secret scanning; delete the custom SECRET_CONTENT_PATTERNS regex scan
  from check-repo-hygiene.ts. .gitleaks.toml allowlists only deliberate
  Stripe placeholder fixtures.
- Adopt actionlint 1.7.12 (CI step, binary pinned by version + SHA-256)
  for workflow linting; clean on all 8 workflows.
- Adopt zizmor via zizmorcore/zizmor-action@v0.6.3 (pinned SHA registered
  in ACTION_VERSION_PINS, offline audits, advanced-security off) for
  workflow security; fix all 11 artipacked findings with
  persist-credentials: false, and suppress 4 findings with in-band
  reasons (release-lane credential persistence, pinned npm floor,
  GitHub-controlled template expansions).
- .github/zizmor.yml disables only the self-repository style audit
  (./local-action form is already audited by check-action-pins).

Net governance surface: -1 custom checker (-210 LOC incl. tests), -1
custom task, -1 custom AutoFlow gate, zero new workflows/jobs.
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

APIError: Insufficient Balance

opencode session  |  github run

actionlint on the ubuntu runner runs shellcheck over every run block
(absent locally on macOS); fix the six findings it reported: four
unused loop counters renamed to _, an intentional SC2086 word-split
and an intentional SC2016 single-quoted EICAR signature documented
with in-band disable comments.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 3, 2026

Copy link
Copy Markdown

Deploying openelement with  Cloudflare Pages  Cloudflare Pages

Latest commit: f1db345
Status: ✅  Deploy successful!
Preview URL: https://0c897327.lessjs.pages.dev
Branch Preview URL: https://feat-1288-b26-oss-governance.lessjs.pages.dev

View logs

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

APIError: Insufficient Balance

opencode session  |  github run

zizmor-action audits dependabot.yml in addition to workflows (its
default input collection); fix the dependabot-cooldown finding with a
7-day bake-in period for github-actions updates.
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

APIError: Insufficient Balance

opencode session  |  github run

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