7 Commits
Author SHA1 Message Date
Thomas Vincent b430f5b1ec fix(tests): make hooks, CI helpers and the i18n audit fail closed (#8457)
* fix(hooks): check staged blobs and fail closed in the changelog tools

The pre-commit hooks read working-tree files while claiming to check staged content, check-changelog.py passed when its base diff failed, and fold-changelog.py deleted fragments it had not validated.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(tests): make CI helper scripts fail when they check nothing

check_all_pages.sh passed without logging in or crawling, the sink inventory accepted ripgrep errors, install_packages.sh and copyright_year.sh lost their failures, and the LDAP spec asserted before navigation finished.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(i18n): audit only changed .po entries and keep contributor badges separate

audit_po.py failed every translation PR on pre-existing errors and matched non-printf text as conversions; update-contributors.py leaked badges between aliased contributors.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* docs(changelog): add fragment for #8457

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* test(e2e): move the pointer off the Deepness multiselect button

Deepness sets a zero body margin, so the unhovered #ms-button sits at the viewport origin and headless Chromium on Linux intermittently applies :hover to it.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* ci: pull pinned integration database from authenticated mirror

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

---------

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
2026-10-23 08:17:12 -04:00
Thomas Vincent e2a5f32ee9 fix(ci): [develop] harden dependency installs and Docker build boundaries (#8294)
* security(ci): constrain dependency installs and container build boundaries

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(docker): retain shipped runtime libraries in build context

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(tooling): quote gettext paths and honor Docker base selection

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* test(auth): use certificate expiry truth in rendering assertions

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(tooling): finish Docker layer and regex scan findings

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(ci): preserve documentation badge anchors without alternation

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* test(ci): preserve contributor badges and enforce Python coverage

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* ci: share changed-code coverage contracts and enforce shell policy

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(ci): enforce private review files and run path regressions

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* test: measure changed gettext shell coverage

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* test: pin coverage to the reviewed PR revision

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

---------

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
2026-10-14 22:52:37 -04:00
Thomas Vincent 13adf317c0 chore: stop pull requests conflicting each other on shared files (#7798)
* chore: resolve concurrent CHANGELOG appends with a union merge

Every PR lands on the same two anchors, so merging one reliably conflicts
the others on CHANGELOG alone.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
(cherry picked from commit 6bc8e63ecb)

* feat(changelog): take entries as fragment files instead of CHANGELOG edits

Every pull request edited one of two lines, so merging one conflicted the
rest. A file per change gives concurrent PRs nothing to collide over.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
(cherry picked from commit a8a0bfa29a)

* chore(security): drop line numbers from the tracked sink baselines

Both verifiers already strip the line before comparing, so the tracked
numbers carried no signal and rewrote 212 lines of baseline on any edit that
shifted code, conflicting every open pull request.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
(cherry picked from commit ccfd3d374b)

* fix(ci): rebase stale pull request branches instead of merging them

A merge update adds a commit per run, so branches accumulate snapshots of
old develop and re-conflict on every shared file they carry.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
(cherry picked from commit e9e33c77cd)

* test: match the escaping call rather than the exact source line

The literal assertions here required the uncast form while
PhpBinaryPathNullCoercionTest required the cast, so the two could not both
pass and whichever landed second broke the other.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
(cherry picked from commit 98cfc84756)

* fix(changelog): handle security entries in fragments and validation

Review caught the missing type. Security entries also take GHSA identifiers
and open a release section ahead of issue and feature entries, none of which
the first pass handled.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* docs: require Composer-managed dependencies

Prevent agents from committing third-party package trees and require composer.json plus composer.lock updates instead.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

---------

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
2026-08-25 21:10:50 -07:00
Thomas Vincent 2e372e5b88 Make PHP 8.1 dependency builds reproducible (#7746)
* Make PHP 8.1 dependency builds reproducible

* Tighten integration runner permissions

* Harden and standardize GitHub Actions

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* Restore ripgrep for security guards

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* Wait for Cacti daemon readiness in CI

* Satisfy strict shell policy in diagnostics

* Preserve Cacti config group ownership

* Run stateful Cacti checks as the web user

* Run privileged page-crawl harness as root

---------

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
2026-08-16 22:06:36 +01:00
Thomas VincentandTheWitness 458a1c30a1 feat(readme): add all-contributors recognition and daily update job (#7345)
* feat(readme): add all-contributors recognition and daily update job

- Add .all-contributorsrc and a Contributors section to README.md, badges
  derived from git log path analysis and PR review history
- Add a scheduled workflow that refreshes both from the GitHub API daily

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(contributors): resolve founder name aliases in daily refresh script

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(ci): correct contributors workflow YAML and script encoding

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* ci: refresh sink and hotspot baselines for upstream line shifts

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

---------

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: TheWitness <thewitness@cacti.net>
2026-07-24 22:06:53 -04:00
Thomas Vincent 649c4299be docs: document CHANGELOG ordering convention (#7318)
* docs: document CHANGELOG ordering convention

* ci: validate changelog ordering

* ci: require identifiers on new changelog entries
2026-07-15 16:47:36 -04:00
e24e78d77e ci: consolidate security and performance workflows (#7200)
* ci: add AI security review workflow for PRs

Adds a GitHub Actions workflow that runs on every PR targeting develop.
The job collects the PR diff, grep hits on changed PHP files (SQL sinks,
superglobal access, command execution, dynamic includes, file writes,
archive extraction), and 120-line excerpts from historically vulnerable
hotspot files. It feeds all of this to claude-opus-4-6 using a
structured security review prompt and posts the model's findings as a
PR comment.

The job fails (blocking merge) when the model returns "BLOCK PR". API
or infrastructure errors are non-fatal so they do not block unrelated
PRs.

Requires the ANTHROPIC_API_KEY repository secret. Fork PRs skip
gracefully when the secret is absent.

Closes #6936-related CI gap — continuous variant-class hunting on every
PR without manual triage overhead.

Signed-off-by: Thomas Vincent <thomasvincent@somethingwithproof.com>
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* ci: remove AI branding from security review workflow

Signed-off-by: Thomas Vincent <thomasvincent@somethingwithproof.com>
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* ci: add security posture and perf regression workflows

Add PHP-oriented parity guardrails similar to Spine modernization:
- new security posture workflow (TruffleHog, Semgrep SARIF, Scorecard,
  Composer audit, workflow policy checks)
- new performance regression workflow with hyperfine + RSS thresholds
- workflow policy checker script for pinned-action/strict-shell validation
- versioned CLI performance baseline file

Fixes #6822

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* ci: address copilot feedback on security and perf workflows

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* ci: fix scorecard install, sarif upload pin, and perf baseline bootstrap

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* ci: avoid github context interpolation in security review run steps

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* ci: gate secret-dependent steps and fix composer audit, sarif, artifact pins

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* ci: generate composer lock without --lock for audit

The --lock flag needs an existing composer.lock; Cacti ships none, so the audit step exited 3.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* ci: report composer audit advisories as non-blocking

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* ci: use a valid model id for the security review and cover security-review.yml in policy lint

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* ci: address review feedback on security and perf workflows

- grant issues:write so the security review can post PR comments
- harden i18n run step by passing github context via env vars
- fail the security gate when the API returns no usable text
- fetch origin/<base> before reading the trusted perf baseline

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* ci: harden review gate, workflow policy, and perf job

- security_review.py: gate on the model's parsed final-decision marker
  instead of a "BLOCK PR" substring match, which misfired on prose
  ("I would not BLOCK PR") and on the attacker-controlled diff echoing the
  instruction text back into the review body
- check-workflow-policy.py: also validate job-level reusable-workflow `uses:`
  and require docker:// references to be pinned by an @sha256 digest
- perf-regression.yml: skip the benchmark job on fork PRs so an untrusted
  fork cannot run baseline-defined commands during the bootstrap window

Co-Authored-By: Oz <oz-agent@warp.dev>

* ci: scope security review write permissions to the job

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

---------

Signed-off-by: Thomas Vincent <thomasvincent@somethingwithproof.com>
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Thomas Vincent <thomas@vincent.dev>
Co-authored-by: Oz <oz-agent@warp.dev>
Co-authored-by: TheWitness <thewitness@cacti.net>
2026-07-13 14:34:49 -04:00