Skip to content

feat(triage): generalize workflow-change block into block_auto_promotion - #1078

Open
rh-hemartin wants to merge 1 commit into
mainfrom
feat/2207-block-auto-promotion
Open

feat(triage): generalize workflow-change block into block_auto_promotion#1078
rh-hemartin wants to merge 1 commit into
mainfrom
feat/2207-block-auto-promotion

Conversation

@rh-hemartin

@rh-hemartin rh-hemartin commented Aug 28, 2026

Copy link
Copy Markdown
Member

Summary

Replace the single-purpose requires_workflow_changes boolean with a general-purpose block_auto_promotion object (blocked + reason). Workflow-file detection now uses that field so later gates (effort scoring) can reuse the same post-script path and attach a reason.

This is the first of two slices split from feat/2207-effort-gating. Effort estimation is not in this PR.

Ref fullsend-ai/fullsend#2207

Behavior

  • For bug/documentation/performance, block_auto_promotion.blocked=true applies triaged instead of ready-to-code and appends the reason to the triage comment.
  • Categories that already go to triaged (feature, security, other) are unchanged.
  • requires_workflow_changes stays optional in the schema for one release. When block_auto_promotion is absent, requires_workflow_changes: true still blocks auto-promotion.
  • The post-script sanitizes :: sequences in the reason, strips paired line-start fenced code blocks from comments, and uses a held-for-review footer when auto-promotion is blocked.

Test plan

  • bash scripts/post-triage-test.sh
  • bash scripts/validate-output-schema-test.sh

@rh-hemartin
rh-hemartin requested a review from a team as a code owner August 28, 2026 11:43
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Generalize triage auto-promotion blocking with reasons

✨ Enhancement 🧪 Tests 📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

• Replaces the workflow-specific flag with reusable, reasoned auto-promotion blocking.
• Preserves legacy outputs while routing blocked auto-code categories to human review.
• Sanitizes triage comments and expands schema and post-script regression coverage.
Diagram

graph TD
  A["Triage agent"] --> B["Result schema"] --> C["Post-triage script"] --> D{"Auto-code eligible?"}
  D -->|Yes| E{"Promotion blocked?"}
  D -->|No| G["Triaged"]
  E -->|No| F["Ready to code"]
  E -->|Yes| G
  E -.->|Reason| H["Held comment"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. List independent blockers
  • ➕ Represents multiple simultaneous gates without merging reasons
  • ➕ Allows future gates to add structured blocker types
  • ➖ Expands the schema and prompt contract prematurely
  • ➖ Requires aggregation and compatibility logic in the post-script
2. Keep gate-specific fields
  • ➕ Makes each blocking condition explicit
  • ➕ Minimizes change to the existing workflow-specific path
  • ➖ Duplicates routing logic as new gates arrive
  • ➖ Couples post-processing to every new triage policy

Recommendation: Use the PR's single generalized block object for this slice: it centralizes routing, carries a human-readable reason, and preserves one-release compatibility without over-designing future effort gating. Consider a blocker array only if multiple independent producers must report concurrent reasons.

Files changed (9) +364 / -82

Enhancement (3) +179 / -50
triage.mdTeach triage to emit reasoned promotion blocks +13/-4

Teach triage to emit reasoned promotion blocks

• Updates workflow-change detection and output examples to use block_auto_promotion. Clarifies category routing and instructs the agent to avoid fenced code blocks in comments.

agents/triage.md

post-triage.shBundle generalized auto-promotion gate behavior +83/-23

Bundle generalized auto-promotion gate behavior

• Updates the generated post-triage script to resolve the new gate with legacy fallback, route eligible blocked issues to triaged, sanitize untrusted text, and publish held-review guidance.

scripts/post-triage.sh

post-triage.src.shImplement generalized auto-promotion gating +83/-23

Implement generalized auto-promotion gating

• Introduces the source implementation for reasoned blocking, backward-compatible workflow handling, comment fence removal, label routing, and blocked-specific next steps.

scripts/post-triage.src.sh

Tests (2) +149 / -25
post-triage-test.shCover blocked routing and comment sanitization +115/-25

Cover blocked routing and comment sanitization

• Expands regression coverage for category routing, legacy fallback, reason footers, held-review guidance, workflow-command sanitization, and fenced-block removal.

scripts/post-triage-test.sh

validate-output-schema-test.shValidate the new promotion block schema +34/-0

Validate the new promotion block schema

• Adds valid and invalid cases for required fields, empty reasons, extra properties, omission behavior, and deprecated-field compatibility.

scripts/validate-output-schema-test.sh

Documentation (3) +22 / -6
FEATURES.mdUpdate feature guidance for generalized promotion blocks +1/-1

Update feature guidance for generalized promotion blocks

• Replaces the workflow-specific schema example with the reusable block_auto_promotion field.

FEATURES.md

code.mdClarify ready-to-code promotion behavior +1/-1

Clarify ready-to-code promotion behavior

• Documents that the triage post-script applies ready-to-code only when auto-promotion is not blocked.

docs/code.md

triage.mdDocument auto-promotion blocking and compatibility +20/-4

Document auto-promotion blocking and compatibility

• Explains blocked and unblocked outcomes, affected categories, reason handling, and the temporary requires_workflow_changes fallback.

docs/triage.md

Other (1) +14 / -1
triage-result.schema.jsonAdd the block_auto_promotion result contract +14/-1

Add the block_auto_promotion result contract

• Adds a strict blocked-and-reason object with reason length validation. Retains requires_workflow_changes as an optional deprecated property for one release.

schemas/triage-result.schema.json

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 28, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 11:45 AM UTC · Completed 12:06 PM UTC

Commit: fa3c916 · View workflow run →

Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $9.18

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📜 Skill insights (2)

Grey Divider


Action required

1. triage.md adds agent directives 📜 Skill insight ⛨ Security
Description
The changed prompt text directly instructs the triage agent to set and apply block_auto_promotion.
This introduces agent-instruction patterns in a changed configuration/prompt file, which the
checklist expressly prohibits.
Code

agents/triage.md[R383-385]

+**Blocking auto-promotion:** Use the `block_auto_promotion` field in `triage_summary` to prevent the post-triage script from auto-promoting the issue to the code agent. Set `blocked: true` with a `reason` when:
+- The fix requires modifying CI/pipeline configuration files (`.github/workflows/`, `.gitlab-ci.yml`, `.fullsend/.github/workflows/`, or enrolled-repo shim workflows) that the code agent cannot modify under current permissions.
+- Any other condition where auto-dispatch would be premature.
Relevance

●●● Strong

Prompt-instruction compliance findings are accepted when changed agent guidance contains imperative
directives.

PR-#381
PR-#326

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1538322 prohibits agent-instruction patterns in changed comments, string literals,
or configuration values. The added text uses imperative directives such as `Use the
block_auto_promotion field and Set blocked: true`, directly matching the prohibited pattern.

agents/triage.md[383-389]
Skill: code-review

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The changed `agents/triage.md` content contains direct agent instructions, contrary to PR Compliance ID 1538322.

## Issue Context
The added text directs the agent to use `block_auto_promotion` and specifies when to set it. Rework the change so prohibited instruction patterns are not introduced in comments, strings, or configuration values.

## Fix Focus Areas
- agents/triage.md[383-389]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. False block still falls back 🐞 Bug ≡ Correctness
Description
Using jq's // empty turns an explicit block_auto_promotion.blocked: false into an empty result,
so a simultaneously present deprecated requires_workflow_changes: true incorrectly blocks
promotion. This violates the documented rule that the deprecated field is consulted only when
block_auto_promotion is absent.
Code

scripts/post-triage.src.sh[R424-426]

+    BLOCKED=$(jq -r '.triage_summary.block_auto_promotion.blocked // empty' "${RESULT_FILE}")
+    BLOCK_REASON=$(jq -r '.triage_summary.block_auto_promotion.reason // empty' "${RESULT_FILE}")
+    if [[ -z "${BLOCKED}" ]]; then
Relevance

●●● Strong

This is a deterministic jq false-value fallback bug, matching accepted requests for robust
null/boolean handling.

PR-#284
PR-#876

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The schema allows both fields and allows blocked to be false, while the documentation limits
legacy fallback to absence of the new object. In jq, false // empty emits no value, so the
subsequent empty check enters the legacy fallback and changes the result to true.

scripts/post-triage.src.sh[424-435]
schemas/triage-result.schema.json[200-212]
docs/triage.md[150-157]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
An explicit `block_auto_promotion.blocked: false` is lost because jq's `//` treats `false` like a missing value, allowing the deprecated flag to override it.

## Issue Context
The schema permits both migration fields, while the documented precedence says `requires_workflow_changes` applies only when the new object is absent. Test the valid combination `blocked:false` plus `requires_workflow_changes:true`.

## Fix Focus Areas
- scripts/post-triage.src.sh[424-436]
- scripts/post-triage-test.sh[810-818]
- scripts/post-triage.sh[1349-1361]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Protected automation paths modified 📜 Skill insight § Compliance
Description
This PR modifies protected agents/ and scripts/ paths, including triage instructions and
executable automation. These governance/automation changes require human approval and must not be
auto-approved.
Code

scripts/post-triage.src.sh[R73-76]

+# Drop paired line-start fenced code blocks. An unmatched opener is left
+# in place so the remainder of the text is not deleted. Inline triple
+# backticks (not at line start) are left unchanged.
+strip_line_start_fences() {
Relevance

●● Moderate

Protected-path approval findings are mixed: some governance requests were rejected, while others
remain undetermined.

PR-#609
PR-#476
PR-#157

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1538392 mandates a finding whenever protected paths such as agents/ or scripts/
are modified. The diff adds executable processing logic under scripts/ and also changes
agents/triage.md, so the protected-path review requirement is triggered.

scripts/post-triage.src.sh[73-76]
agents/triage.md[133-133]
Skill: pr-review



Remediation recommended

4. Fence stripping is bypassable 🐞 Bug ≡ Correctness
Description
The sanitizer recognizes every line beginning with exactly three backticks as a delimiter, so valid
tilde-fenced blocks are left intact and backtick-prefixed content inside a longer/matching fence can
be mistaken for its close. Consequently the post-script can publish code content it claims to strip,
or delete the wrong region of the triage comment.
Code

scripts/post-triage.src.sh[R80-87]

+      if ($0 ~ /^```/) {
+        n++
+        pos[n] = NR
+      }
+    }
+    END {
+      for (i = 1; i + 1 <= n; i += 2) {
+        for (j = pos[i]; j <= pos[i + 1]; j++) skip[j] = 1
Relevance

●●● Strong

Fence parsing edge cases are accepted; historical linter fixes specifically broaden fence
recognition and handling.

PR-#476

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The agent contract prohibits fenced code blocks generally, but the implementation records only lines
matching ^``` and blindly removes alternating pairs. The same helper's output becomes the posted
comment, so unsupported or prematurely closed fences reach every tracker.

agents/triage.md[367-372]
scripts/post-triage.src.sh[76-97]
scripts/post-triage.src.sh[489-495]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new sanitizer only detects `^```` and pairs matches by position rather than matching actual Markdown opening and closing delimiters. Valid fenced blocks can survive, and delimiter-like lines inside a block can terminate removal early.

## Issue Context
Track the opening delimiter character and length, accept both backtick and tilde fences, and only close on a compatible delimiter-only line. Add tests for tilde fences, longer backtick fences containing triple backticks, and non-closing backtick-prefixed lines.

## Fix Focus Areas
- scripts/post-triage.src.sh[76-97]
- scripts/post-triage-test.sh[608-618]
- scripts/post-triage.sh[1001-1022]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
✅ Compliance rules (platform): 56 rules
✅ Skills: 4 invoked
  code-review
  code-implementation
  pr-review
  docs-review
Review mode: ⚖️ Balanced

Grey Divider

Tip of the day
💡 Did you know, you can reply 'qodo' on any finding to push back, ask questions, or dig deeper

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread scripts/post-triage.src.sh Outdated
Comment on lines +73 to +76
# Drop paired line-start fenced code blocks. An unmatched opener is left
# in place so the remainder of the text is not deleted. Inline triple
# backticks (not at line start) are left unchanged.
strip_line_start_fences() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Protected automation paths modified 📜 Skill insight § Compliance

This PR modifies protected agents/ and scripts/ paths, including triage instructions and
executable automation. These governance/automation changes require human approval and must not be
auto-approved.

Comment thread agents/triage.md
Comment on lines +383 to +385
**Blocking auto-promotion:** Use the `block_auto_promotion` field in `triage_summary` to prevent the post-triage script from auto-promoting the issue to the code agent. Set `blocked: true` with a `reason` when:
- The fix requires modifying CI/pipeline configuration files (`.github/workflows/`, `.gitlab-ci.yml`, `.fullsend/.github/workflows/`, or enrolled-repo shim workflows) that the code agent cannot modify under current permissions.
- Any other condition where auto-dispatch would be premature.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. triage.md adds agent directives 📜 Skill insight ⛨ Security

The changed prompt text directly instructs the triage agent to set and apply block_auto_promotion.
This introduces agent-instruction patterns in a changed configuration/prompt file, which the
checklist expressly prohibits.
Agent Prompt
## Issue description
The changed `agents/triage.md` content contains direct agent instructions, contrary to PR Compliance ID 1538322.

## Issue Context
The added text directs the agent to use `block_auto_promotion` and specifies when to set it. Rework the change so prohibited instruction patterns are not introduced in comments, strings, or configuration values.

## Fix Focus Areas
- agents/triage.md[383-389]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread scripts/post-triage.src.sh Outdated
Comment on lines +424 to +426
BLOCKED=$(jq -r '.triage_summary.block_auto_promotion.blocked // empty' "${RESULT_FILE}")
BLOCK_REASON=$(jq -r '.triage_summary.block_auto_promotion.reason // empty' "${RESULT_FILE}")
if [[ -z "${BLOCKED}" ]]; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

3. False block still falls back 🐞 Bug ≡ Correctness

Using jq's // empty turns an explicit block_auto_promotion.blocked: false into an empty result,
so a simultaneously present deprecated requires_workflow_changes: true incorrectly blocks
promotion. This violates the documented rule that the deprecated field is consulted only when
block_auto_promotion is absent.
Agent Prompt
## Issue description
An explicit `block_auto_promotion.blocked: false` is lost because jq's `//` treats `false` like a missing value, allowing the deprecated flag to override it.

## Issue Context
The schema permits both migration fields, while the documented precedence says `requires_workflow_changes` applies only when the new object is absent. Test the valid combination `blocked:false` plus `requires_workflow_changes:true`.

## Fix Focus Areas
- scripts/post-triage.src.sh[424-436]
- scripts/post-triage-test.sh[810-818]
- scripts/post-triage.sh[1349-1361]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread scripts/post-triage.src.sh Outdated
Comment on lines +80 to +87
if ($0 ~ /^```/) {
n++
pos[n] = NR
}
}
END {
for (i = 1; i + 1 <= n; i += 2) {
for (j = pos[i]; j <= pos[i + 1]; j++) skip[j] = 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.

Remediation recommended

4. Fence stripping is bypassable 🐞 Bug ≡ Correctness

The sanitizer recognizes every line beginning with exactly three backticks as a delimiter, so valid
tilde-fenced blocks are left intact and backtick-prefixed content inside a longer/matching fence can
be mistaken for its close. Consequently the post-script can publish code content it claims to strip,
or delete the wrong region of the triage comment.
Agent Prompt
## Issue description
The new sanitizer only detects `^```` and pairs matches by position rather than matching actual Markdown opening and closing delimiters. Valid fenced blocks can survive, and delimiter-like lines inside a block can terminate removal early.

## Issue Context
Track the opening delimiter character and length, accept both backtick and tilde fences, and only close on a compatible delimiter-only line. Add tests for tilde fences, longer backtick fences containing triple backticks, and non-closing backtick-prefixed lines.

## Fix Focus Areas
- scripts/post-triage.src.sh[76-97]
- scripts/post-triage-test.sh[608-618]
- scripts/post-triage.sh[1001-1022]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@fullsend-ai-review fullsend-ai-review Bot added the risk/moderate PR risk: moderate label Aug 28, 2026
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 28, 2026

Copy link
Copy Markdown

Risk Assessment: elevated (3/5)

Details

Elevated risk maintained at 3, consistent with prior assessment: 9 files with 504 changed lines and large blast radius across the triage subsystem, 5 protected paths modified, test ratio at 0.22. Tier 2 continues to show very high fix/revert churn and high commit frequency, confirming an actively unstable area. Linked issue is well-scoped (priority/medium feature) which provides mild downward pressure, but the sustained Tier 2 churn keeps the composite at elevated.

Previous run

Risk Assessment: elevated (3/5)

Details

Elevated risk (up from prior moderate): 9 files with 504 changed lines and large blast radius across the triage subsystem, 5 protected paths modified, test ratio at 0.22, and very high fix/revert churn (3-40 per file in 90d) indicating an actively unstable area; score increased from 2 to 3 due to blast radius upgrading to large and sustained high churn in Tier 2.

Previous run (2)

Risk Assessment: moderate (2/5)

Details

Moderate risk: 9 files with 445 changed lines across the triage subsystem, 5 protected paths modified, no CI/dependency changes, established contributor, but elevated churn in the triage scripts and docs (20-36 commits in 30 days).

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 28, 2026

Copy link
Copy Markdown

Review

Findings

Medium

  • [protected-path] agents/triage.md, scripts/post-triage.sh, scripts/post-triage.src.sh, scripts/post-triage-test.sh, scripts/validate-output-schema-test.sh — Five files under protected paths (agents/, scripts/) are modified. The PR links to dispatch: no effort-based gating before auto-promoting issues to coder fullsend#2207 and describes the rationale for these changes (generalizing the auto-promotion blocking mechanism). Human approval is always required for protected-path changes, regardless of context.

Low

  • [logic-inconsistency] scripts/post-triage.sh, scripts/post-triage.src.sh — The fence-stripping guard for BLOCK_REASON checks only backtick fences (grep -q '^\``') but not tilde fences (~~~), while the equivalent guard for COMMENT correctly checks both (grep -qE '^(```|~~~)'). In practice this is harmless because _gha_sanitize()` strips newlines first, making multi-line fences impossible — the guard is effectively dead code after sanitization.

  • [schema-runtime-mismatch] scripts/post-triage-test.sh — The schema enforces reason with minLength: 1, but the post-script has a fallback for empty BLOCK_REASON ("No reason provided"). The test blocked-empty-reason-gets-fallback exercises a state the schema disallows. This is defense-in-depth; a brief comment noting it exercises a schema-invalid state for robustness would clarify intent.

  • [deprecation-lifecycle] schemas/triage-result.schema.json — The deprecation comment for requires_workflow_changes says "Kept optional for one release" but no tracking mechanism (issue reference, version target) ensures removal. A follow-up issue would prevent the dual-path logic from becoming permanent.

  • [precedence-semantics] scripts/post-triage.sh — When both block_auto_promotion and requires_workflow_changes are present, block_auto_promotion wins unconditionally via has(). This precedence rule is correctly tested (unblocked-wins-over-deprecated-workflow-flag) but only documented in inline comments — no schema-level annotation communicates it to external consumers.

Previous run

Review

Findings

Medium

  • [protected-path] agents/triage.md, scripts/post-triage.sh, scripts/post-triage.src.sh, scripts/post-triage-test.sh, scripts/validate-output-schema-test.sh — Five files under protected paths (agents/, scripts/) are modified. The PR links to dispatch: no effort-based gating before auto-promoting issues to coder fullsend#2207 and describes the rationale for these changes (generalizing the auto-promotion blocking mechanism). Human approval is always required for protected-path changes, regardless of context.

Low

  • [logic-inconsistency] scripts/post-triage.sh — The fence-stripping guard for BLOCK_REASON checks only backtick fences (grep -q '^\``') but not tilde fences (~~~), while the equivalent guard for COMMENT correctly checks both (grep -qE '^(```|~~~)'). In practice this is harmless because _gha_sanitize()strips newlines first, making multi-line fences impossible, but the inconsistency is worth aligning. The same applies toscripts/post-triage.src.sh`.

  • [scope-creep] agents/triage.md — The PR changes the comment field instructions from “Include the proposed test case as a fenced code block” to “Do not include fenced code blocks; summarize test cases and fixes in prose.” This behavioral change is reinforced by the new strip_line_start_fences() function and ~15 associated tests, but is not mentioned in the PR title or description.

  • [code-duplication] scripts/post-triage.sh, scripts/post-triage.src.sh — Both files now contain identical copies of strip_line_start_fences(), the block_auto_promotion gate logic (~40 lines), and the held-for-review footer, extending a pre-existing duplication pattern.

  • [deprecation-lifecycle] schemas/triage-result.schema.json — The deprecation comment for requires_workflow_changes says “Kept optional for one release” but no tracking mechanism ensures removal. A follow-up issue would prevent the dual-path logic from becoming permanent.

  • [schema-runtime-mismatch] scripts/post-triage.sh — The schema enforces reason with minLength: 1, but the post-script has a fallback for empty BLOCK_REASON ("No reason provided"). The test blocked-empty-reason-gets-fallback exercises a state the schema disallows. This is defense-in-depth — adding a comment would clarify the intent.

Previous run (2)

Review

Findings

High

  • [logic-error] scripts/post-triage.sh:1345 — jq's // (alternative operator) treats false as falsy, so jq -r '.triage_summary.block_auto_promotion.blocked // empty' produces no output when blocked is false. This causes BLOCKED to be empty, falling into the if [[ -z "${BLOCKED}" ]] branch which reads the deprecated requires_workflow_changes field instead. If both fields are present with conflicting values (e.g., block_auto_promotion.blocked: false and requires_workflow_changes: true), the deprecated field incorrectly wins. The same issue exists in scripts/post-triage.src.sh.
    Remediation: Check for the presence of the block_auto_promotion object rather than the truthiness of blocked. Use jq -r 'if .triage_summary | has("block_auto_promotion") then "yes" else "no" end' and branch on that, then use .blocked | tostring inside.

  • [protected-path] agents/triage.md, scripts/post-triage.sh, scripts/post-triage.src.sh, scripts/post-triage-test.sh, scripts/validate-output-schema-test.sh — Five files under protected paths (agents/, scripts/) are modified. The PR has no linked issue, so there is insufficient context to verify authorization for modifying governance and infrastructure files. Human approval is required for protected-path changes.

Medium

  • [missing-authorization] — The PR body references branch feat/2207-effort-gating and mentions this is the first of two slices, but no issue is linked (no Closes #N or Ref #N). Per AGENTS.md section 3, non-trivial changes (400+ lines across 9 files) require explicit authorization via a linked issue.
    Remediation: Link the authorizing issue using Closes #NNNN or Ref #NNNN.

  • [sanitization-pattern] scripts/post-triage.src.shBLOCK_REASON is sanitized for :: sequences via a while-loop, but is not passed through _gha_sanitize() like other untrusted values in this file. While BLOCK_REASON does not currently reach stdout (it flows into COMMENT which is posted via --body-file), the inconsistency with the file's sanitization patterns creates fragility for future maintainers. The same applies to scripts/post-triage.sh.
    Remediation: Either pass BLOCK_REASON through _gha_sanitize() or add a comment explaining why the colon-only sanitization is sufficient.

Low

  • [scope-creep] agents/triage.md:367 — The PR changes the comment field instructions from "Include the proposed test case as a fenced code block" to "Do not include fenced code blocks; summarize test cases and fixes in prose." This is related to the new strip_line_start_fences() function (both are about preventing fenced blocks in comments), but the behavioral change to agent commenting style is not mentioned in the PR title or description.

  • [test-inadequate] scripts/post-triage-test.sh — No test covers the scenario where both block_auto_promotion.blocked: false and requires_workflow_changes: true are present. This would exercise the jq false // empty precedence bug and document the intended field priority.

  • [test-inadequate] scripts/post-triage-test.sh — No test verifies the conditional "Next steps" footer text for blocked issues ("This issue was held for review. Run /fs-code only after confirming the concerns above.").


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 28, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 12:42 PM UTC · Completed 1:02 PM UTC

Commit: 361fb43 · View workflow run →

Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $6.68

@fullsend-ai-review fullsend-ai-review Bot added risk/elevated PR risk: elevated and removed risk/moderate PR risk: moderate labels Aug 28, 2026
@fullsend-ai-review
fullsend-ai-review Bot dismissed their stale review August 28, 2026 13:02

Superseded by updated review

@fullsend-ai-review fullsend-ai-review Bot added the requires-manual-review Review requires human judgment label Aug 28, 2026
Replace the single-purpose requires_workflow_changes boolean with a
general-purpose block_auto_promotion object (blocked + reason). Workflow
file detection now sets blocked=true with a reason; later gates can use
the same field without a new post-script path.

Keep requires_workflow_changes as a deprecated optional property for one
release so lockstep-skewed agent output still validates. When
block_auto_promotion is absent, the old boolean still blocks
auto-promotion.

The post-script appends the reason to the triage comment, sanitizes GHA
workflow-command sequences, strips paired line-start fenced code blocks,
and uses a held-for-review footer when auto-promotion is blocked.

Signed-off-by: Hector Martinez <hemartin@redhat.com>
@rh-hemartin
rh-hemartin force-pushed the feat/2207-block-auto-promotion branch from 361fb43 to f09b3d7 Compare September 1, 2026 09:02
@fullsend-ai-review

fullsend-ai-review Bot commented Sep 1, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 9:04 AM UTC · Completed 9:46 AM UTC

Commit: f09b3d7 · View workflow run →

Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high

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

Labels

requires-manual-review Review requires human judgment risk/elevated PR risk: elevated

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant