* ci(security): run deterministic eval tests in affected-area CI (Task 04)
The build-check job validated build + suite structure but never ran the
tests, and its summary referenced a `test:ci` script that did not exist.
Make affected-area CI meaningful:
- Add `test:ci` to evals/framework running the offline, deterministic
Vitest allowlist (7 files / 112 tests) — no model, network, or paid
execution.
- Add a required "Run deterministic tests" step to build-check; a failure
fails the job and the existing PR summary gate (which keys on
build-check.result) fails closed.
- Correct the summary note to state test:ci runs the deterministic
allowlist and that model/network agent suites are excluded on PRs.
The broader deterministic suite has 3 pre-existing failing files
(framework-confidence, logger, test-runner; confirmed failing before this
work) which are intentionally out of the allowlist and tracked separately.
Validated locally: build, validate:suites:all, and test:ci all exit 0.
* ci(security): least privilege permissions + pin actions to SHAs (Task 05)
Harden all 9 GitHub Actions workflows:
Least privilege:
- Add explicit top-level `permissions: contents: read` to installer-checks,
validate-test-suites, and opencode (opencode's job keeps the writes it
needs; the top level now defaults to read).
- Every workflow now declares an explicit top-level permissions block.
- Write scopes retained only where justified (releases, doc/registry
commits, follow-up PRs, and sync-docs' issues.create).
Immutable action pinning:
- Pin every `uses:` to a full 40-char commit SHA with a version comment,
including first-party actions/* (checkout, github-script, setup-node,
upload-artifact) and third-party (oven-sh/setup-bun).
- Replace the two mutable refs that could change under us at any push:
ludeeus/action-shellcheck@master and sst/opencode/github@latest.
Record all SHAs, versions, and permission justifications in
docs/maintenance/repository-recovery/action-pin-inventory.md.
Verified: all 9 workflows parse as valid YAML; no floating tag/branch refs
remain; every workflow has a top-level permissions block.
* docs(security): add SECURITY.md and private-reporting checklist (Task 06)
- Add root SECURITY.md: supported versions (0.7.x), private reporting via
GitHub's "Report a vulnerability", best-effort response expectations,
coordinated disclosure, and no-secret guidance.
- Add private-vulnerability-reporting checklist that separates repository
file work (this PR) from GitHub settings changes that require their own
approval (Task 07: enabling private vulnerability reporting).
No external links to validate; the reporting path uses the repo Security
tab. SECURITY.md documents the private reporting path ahead of Task 07
enabling it.
* ci(security): add dependency governance and ownership controls (Task 08)
- .github/dependabot.yml: weekly grouped github-actions updates (keeps the
Task 05 SHA pins current). Scoped to actions only — the primary lockfile
is bun.lock and Dependabot's npm ecosystem would desync it; npm
dependency risk is covered by dependency-review below.
- .github/workflows/dependency-review.yml: runs on PRs with contents: read,
SHA-pinned actions, fail-on-severity: high to block newly introduced
high-severity vulnerabilities (exceptions documented inline).
- .github/CODEOWNERS: default owner @darrenhinde with explicit ownership of
security-sensitive paths (workflows, dependabot, CODEOWNERS, SECURITY.md,
scripts/validation).
Verified: dependabot.yml and dependency-review.yml are valid YAML;
dependency-review actions are SHA-pinned with contents: read; CODEOWNERS
owner is the repository owner.
* docs(security): record GitHub security settings evidence (Task 07)
Enable private vulnerability reporting and record read-back evidence.
Settings changed (each approved immediately before, verified by read-back):
- Private vulnerability reporting: enabled=false -> enabled=true. The
Security tab now offers "Report a vulnerability", making the path
documented in SECURITY.md live.
- Dependency Graph / Dependabot alerts: 404 -> 204. This was an
undocumented prerequisite of Task 08's dependency-review.yml, which
failed with "Dependency graph is not enabled"; the Dependency Review
check on PR #336 went fail -> pass after enabling it.
No other repository setting was modified; secret scanning and push
protection are unchanged, and dependabot_security_updates remains disabled
(out of scope, would need its own approval). Both changes are reversible
via the corresponding DELETE calls.
Marks Part B of the private-vulnerability-reporting checklist complete.
* fix(ci): remove [skip ci] from version bump commits to allow PR checks
The [skip ci] flag was preventing PR checks from running on version bump PRs,
making it impossible to validate them before merge.
Changes:
- Remove [skip ci] from version bump commit message
- Update skip pattern to be more specific: '^chore: bump version to v'
- Rely on 3-layer loop prevention:
1. Primary: PR label checking (version-bump, automated)
2. Secondary: Commit title pattern matching
3. Removed: [skip ci] flag (was blocking PR checks)
This allows PR checks to run while still preventing infinite loops through
label-based detection and commit title pattern matching.
* chore: trigger CI checks
- Rename workflow: 'Post-Merge Version & Docs Sync' → 'Post-Merge Version Bump'
- Rename job: 'Create Version & Docs Sync PR' → 'Create Version Bump PR'
- Update branch naming: 'chore/version-docs-sync-*' → 'chore/version-bump-*'
- Update PR title: 'chore: version and docs sync v*' → 'chore: bump version to v*'
- Remove confusing 'Documentation Sync' section from PR body
- Simplify skip patterns (remove 'docs: sync' pattern)
- Remove 'documentation' label from version bump PRs
- Add note clarifying that docs are handled by separate workflow
This makes it clear that version bumps and documentation syncs are
separate workflows with different triggers and purposes.
* fix(ci): check only commit title for skip patterns
The workflow was incorrectly checking the entire commit body for [skip ci]
patterns, causing false positives when the body mentioned these patterns
in documentation.
Fixed by:
- Check only commit title (first line) for skip patterns
- Use git log --pretty=%s instead of %B for skip detection
- Still use full body for version bump type detection
This prevents false positives while maintaining loop prevention.
* chore: trigger CI checks
* feat(ci): implement PR-based version bumps with docs sync
Replace direct-push version bumping with PR-based workflow that respects
branch protection rules and combines version updates with documentation sync.
## Changes
### New Workflow: post-merge-pr.yml
- Creates automated PR for version bumps instead of pushing directly
- Combines version bump with documentation sync in single PR
- Respects branch protection rules (no bypass needed)
- Follows semantic versioning based on commit message
- Updates VERSION, package.json, and CHANGELOG.md
- Labels PR for easy identification
### Workflow Behavior
- Triggers on push to main (after PR merge)
- Detects version bump type from commit message (feat/fix/breaking)
- Creates branch: chore/version-docs-sync-TIMESTAMP
- Commits version changes with [skip ci] to prevent loops
- Creates PR with detailed description
- Allows manual review before version is applied
### Benefits
- ✅ Works with branch protection (no special permissions needed)
- ✅ Combines version + docs in one reviewable PR
- ✅ Maintains audit trail through PR process
- ✅ Allows manual adjustments before merge
- ✅ Prevents accidental version bumps
- ✅ Clear separation of concerns
### Disabled
- post-merge.yml → post-merge.yml.disabled (old direct-push workflow)
## Migration Notes
Going forward:
1. Merge PR to main
2. Workflow creates version bump PR automatically
3. Review and merge version bump PR
4. Manually create GitHub release (or add release workflow later)
This fixes the branch protection issues that were blocking automated version bumps.
* chore: trigger CI checks
* fix(ci): prevent version bump loop by checking PR labels
Add PR label detection to prevent infinite loop:
- Check if merged PR had 'version-bump' or 'automated' labels
- Skip version bump workflow if labels are present
- This prevents version bump PRs from triggering more version bump PRs
Flow:
1. Regular PR merges → Creates version bump PR (with labels)
2. Version bump PR merges → Detects labels → Skips workflow ✅
This ensures only actual feature/fix PRs trigger version bumps.