Skip to content

docs: CI integration recipe for the exit-code PR gate - #17

Merged
modusensus merged 1 commit into
mainfrom
docs/ci-integration
Sep 24, 2026
Merged

modusensus merged 1 commit into
mainfrom
docs/ci-integration

Conversation

@modusensus

@modusensus modusensus commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Closes the one gap the ChatGPT review surfaced: the exit-code contract (0/10/1/2) exists and is tested, but nothing shows how to wire it as a PR gate.

  • docs/ci-integration.md + -zh: copy-paste audit.yml (one step, npx euthyna@latest audit --base origin/<target>), the exit-code-to-merge-decision table, an optional two-step variant for when 10 should not block, artifact upload, and explicit does/does-not-answer boundaries (the workflow deliberately does not run gate).
  • README 'Not verified' gains the honest entry: the recipe is documented, not yet exercised as a live Actions run.

No CLI changes. npm test 207 pass / 0 fail on this tree before commit.

Summary by Sourcery

Document how to integrate the existing euthyna audit exit-code contract into GitHub Actions pull-request gates.

New Features:

  • Add English and Chinese GitHub Actions recipes for using euthyna audit as a pull-request gate, including exit-code guidance, optional handling for non-blocking findings, and report artifacts.

Enhancements:

  • Document the gate’s scope and limitations, including that it reports evidence for adjudication without running euthyna gate.
  • Clarify that the documented workflow has not yet been validated as a live GitHub Actions run.

Documentation:

  • Add bilingual CI integration documentation covering workflow setup, exit-code merge decisions, report access, and operational notes.

@sourcery-ai

sourcery-ai Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

Adds bilingual, copy-paste GitHub Actions guidance for using euthyna audit as a PR gate, including exit-code semantics, optional handling for code 10, artifact collection, and clear scope limitations; updates README to disclose that the recipe has not yet been validated in a live Actions run.

Flow diagram for PR gate exit-code decisions

flowchart TD
    A[Run euthyna audit] --> B{Exit code}
    B -->|0| C[Merge freely]
    B -->|10| D[Human reviews report before merging]
    B -->|1| E[Fix workflow usage]
    B -->|2| F[Never merge; fix measurement failure]
Loading

File-Level Changes

Change Details Files
Document a copy-paste GitHub Actions PR gate around the existing audit exit-code contract.
  • Add English and Chinese workflows using full-history checkout, Node setup, and npx euthyna@latest audit against the PR base.
  • Explain the meanings and merge handling for exit codes 0, 10, 1, and 2.
  • Provide an optional shell-based variant that allows code 10 while still failing other nonzero outcomes.
  • Show how to capture human-readable or JSON reports as artifacts.
  • Define the recipe’s measurement boundaries and explicitly exclude euthyna gate from the workflow.
  • Document history, stacked-PR, --pickaxe, and CLI version-pinning considerations.
docs/ci-integration.md
docs/ci-integration-zh.md
Make the project’s CI integration status explicit in the verification caveats.
  • Add that the CI recipe is documented but has not been exercised as a live GitHub Actions run.
README.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@modusensus
modusensus merged commit 718941b into main Sep 24, 2026
10 checks passed
@modusensus
modusensus deleted the docs/ci-integration branch September 24, 2026 04:28

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="docs/ci-integration.md" line_range="53-63" />
<code_context>
+
+```yaml
+      - name: 变更面审计(删除代码来源 + 依赖锁定版本)
+        run: |
+          npx --yes euthyna@latest audit --base "origin/${{ github.base_ref }}" --head HEAD
+        continue-on-error: true
+        id: audit
+      - name: 执行契约(10 = 留给人工审阅,其余非零失败)
+        if: always()
+        run: |
+          code=${{ steps.audit.outcome == 'success' && 0 || 1 }}
+          if [ "$code" -eq 0 ]; then exit 0; fi
+          echo "euthyna audit 未测成干净(或发现了 security 分类的历史);见上一步。" >&2
+          exit 1
+```
+
</code_context>
<issue_to_address>
**issue (bug_risk):** The optional two-step workflow cannot distinguish exit code `10` from exit codes `1` and `2`: every non-successful audit outcome is converted to `1`, so the enforcement step fails for flagged audits as well as measurement or usage errors. This contradicts the stated purpose of allowing `10` not to block merges.

**Triggers:** When a repository copies the two-step variant intending security-classified findings (`10`) to remain mergeable.

**Suggested fix:** Capture the audit process exit code explicitly, for example by writing `$?` to `GITHUB_OUTPUT` before enabling `continue-on-error`, then allow only code `10` and fail for `1` or `2`.
</issue_to_address>

### Comment 2
<location path="docs/ci-integration.md" line_range="75-84" />
<code_context>
+        id: audit
+      - name: 执行契约(10 = 留给人工审阅,其余非零失败)
+        if: always()
+        run: |
+          code=${{ steps.audit.outcome == 'success' && 0 || 1 }}
+          if [ "$code" -eq 0 ]; then exit 0; fi
+          echo "euthyna audit 未测成干净(或发现了 security 分类的历史);见上一步。" >&2
+          exit 1
+```
+
+`ponytail:` 两步版用 shell 重述了一遍退出码,把 `10` 和 `2` 混在一起;一步版才是诚实的
+门禁。只有当 `10` 不该挡合并时才用两步版。
+
+## 把报告挂到 PR 上
+
+运行会把人类可读的报告打进步骤日志。要作为附件挂到 PR 上:
+
+```yaml
+      - name: 变更面审计
+        run: |
+          npx --yes euthyna@latest audit --base "origin/${{ github.base_ref }}" --head HEAD \
+            | tee audit-report.txt
+        continue-on-error: true
+        id: audit
+      - uses: actions/upload-artifact@v4
+        if: always()
+        with:
+          name: euthyna-audit-report
+          path: audit-report.txt
+```
+
</code_context>
<issue_to_address>
**issue (broader_impact):** The artifact-upload recipe pipes `euthyna audit` into `tee` without enabling `pipefail`, so the shell reports `tee`'s successful status instead of the audit's exit code. A usage error, unmeasured result, or flagged result therefore makes this copied workflow step succeed and can silently turn the purported PR gate green.

**Triggers:** When this artifact snippet is used as the audit step in a gating workflow.

**Suggested fix:** Enable `set -o pipefail` before the pipeline, or capture the audit status explicitly while still writing the report file.
</issue_to_address>

Sourcery assessment

Approval pending. 2 findings to address first.

Blocking findings: docs/ci-integration.md:63, docs/ci-integration.md:84


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread docs/ci-integration.md
Comment on lines +53 to +63
run: |
npx --yes euthyna@latest audit --base "origin/${{ github.base_ref }}" --head HEAD
continue-on-error: true
id: audit
- name: Enforce the contract (10 = review, anything else non-zero fails)
if: always()
run: |
code=${{ steps.audit.outcome == 'success' && 0 || 1 }}
if [ "$code" -eq 0 ]; then exit 0; fi
echo "euthyna audit did not measure clean (or found security-classified history); see the step above." >&2
exit 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): The optional two-step workflow cannot distinguish exit code 10 from exit codes 1 and 2: every non-successful audit outcome is converted to 1, so the enforcement step fails for flagged audits as well as measurement or usage errors. This contradicts the stated purpose of allowing 10 not to block merges.

Triggers: When a repository copies the two-step variant intending security-classified findings (10) to remain mergeable.

Suggested fix: Capture the audit process exit code explicitly, for example by writing $? to GITHUB_OUTPUT before enabling continue-on-error, then allow only code 10 and fail for 1 or 2.

Comment thread docs/ci-integration.md
Comment on lines +75 to +84
run: |
npx --yes euthyna@latest audit --base "origin/${{ github.base_ref }}" --head HEAD \
| tee audit-report.txt
continue-on-error: true
id: audit
- uses: actions/upload-artifact@v4
if: always()
with:
name: euthyna-audit-report
path: audit-report.txt

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (broader_impact): The artifact-upload recipe pipes euthyna audit into tee without enabling pipefail, so the shell reports tee's successful status instead of the audit's exit code. A usage error, unmeasured result, or flagged result therefore makes this copied workflow step succeed and can silently turn the purported PR gate green.

Triggers: When this artifact snippet is used as the audit step in a gating workflow.

Suggested fix: Enable set -o pipefail before the pipeline, or capture the audit status explicitly while still writing the report file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant