fix(github): surface a warning when CI completeness can't be verified - #2403
Conversation
reduceLiveCiAggregate's only "absence" safety net for a workflow that never triggers at all (path-filtered out, or a broken YAML trigger — producing neither a check-run nor a check-suite entry) was missingConventionalValidateAggregate, hardcoded to this repo's own validate/changes/security/validate-code convention. For any other self-hosted repo without branch protection configured, a workflow that silently never starts is indistinguishable from one that doesn't exist, and folds into "passed" as long as some OTHER check ran and passed. Add a ciCompletenessWarning field to LiveCiAggregate, populated when the aggregate resolves to "passed" with no branch-protection required contexts configured (enforceRequiredOnly false). This never changes ciState or disposition — forcing "pending" would leave a self-hosted repo with no expected-checks config stuck waiting forever on a workflow that can structurally never complete. The main planner records it as an informational audit event (github_app.ci_completeness_unverified) so operators can notice and configure branch protection or an expected-checks list. The full fix (a generic, learned-or-configured expected-workflow-set comparison) is a separate, larger follow-up; this ships the "lower effort interim mitigation" the issue calls out as sufficient ahead of that.
|
Warning 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏸️ Gittensory review result - manual review recommendedReview updated: 2026-07-01 20:41:48 UTC
⏸️ Suggested Action - Manual Review
Review summary Nits — 6 non-blocking
Review context
Contributor next steps
Signal definitions
🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2403 +/- ##
=======================================
Coverage 95.73% 95.73%
=======================================
Files 223 223
Lines 24755 24758 +3
Branches 8970 8972 +2
=======================================
+ Hits 23699 23702 +3
Misses 433 433
Partials 623 623
🚀 New features to boost your workflow:
|
What
When no branch-protection required contexts are resolvable (
enforceRequiredOnly === false— common on repos without branch protection configured, or when the required-contexts fetch 403s), the only "absence" safety net inreduceLiveCiAggregatewasmissingConventionalValidateAggregate— hardcoded to this repo's own CI convention (avalidatecontext gated behindchanges/security/validate-code). For any other self-hosted repo with different job names, a workflow that never triggers for a given PR (path-filtered out, or a broken workflow YAML trigger) produces neither a check-run nor a check-suite entry — indistinguishable from "no such check exists" — and folds into"passed"as long as at least one other check ran and passed. A self-hosted maintainer expecting a non-required, path-filterede2e-testsjob to run on every PR would get no signal that it silently never ran.Fix
Ships the issue's own "lower-effort interim mitigation" rather than the full generalized fix (a learned-or-
.gittensory.yml-declared expected-workflow-set comparison), which the issue itself frames as a separate, larger follow-up.ciCompletenessWarning: string | nullfield toLiveCiAggregate.reduceLiveCiAggregatepopulates it when the aggregate resolves to"passed"with no branch-protection required contexts configured.ciState/disposition is never touched — forcing"pending"in this scenario would leave a self-hosted repo with no expected-checks config stuck waiting forever on a workflow that can structurally never complete (worse than the silent-pass it replaces).missingConventionalValidateAggregate) already forces"pending"— not"passed"— when its aggregate check is legitimately missing, the new warning can never fire for a properly-configured gittensory-convention repo; it's mathematically orthogonal to the existing mechanism, not a replacement for it.maybeRunAgentMaintenanceinsrc/queue/processors.ts) records the warning as an informationalgithub_app.ci_completeness_unverifiedaudit event (outcome: "completed", never"denied") — a nudge for the operator, not a gate blocker.Tests
toEqualassertion broke at runtime from the new field (not caught bytscsinceexpect().toEqual()isn't type-checked against the exact shape).fetchLiveCiAggregate: the warning is set when CI resolves to passed with no required contexts (workflow A passes, workflow B never appears at all); the warning is absent when required contexts ARE configured; the warning is absent whenciStateis anything other than"passed".processJob/agent-regate-pr: the audit event fires with the expected detail when the mocked aggregate carries a warning; it does NOT fire when the aggregate carries none.npx tsc --noEmitclean — wideningLiveCiAggregate's required fields surfaced 5 test-side mock objects needing the new field via the compiler.backfill.test.ts— 143 passed; fullqueue.test.ts— 204 passed.graphql-status-rollup.test.ts(the otherreduceLiveCiAggregatecall path) — 30 passed./* v8 ignore next */with a verified, non-hand-wavy invariant justification —ciCompletenessWarningis only ever set whenciState === "passed", which itself requires a truthyheadSha).npm run test:coverage: 5605 passed, 4 skipped (pre-existing/unrelated), 0 failed.npm audit --audit-level=moderate: 0 vulnerabilities.Advances #1936. Closes #2137.