You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Make CI actually gate PRs to dev — green should mean mergeable, red should mean blocked. The workflows themselves are well built, but dev branch protection is empty, so every check currently runs as advisory, not as a gate.
What do you do today?
ci.yml, desktop-smoke.yml, codeql.yml all run on PRs and produce clear pass/fail signals.
gh api repos/Astro-Han/pawwork/branches/dev/protection returns no required_status_checks, no required_pull_request_reviews, and no ruleset. A red PR can still be merged.
Dependabot (.github/dependabot.yml) covers only github-actions; npm deps are never refreshed.
ci.yml runs bun turbo typecheck but no bun turbo lint, despite AGENTS.md stating "Lint only, no formatter."
No dependency / license review on PR (CodeQL scans source only, not the dependency graph).
husky is wired in via "prepare": "husky" but no user-level hooks exist under .husky/ — pure dead weight.
Action pinning is inconsistent within this repo: codeql.yml SHA-pins actions/checkout, ci.yml uses tag refs for the same action.
What would a good result look like?
Merging to dev is blocked unless ci / check, desktop-smoke / check, and codeql / analyze-js-ts all pass.
New dependency CVEs or disallowed licenses surface on the PR itself, not in post-merge triage.
Lint violations block merge (matches the AGENTS.md rule).
Dead tooling (husky) either does real work or is removed.
Action pinning policy is consistent and documented.
Which audience does this matter to most?
Not sure
Extra context
Refined 2026-04-20 after a multi-reviewer crosscheck (Claude Opus + Codex). Decisions and corrections are recorded at the bottom of this issue — the issue body is the durable record for this work.
P0 — branch protection / ruleset ✅ Done — ruleset dev-merge-gate (id 15292177) is active on dev as of 2026-04-20.
Enable a repo ruleset on dev with required status checks: ci / check, desktop-smoke / check, codeql / analyze-js-ts
Require conversation resolution before merge (via pull_request rule with required_review_thread_resolution: true)
Require branches to be up-to-date before merge (via strict_required_status_checks_policy: true)
Require PR path (no direct push to dev, enforced by pull_request rule with 0 approvals)
non_fast_forward — dev cannot be force-pushed
Note: "Require linear history" intentionally NOT enabled — see D2 below.
P1 — security & correctness gaps
Add bun turbo lint job to ci.yml — moved to follow-up track (see Out of scope). Repo has no lint infrastructure today: no package defines a "lint" script and turbo.json has no lint task. Wiring this up is a separate project.
Add actions/dependency-review-action@v4 on PR events — landed as a separate dependency-review.yml workflow. Initially used continue-on-error, revised during crosscheck to step-level warn-only: true. Verified on PR feat(ci): harden pre-merge workflows for dev gate #55: Dependency graph parses bun.lock correctly (job ran green, "Dependency Changes" group detected husky removal). Ready for follow-up PR to drop warn-only, set fail-on-severity: high, and add to the ruleset.
Verify GitHub secret scanning + push protection are enabled — confirmed via gh api on 2026-04-20: secret_scanning: enabled, secret_scanning_push_protection: enabled.
Expand Dependabot to bun ecosystem (originally drafted as npm; fixed during crosscheck) with explicit groups: stanzas (electron, typescript-tooling, turbo-build, testing, opencode, production/development catch-alls)
SHA-pin first-party actions across ci.yml, desktop-smoke.yml, e2e-artifacts.yml (to match codeql.yml and build.yml). Policy decision captured in D5.
P2 — hygiene
Audit every package's test:ci script to confirm exit codes propagate through bun turbo test:ci. Important: fail_on_failure: false at ci.yml:181 is on the JUnit reporter only and does NOT affect unit-job success — the real risk is per-package scripts swallowing failures before turbo ever sees them
Remove husky + "prepare": "husky" — landed; .husky/ was never populated, hook was dead
Consider adopting re-actors/alls-green as a single dynamic required check instead of a static list of check names — makes adding/renaming workflow jobs safe without editing the ruleset (deferred; threshold noted inline in ci.yml)
Add inline comment near the check job in ci.yml and desktop-smoke.yml reminding: "every added job must be listed in check.needs"
Add guard comment in e2e-artifacts.yml: this workflow uses continue-on-error: true by design and MUST NOT be added as a required check
P3 — polish
Add PR/issue title lint enforcing the [Feature] / [Bug] prefix (AGENTS.md convention)
Add commit message lint enforcing Conventional Commits (separate check from title lint)
Drop actions/setup-node from bun-only jobs unless a step actually needs the node CLI
Sequencing recommendation
Land P0 first — without branch protection, nothing else gates.
Pair dependency-review + Dependabot-npm as a single "supply-chain" slice: dependency-review lands first to verify bun.lock is parseable; Dependabot npm only flips on once the CVE gate is working.
Out of scope (decisions already made)
Windows CI on PRs — Phase 1 is macOS-only per AGENTS.md commitment 4.
Blocking e2e on PRs — e2e-artifacts.yml is intentionally non-blocking.
Desktop build in ci.yml — upstream-parity decision.
Docs-only PRs bypass typecheck / unit / desktop-smoke. The changes → docs_only → check passes shortcut in ci.yml:18-87 and desktop-smoke.yml:18-87 is by design. Trade-off: a README edit that breaks a fenced code block will not be caught by CI; manual PR review catches it. Not in scope to change.
Setting up lint infrastructure. Originally a P1 item, but the repo has no "lint" script in any package and no lint task in turbo.json. Adding a bun turbo lint CI job requires first picking a linter, configuring each package, and defining the task. That is a separate track from "make CI a real merge gate" and will get its own issue/PR.
Decisions recorded during refinement (2026-04-20)
D1 — CodeQL is a required check. PawWork is a desktop app that will execute user-authored skills and access the system keychain; solo-dev code review cannot substitute for a security scanner. Corrected from earlier draft: do not edit AGENTS.md — it is not tracked by git (see D3), so edits would only exist on the local machine and would not propagate to worktrees or clones. Decision is instead captured as an inline comment in codeql.yml and in this issue body.
D2 — Drop "Require linear history" from the ruleset. Project policy uses merge commits for own PRs; squash is reserved for upstream-sync PRs only. Linear history would forbid merge commits and break that flow.
D3 — Decision log lives in this issue body and inline comments in workflow files, not AGENTS.md. AGENTS.md is in .git/info/exclude and is not a tracked file; worktrees created from git do not see it. Git-tracked places (issue body, inline comments, PR descriptions) are the only durable records.
D4 — Renovate is not in scope. The Dependabot-vs-Renovate comparison for bun catalog: support is not backed by in-repo evidence; default to Dependabot with proper grouping (landed in this PR).
D5 — SHA-pin first-party actions across the repo. Decision taken during implementation: the "first-party trusted by tag" option was rejected because codeql.yml and build.yml already SHA-pin official actions; normalizing the rest removes the drift instead of documenting it.
Origin: internal CI audit + multi-reviewer crosscheck on 2026-04-20. Reviewers flagged a merge-flow contradiction (D2), an ambiguous AGENTS.md policy line (D1), an unverified "switch to Renovate" claim (D4), and an incorrect attribution of the silent-green risk to fail_on_failure (now corrected in P2).
Status at close (2026-04-20)
Closing as the main goal (P0 merge gate + P1 supply-chain + P2 husky cleanup) shipped in #55. Remaining items tracked separately; one P0 bullet above is out of date and corrected here.
Ruleset downgrade: required_status_checks was intentionally removed from ruleset dev-merge-gate after it blocked merges due to how the ruleset engine evaluates the test merge commit SHA. dev is now guarded by non_fast_forward + pull_request (PR path, conversation resolution); CI gating on ci / check, desktop-smoke / check, codeql / analyze-js-ts is enforced by convention and PR review rather than by ruleset. Revisit if/when the ruleset engine issue is resolved upstream, or if we add a second maintainer. The P0 checklist line "Enable a repo ruleset on dev with required status checks" should be read as "attempted and reverted" not "active".
Deferred, no issue filed: re-actors/alls-green evaluation — only relevant if we reinstate required status checks; revisit together with the ruleset question.
What task are you trying to do?
Make CI actually gate PRs to
dev— green should mean mergeable, red should mean blocked. The workflows themselves are well built, butdevbranch protection is empty, so every check currently runs as advisory, not as a gate.What do you do today?
ci.yml,desktop-smoke.yml,codeql.ymlall run on PRs and produce clear pass/fail signals.gh api repos/Astro-Han/pawwork/branches/dev/protectionreturns norequired_status_checks, norequired_pull_request_reviews, and no ruleset. A red PR can still be merged..github/dependabot.yml) covers onlygithub-actions; npm deps are never refreshed.ci.ymlrunsbun turbo typecheckbut nobun turbo lint, despite AGENTS.md stating "Lint only, no formatter."huskyis wired in via"prepare": "husky"but no user-level hooks exist under.husky/— pure dead weight.codeql.ymlSHA-pinsactions/checkout,ci.ymluses tag refs for the same action.What would a good result look like?
devis blocked unlessci / check,desktop-smoke / check, andcodeql / analyze-js-tsall pass.Which audience does this matter to most?
Not sure
Extra context
Refined 2026-04-20 after a multi-reviewer crosscheck (Claude Opus + Codex). Decisions and corrections are recorded at the bottom of this issue — the issue body is the durable record for this work.
P0 — branch protection / ruleset ✅ Done — ruleset
dev-merge-gate(id 15292177) isactiveondevas of 2026-04-20.devwith required status checks:ci / check,desktop-smoke / check,codeql / analyze-js-tspull_requestrule withrequired_review_thread_resolution: true)strict_required_status_checks_policy: true)dev, enforced bypull_requestrule with 0 approvals)non_fast_forward—devcannot be force-pushedNote: "Require linear history" intentionally NOT enabled — see D2 below.
P1 — security & correctness gaps
Add— moved to follow-up track (see Out of scope). Repo has no lint infrastructure today: no package defines abun turbo lintjob toci.yml"lint"script andturbo.jsonhas nolinttask. Wiring this up is a separate project.actions/dependency-review-action@v4on PR events — landed as a separatedependency-review.ymlworkflow. Initially usedcontinue-on-error, revised during crosscheck to step-levelwarn-only: true. Verified on PR feat(ci): harden pre-merge workflows for dev gate #55: Dependency graph parsesbun.lockcorrectly (job ran green, "Dependency Changes" group detected husky removal). Ready for follow-up PR to dropwarn-only, setfail-on-severity: high, and add to the ruleset.gh apion 2026-04-20:secret_scanning: enabled,secret_scanning_push_protection: enabled.npm; fixed during crosscheck) with explicitgroups:stanzas (electron, typescript-tooling, turbo-build, testing, opencode, production/development catch-alls)ci.yml,desktop-smoke.yml,e2e-artifacts.yml(to matchcodeql.ymlandbuild.yml). Policy decision captured in D5.P2 — hygiene
test:ciscript to confirm exit codes propagate throughbun turbo test:ci. Important:fail_on_failure: falseatci.yml:181is on the JUnit reporter only and does NOT affect unit-job success — the real risk is per-package scripts swallowing failures before turbo ever sees them"prepare": "husky"— landed;.husky/was never populated, hook was deadre-actors/alls-greenas a single dynamic required check instead of a static list of check names — makes adding/renaming workflow jobs safe without editing the ruleset (deferred; threshold noted inline inci.yml)checkjob inci.ymlanddesktop-smoke.ymlreminding: "every added job must be listed incheck.needs"e2e-artifacts.yml: this workflow usescontinue-on-error: trueby design and MUST NOT be added as a required checkP3 — polish
[Feature]/[Bug]prefix (AGENTS.md convention)actions/setup-nodefrom bun-only jobs unless a step actually needs the node CLISequencing recommendation
bun.lockis parseable; Dependabot npm only flips on once the CVE gate is working.Out of scope (decisions already made)
e2e-artifacts.ymlis intentionally non-blocking.ci.yml— upstream-parity decision.changes → docs_only → check passesshortcut inci.yml:18-87anddesktop-smoke.yml:18-87is by design. Trade-off: a README edit that breaks a fenced code block will not be caught by CI; manual PR review catches it. Not in scope to change."lint"script in any package and nolinttask inturbo.json. Adding abun turbo lintCI job requires first picking a linter, configuring each package, and defining the task. That is a separate track from "make CI a real merge gate" and will get its own issue/PR.Decisions recorded during refinement (2026-04-20)
codeql.ymland in this issue body..git/info/excludeand is not a tracked file; worktrees created from git do not see it. Git-tracked places (issue body, inline comments, PR descriptions) are the only durable records.catalog:support is not backed by in-repo evidence; default to Dependabot with proper grouping (landed in this PR).codeql.ymlandbuild.ymlalready SHA-pin official actions; normalizing the rest removes the drift instead of documenting it.Origin: internal CI audit + multi-reviewer crosscheck on 2026-04-20. Reviewers flagged a merge-flow contradiction (D2), an ambiguous AGENTS.md policy line (D1), an unverified "switch to Renovate" claim (D4), and an incorrect attribution of the silent-green risk to
fail_on_failure(now corrected in P2).Status at close (2026-04-20)
Closing as the main goal (P0 merge gate + P1 supply-chain + P2 husky cleanup) shipped in #55. Remaining items tracked separately; one P0 bullet above is out of date and corrected here.
required_status_checkswas intentionally removed from rulesetdev-merge-gateafter it blocked merges due to how the ruleset engine evaluates the test merge commit SHA.devis now guarded bynon_fast_forward+pull_request(PR path, conversation resolution); CI gating onci / check,desktop-smoke / check,codeql / analyze-js-tsis enforced by convention and PR review rather than by ruleset. Revisit if/when the ruleset engine issue is resolved upstream, or if we add a second maintainer. The P0 checklist line "Enable a repo ruleset ondevwith required status checks" should be read as "attempted and reverted" not "active".test:ciexit code propagation[Feature]/[Bug]title prefix on PRs and issuesactions/setup-nodefrom bun-only CI jobsre-actors/alls-greenevaluation — only relevant if we reinstate required status checks; revisit together with the ruleset question.