- lint-ultimate/action.yml: Add input validation step for linter-version
(regex allowlist) and linter type before shell interpolation, resolving
CodeQL code-injection findings (#discussion_r3685339915, #discussion_r3685339933)
- pr-summary.yml & review.yml: Switch from pull_request to
pull_request_target with explicit head SHA checkout, so fork PRs get
a write-capable GITHUB_TOKEN for comment posting
- tests/fixtures/js-{failing,passing}/package.json: Bump vitest from
^2.0.0 to ^3.2.6, resolving GHSA-5xrq-8626-4rwp (critical CVE)
Tier 1.1 of the quality expansion design. Adds the lint-ultimate
composite action that runs MegaLinter (or Super-Linter) over the
repo and emits a per-linter checks[] plus per-finding findings[]
envelope, matching the standard .agent/output.json contract.
## Changes
### Action
- .github/actions/lint-ultimate/action.yml: composite action, runs
oxsecurity/megalinter:v7 via Docker, uploads the JSON report and
stdout as lint-ultimate-reports artifact, uploads the envelope as
agent-output-lint for downstream consumers.
- .github/actions/lint-ultimate/build-envelope.sh: parses
megalinter-report.json, maps each linter category to a check[]
entry and each finding to a findings[] entry. Falls back to an
empty envelope when the report is missing or unreadable.
### Library
- .github/actions/agent-envelope.sh: add add_finding() helper
mirroring add_check(). Optional fields (rule, file, line, column,
suggested_fix) default to null; numbers coerce when non-empty.
### Library fixes (pre-existing bugs surfaced by the new test)
- GITHUB_REPOSITORY default and owner/repo prefix strip now set -u
safe. Previously the original --arg repo_name reference threw on
unbound-variable in any non-GitHub runner.
- GITHUB_RUN_ID now passed as --argjson (numeric or null) instead of
--arg with tonumber? in the filter. The prior form silently
produced empty output when run_id was unset (jq 1.8.2 quirk where
tonumber? on null returns Empty and jq emits no output).
### Schema
- .agent/schema.json: enum agent_action extended with all twelve new
values from the quality-check expansion design (lint-ultimate,
coverage, actionlint, codeql, lefthook-ci, test-matrix, reviewdog,
quality-gate, semantic-release, dependabot, docker-ci). Future
Tier 1/2/3 PRs pick the right value.
### Tests
- tests/: ship the previously untracked harness (run-action.sh,
run-all.sh, README.md, fixtures for all CI actions) plus the
new megalinter-passing and megalinter-failing fixtures.
- tests/unit/test-lint-ultimate-parser.sh: parser unit test that
runs build-envelope.sh against a fabricated megalinter-report.json
and asserts the envelope shape. No Docker required.
- tests/golden/lint-ultimate/README.md: documents that goldens are
generated on first real-CI run (per tests/README.md first-run
convention) and provides a no-Docker local check.
### Matrix
- tests/run-all.sh: megalinter-passing and megalinter-failing added
to MATRIX (paired with lint-ultimate action).
### Docs
- README.md: lint-ultimate row added to the CI Composite Actions
table; full example block added between python-ci and ---.
## Risk
- Pre-existing agent-envelope.sh changes affect all envelope-writing
callers; the same fixes apply everywhere (none had a green test
before). Behavior is unchanged when GITHUB_* env vars are set
(real CI).
- No existing tests to regress against (tests/ was untracked).
Unit test added in this PR exercises the new parser path.
Refs: docs/superpowers/specs/2026-07-30-code-quality-expansion-design.md
Capture five decisions + one re-sequencing note that unblock Tier 1:
- semantic-release emits agent_action 'semantic-release'; chain on
outputs.next-version rather than colliding with 'release'
- coverage artifacts use coverage-{lang} names; coverage action
downloads with pattern: coverage-*, merge-multiple: true
- codeql-analysis.yml uploads agent-output-codeql so the
quality-gate orchestrator can consume it via the standard channel
- semantic-release.yml trigger model: push -> version -> commit ->
tag -> repository_dispatch -> release.yml
- split dependabot config (3.2.1) from dependency-review workflow
(3.2.2); remove the standalone dependabot-envelope action
- single coverage-baseline mechanism: explicit commit only; remove
threshold-diff input and the auto-write baseline paragraph
- reorder Tier 1: actionlint before coverage so the upload-artifact
pattern is established first
- reframe reviewdog (#7) as a helper script in agent-envelope.sh,
not a standalone composite action
Refs: review of 2026-07-30-code-quality-expansion-design.md
On a fresh CI checkout (actions/checkout), git diff is empty, so ocr
scan's auto-discovery finds 0 files to review. Replace the bare
--path '.' with an explicit comma-separated file list built from find.
This ensures every file under SCAN_PATH is reviewed, matching the
behavior ocr scan shows when run locally with a dirty working tree.
Co-Authored-By: Claude <[email protected]>
The eval-based flag building used embedded quotes inside variables,
which shell interprets as literal quote characters. This caused
ocr scan --path '. to become --path with value '.'\'' (including
quotes), making it scan an empty directory set and exit immediately.
Fix: invoke ocr scan directly with properly quoted arguments,
using shell conditional expansion for the optional --no-plan flag.
Co-Authored-By: Claude <[email protected]>
Rewrite both ocr-review.yml and ocr-scan.yml to use direct CLI
invocation instead of the marketplace composite action, matching the
official OCR CI/CD documentation patterns.
Changes:
- ocr-review.yml: Replace alibaba/open-code-review@main action with
direct 'ocr review' CLI. Add --background (PR title context),
--concurrency (default 5), provider-based config (custom_providers.*),
credential validation via 'ocr llm test', version pin to 1.8.1.
- ocr-scan.yml: Switch to same provider config model. Add --concurrency
(default 5), --no-plan toggle (opt-out for speed, 'false' for quality).
Fix default model from claude-sonnet-4-20250514 to deepseek-v4-flash.
Add credential validation step.
- Design spec: docs/superpowers/specs/2026-07-30-ocr-workflow-optimization-design.md
Co-Authored-By: Claude <[email protected]>
Root cause: bash parses ${VAR:-{}} as "word={, default}" with the
trailing } treated as a literal append. Result: ${VAR:-{}} with
VAR set to {a:b,c:d} produces {a:b,c:d}} — the extra } closes
the root object early, making the rest of the JSON trailing garbage.
Verified from artifact hex at offset 0x103:
7d 7d 2c 0a = }},\n (double close brace before comma)
This corrupted .agent/output.json in scan PR #30561172584, causing
the Summarize step to fail with "Expected value before ',' at
line 11, column 3".
Fix: assign defaults via explicit if/then, then reference the
variable directly. Applies to all 5 JSON variables in BOTH the
primary jq path AND the heredoc fallback:
AGENT_OUTPUTS, AGENT_SUGGESTIONS, AGENT_CHECKS, AGENT_FINDINGS,
AGENT_RELEASE
Verified pre/post-fix produces:
pre : {"a":"b"}} (extra })
post : {"a":"b"} (clean)
From official docs at integrations/ci.md:
- Use llm.* config keys (llm.url, llm.auth_token, llm.model,
llm.use_anthropic) instead of custom_providers
- Add llm.extra_body to disable thinking mode for provider compat
- Model is configured via ocr config set, not --model flag
Docs ref: github.com/alibaba/open-code-review/blob/main/
pages/src/content/docs/en/integrations/ci.md
Root cause analysis (5-perspective adversarial review):
1. Wrong NPM package — used @open-code-review/cli (doesn't exist),
correct is @alibaba-group/open-code-review (verified on npmjs.com)
2. Missing LLM config — OCR_LLM_URL/OCR_LLM_TOKEN are custom env vars
OCR doesn't read. Added ocr config set step mapping to a custom
provider with the protocol/url/key from workflow secrets.
3. No install verification — previous install step swallowed all
errors with 2>/dev/null || true. Now uses npm install -g + ocr
scan --help + ocr llm test for fail-fast verification.
4. Wrong output path — scan --format json writes JSON to stdout, not
.ocr/result.json. Now captures stdout directly to .ocr/result.json.
5. Missing comments field in envelope — build-envelope.sh didn't
handle .comments[] from scan output (only handled .issues and
.review_comments). Added .comments extraction with field mapping.
Fixes:
- .github/workflows/ocr-scan.yml: Split into Install & Configure +
Run Scan steps. Correct package, LLM config via custom provider,
direct output capture, explicit --model flag.
- .github/actions/ocr-envelope/build-envelope.sh: Handle .comments[]
from scan output, map to uniform findings format with file/line/
message/severity, handle object-typed .summary field.
All workflow 'Summarize' / 'Read Agent Output' steps used
'cat file | jq ... >> ' pipelines. With
set -o pipefail (GitHub Actions default), a jq exit code 5 (parse
error on malformed JSON) would kill the entire step — even though
the envelope was written successfully.
Fix: Replace all cat|jq pipe patterns with direct 'jq -r ... file'
invocations. jq can read files directly without cat, and the error
handling uses 2>/dev/null || true for robust fallback when the file
happens to be malformed between write and read.
Co-Authored-By: Claude <[email protected]>
agent-envelope.sh's write_envelope was failing with 'jq: invalid JSON
text passed to --argjson' when AGENT_OUTPUTS contained malformed JSON
from uninitialized variables.
Fix: merged the jq call into a single 'if command -v jq && jq -n ...; then'
block with 2>/dev/null on the jq call. When jq fails (command not found or
bad --argjson input), it falls through to the simple cat fallback instead of
crashing with exit code 2.
This is the simpler and more robust approach — no extra validation logic,
no nested ifs. jq failure is non-fatal, period.
Co-Authored-By: Claude <[email protected]>
detect_stack/detect_hooks/query_github functions write variables to
GITHUB_ENV for downstream workflow steps, but the same shell session
needs them as local variables too. Added explicit defaults before the
function calls.
Also removed heredoc expansion fallback syntax (:-) since variables
now have guaranteed defaults set before they're used.
Co-Authored-By: Claude <[email protected]>
All scripts using the pattern AGENT_OUTPUTS=$(cat <<OUTPUTS ... OUTPUTS
were missing the closing ')' for the command substitution. This caused
'unexpected EOF while looking for matching )' errors at runtime.
Fixed 7 files: build-context.sh, watch-checks.sh, triage-issue.sh,
analyze-pr.sh, run-review.sh, run-release.sh, and the 3 write-envelope.sh
files (rust-ci, js-ci, python-ci).
Co-Authored-By: Claude <[email protected]>
Missing closing parentheses in command substitution on the
jq-less fallback path of add_suggestion and add_check:
- line 130: .../cat && echo ...])) was missing the final ))
- line 154: same pattern
Also removed set -euo pipefail since this is a sourced library,
not a standalone script.
Co-Authored-By: Claude <[email protected]>
When a workflow inside a repo references a composite action from the same
repo, it must use './.github/actions/name' — not 'org/repo/.github/actions/name@tag'.
The latter is for external repos and fails with 'Can't find action.yml'.
Fixed across all 10 workflow files.
Co-Authored-By: Claude <[email protected]>
- Removed Heretek-AI/heretek-actions self-reference from pre-commit config
(repo has no .pre-commit-hooks.yaml manifest)
- Removed mypy's types-all additional_dependencies which has yanked
packages (types-pkg-resources not found)
- Updated mypy rev to v1.15.0
Co-Authored-By: Claude <[email protected]>
pre-commit config referenced Heretek-AI/heretek-actions as a hook repo
but this repo doesn't have a .pre-commit-hooks.yaml manifest, causing
InvalidManifestError in CI.
Co-Authored-By: Claude <[email protected]>
Three issues causing all workflow runs to fail:
1. github_token is a reserved name in workflow_call secrets
- Renamed to repo_token across ocr-review, ocr-scan, release, and
check-status workflows. Updated all secrets.repo_token refs.
2. Shell scripts not executable (exit code 126)
- chmod +x all .sh files in .github/actions/
3. pre-commit types_or rejected 'typescript' type tag
- Changed to 'ts' in .pre-commit-config.yaml for eslint and prettier hooks
Co-Authored-By: Claude <[email protected]>
Users can now set OCR_LLM_MODEL as a GitHub secret to configure the
LLM model once at the repo/org level without exposing it in workflow files.
Resolution order: secrets.ocr_llm_model -> inputs.ocr-llm-model ->
vars.OCR_LLM_MODEL -> built-in default (claude-sonnet-4-20250514)
Updated both ocr-review and ocr-scan workflows plus README documentation.
Co-Authored-By: Claude <[email protected]>
Two new optional reusable workflows integrating alibaba/open-code-review into
the heretek-actions ecosystem:
- ocr-review.yml — AI-powered PR review on pull_request_target, with
re-trigger support via /open-code-review or @open-code-review comments.
Outputs .agent/output.json with findings for agent consumption.
- ocr-scan.yml — Full codebase scan on workflow_dispatch, scans the entire
repo (or a sub-path) using OCR CLI. Outputs agent envelope with scan
findings. Optional issue creation from findings.
Shared component:
- .github/actions/ocr-envelope/ — Composite action that reads OCR output
and writes the standardized .agent/output.json with status, findings, and
suggestions for agents to act upon.
Documentation:
- Updated README with OCR usage examples, configuration guide (secrets/vars),
and workflow table entries
Co-Authored-By: Claude <[email protected]>
Shell scripts (.sh) were sourcing agent-envelope.sh via the literal
GitHub Actions expression '${{ github.action_path }}', which doesn't get
evaluated by the shell — only in run: blocks in action YAML files.
Fix: Pass AGENT_ACTION_PATH as an environment variable from the action.yml
env block (where the runner evaluates the expression) and reference it as
${AGENT_ACTION_PATH} in shell scripts.
Also fix: date format bug (%Y repeated twice) in agent-envelope.sh
Co-Authored-By: Claude <[email protected]>