Skip to content

feat(triage): add effort-based gating before auto-promoting to coder#3048

Closed
rh-hemartin wants to merge 1 commit into
mainfrom
feat/triage-effort-analysis
Closed

feat(triage): add effort-based gating before auto-promoting to coder#3048
rh-hemartin wants to merge 1 commit into
mainfrom
feat/triage-effort-analysis

Conversation

@rh-hemartin

Copy link
Copy Markdown
Member

Summary

Adds effort estimation to the triage agent and gates auto-promotion to ready-to-code based on complexity. High-effort bug/documentation/performance issues now route through human review before dispatching to the code agent.

Problem

Currently post-triage.sh auto-applies ready-to-code to all bug/documentation/performance issues regardless of complexity. A trivial typo fix and a multi-file architectural change both auto-promote equally, leading to inadequate first attempts on complex issues and costly review-fix iteration cycles.

Fixes #2207

Changes

  1. Schema: Added optional effort field to triage_summary (0.25–3 scale, matching RICE)
  2. Agent: Updated triage agent to estimate effort based on:
    • Files/lines of code expected
    • Architectural impact
    • Testing complexity
    • Domain knowledge required
  3. Gating logic: In post-triage.sh sufficient handler:
    • Effort >= 2.0 → apply triaged label (routes to human review)
    • Effort < 2.0 → apply ready-to-code label (auto-promote to coder)
  4. Tests: Updated all existing test cases, added 3 new tests for effort gating

Test Plan

  • All 57 tests pass in post-triage-test.sh
  • Low-effort bug (0.25) gets ready-to-code
  • High-effort bug (2.5) gets triaged
  • High-effort docs/performance also get triaged
  • Feature issues unchanged (already go to triaged)

Example

Low effort (0.5) — auto-promotes:

{
  "category": "bug",
  "effort": 0.5,
  ...
}

ready-to-code label

High effort (2.5) — human review:

{
  "category": "bug",
  "effort": 2.5,
  ...
}

triaged label

@rh-hemartin rh-hemartin requested a review from a team as a code owner July 6, 2026 07:56
@rh-hemartin rh-hemartin self-assigned this Jul 6, 2026
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 6, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 7:57 AM UTC · Completed 8:07 AM UTC
Commit: d8c0a84 · View workflow run →

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

triage: estimate effort and gate ready-to-code auto-promotion

✨ Enhancement 🧪 Tests 📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

• Add an effort estimate to triage results for bug/docs/performance issues.
• Gate auto-promotion to ready-to-code when effort indicates substantial work.
• Update schema and tests to validate the new effort field and label behavior.
Diagram

graph TD
A["Triage agent"] --> B["triage_summary JSON"] --> C["Schema validation"] --> D["post-triage.sh"] --> E{effort >= 2.0?}
E -->|"yes"| F["Apply triaged"]
E -->|"no"| G["Defer/apply ready-to-code"]
D -."verified by".-> H["post-triage-test.sh"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Make the effort threshold configurable
  • ➕ Allows tuning (e.g., 1.5 vs 2.0) without code changes
  • ➕ Supports different repos/teams with different tolerance for auto-promotion
  • ➖ Adds configuration surface area and documentation burden
  • ➖ Risk of misconfiguration causing unexpected routing
2. Move gating into the triage agent output (label_actions)
  • ➕ Centralizes policy decision with the model’s context and reasoning
  • ➕ Reduces shell-side policy logic
  • ➖ Harder to enforce consistently and audit (model could drift)
  • ➖ Less deterministic than a scripted, repo-owned threshold
3. Introduce a separate policy file (category → threshold)
  • ➕ Keeps post-triage.sh simple while retaining deterministic policy
  • ➕ Easy to extend to new categories or multi-factor rules later
  • ➖ More moving parts than a single inline check
  • ➖ Overkill if the only rule is one threshold

Recommendation: The current approach (deterministic gating in post-triage.sh with schema support and tests) is the right default for enforceability and auditability. The main potential follow-up is to externalize the 2.0 threshold into a config/policy file if maintainers expect to tune it over time.

Files changed (4) +84 / -29

Enhancement (1) +14 / -3
post-triage.shGate ready-to-code on effort for bug/docs/performance categories +14/-3

Gate ready-to-code on effort for bug/docs/performance categories

• Reads triage_summary.effort (defaulting to 1.0) and, for bug/documentation/performance, applies triaged when effort >= 2.0; otherwise defers ready-to-code until after label_actions. Improves logging to include both category and effort and emits an explicit message when routing to human review.

internal/scaffold/fullsend-repo/scripts/post-triage.sh

Tests (1) +44 / -24
post-triage-test.shUpdate fixtures and add coverage for effort-based label routing +44/-24

Update fixtures and add coverage for effort-based label routing

• Updates existing sufficient-case fixtures to include effort, aligning with the schema change. Adds new tests ensuring low-effort bug routes to ready-to-code, high-effort bug/docs/perf route to triaged, and that the reason is logged.

internal/scaffold/fullsend-repo/scripts/post-triage-test.sh

Documentation (1) +19 / -1
triage.mdDocument effort estimation guidance and add effort to examples +19/-1

Document effort estimation guidance and add effort to examples

• Adds a new section describing how to score effort (0.25–3) for bug/documentation/performance triage results. Updates the JSON example to include an effort field and explains that high-effort items route to human review.

internal/scaffold/fullsend-repo/agents/triage.md

Other (1) +7 / -1
triage-result.schema.jsonExtend triage result schema with optional effort field +7/-1

Extend triage result schema with optional effort field

• Introduces an optional numeric triage_summary.effort field with bounds (0.25–3) and a descriptive hint. Keeps the schema strict via additionalProperties: false while allowing the new attribute.

internal/scaffold/fullsend-repo/schemas/triage-result.schema.json

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown

Site preview

Preview: https://d02ed479-site.fullsend-ai.workers.dev

Commit: 9cabba69a9761d4863d9be7fdd3f5b448e539e16

@codecov

codecov Bot commented Jul 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@qodo-code-review

qodo-code-review Bot commented Jul 6, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 61 rules

Grey Divider


Action required

1. EFFORT defaults to 1.0 ✓ Resolved 📎 Requirement gap ☼ Reliability
Description
post-triage.sh treats missing triage_summary.effort as 1.0, which can still auto-apply
ready-to-code for bug/documentation/performance issues without a real effort/complexity
estimate. This undermines the effort-based gating requirement and risks complex issues being
promoted prematurely.
Code

internal/scaffold/fullsend-repo/scripts/post-triage.sh[R271-282]

+    EFFORT=$(jq -r '.triage_summary.effort // 1.0' "${RESULT_FILE}")
+    echo "Category: ${CATEGORY}, Effort: ${EFFORT}"
    case "${CATEGORY}" in
      bug|documentation|performance)
-        echo "Deferring ready-to-code label (${CATEGORY}) until after label_actions..."
-        DEFERRED_LABEL="ready-to-code"
+        # Effort threshold: >= 2.0 is substantial work, route to human review.
+        if awk -v effort="${EFFORT}" 'BEGIN { exit (effort >= 2.0 ? 0 : 1) }'; then
+          echo "High effort (${EFFORT}) — applying triaged label for human review..."
+          add_label "triaged"
+        else
+          echo "Low effort (${EFFORT}) — deferring ready-to-code label until after label_actions..."
+          DEFERRED_LABEL="ready-to-code"
+        fi
Relevance

⭐⭐ Medium

No historical evidence on handling missing effort; prior patterns use defaults/optionals rather than
hard-failing absent fields.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Rule 1525850 requires that auto-promotion to ready-to-code for non-feature issues be gated by an
effort/complexity estimate. The changed code explicitly defaults missing effort to 1.0, which
allows auto-promotion even when no estimate is present, weakening the gating.

Effort-based gating before auto-applying ready-to-code for non-feature issues
internal/scaffold/fullsend-repo/scripts/post-triage.sh[271-282]

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

## Issue description
`post-triage.sh` currently sets `EFFORT` with a fallback (`.triage_summary.effort // 1.0`). If the triage output omits `effort`, the gating effectively reverts to category-based auto-promotion, which violates the intent of effort-based gating for non-feature issues.

## Issue Context
The compliance requirement is to prevent auto-applying `ready-to-code` for `bug`/`documentation`/`performance` without considering an effort/complexity signal.

## Fix Focus Areas
- internal/scaffold/fullsend-repo/scripts/post-triage.sh[271-282]

## Implementation notes
- For categories `bug|documentation|performance`, treat missing/invalid `effort` as a hard stop (fail) or conservatively route to `triaged`.
- Consider validating that `effort` is numeric and within the allowed range (0.25–3) before applying the threshold logic.

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



Remediation recommended

2. Ready-to-code not cleared ✓ Resolved 🐞 Bug ≡ Correctness
Description
In post-triage.sh (sufficient handler), the high-effort path adds triaged but never removes an
existing ready-to-code label, leaving contradictory control labels and undermining the intended
human-review gate. The dispatch workflow routes to the code stage when the triggering label is
ready-to-code, so leaving that label present keeps the issue in a state that implies code dispatch
eligibility.
Code

internal/scaffold/fullsend-repo/scripts/post-triage.sh[R270-282]

    CATEGORY=$(jq -r '.triage_summary.category // "unknown"' "${RESULT_FILE}")
-    echo "Category: ${CATEGORY}"
+    EFFORT=$(jq -r '.triage_summary.effort // 1.0' "${RESULT_FILE}")
+    echo "Category: ${CATEGORY}, Effort: ${EFFORT}"
    case "${CATEGORY}" in
      bug|documentation|performance)
-        echo "Deferring ready-to-code label (${CATEGORY}) until after label_actions..."
-        DEFERRED_LABEL="ready-to-code"
+        # Effort threshold: >= 2.0 is substantial work, route to human review.
+        if awk -v effort="${EFFORT}" 'BEGIN { exit (effort >= 2.0 ? 0 : 1) }'; then
+          echo "High effort (${EFFORT}) — applying triaged label for human review..."
+          add_label "triaged"
+        else
+          echo "Low effort (${EFFORT}) — deferring ready-to-code label until after label_actions..."
+          DEFERRED_LABEL="ready-to-code"
+        fi
Relevance

⭐⭐⭐ High

They’ve accepted fixes removing stale/conflicting control labels in post-triage (blocked/needs-info
cleanup, ready-to-code sequencing).

PR-#743
PR-#1755

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The sufficient handler’s high-effort branch adds triaged without any `remove_label
"ready-to-code" call. Separately, the dispatcher maps a ready-to-code` label event directly to the
code stage, making ready-to-code the control label whose presence/meaning must not conflict with
triaged.

internal/scaffold/fullsend-repo/scripts/post-triage.sh[259-292]
internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[178-196]

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

## Issue description
High-effort bug/docs/perf issues are supposed to be routed to human review by applying the `triaged` label. The new effort-gating branch adds `triaged` but does not clear `ready-to-code` if it is already present, leaving contradictory control labels and weakening the meaning of the gate.

## Issue Context
The dispatcher routes to the code stage based on `ready-to-code` label events, and `ready-to-code` is the canonical “eligible for coding” control label. If it remains present while `triaged` is applied, the issue state is inconsistent.

## Fix Focus Areas
- internal/scaffold/fullsend-repo/scripts/post-triage.sh[259-292]
- internal/scaffold/fullsend-repo/scripts/post-triage-test.sh[177-207]

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


Grey Divider

Qodo Logo

Comment thread internal/scaffold/fullsend-repo/scripts/post-triage.sh Outdated
Comment on lines 270 to +282
CATEGORY=$(jq -r '.triage_summary.category // "unknown"' "${RESULT_FILE}")
echo "Category: ${CATEGORY}"
EFFORT=$(jq -r '.triage_summary.effort // 1.0' "${RESULT_FILE}")
echo "Category: ${CATEGORY}, Effort: ${EFFORT}"
case "${CATEGORY}" in
bug|documentation|performance)
echo "Deferring ready-to-code label (${CATEGORY}) until after label_actions..."
DEFERRED_LABEL="ready-to-code"
# Effort threshold: >= 2.0 is substantial work, route to human review.
if awk -v effort="${EFFORT}" 'BEGIN { exit (effort >= 2.0 ? 0 : 1) }'; then
echo "High effort (${EFFORT}) — applying triaged label for human review..."
add_label "triaged"
else
echo "Low effort (${EFFORT}) — deferring ready-to-code label until after label_actions..."
DEFERRED_LABEL="ready-to-code"
fi

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

2. Ready-to-code not cleared 🐞 Bug ≡ Correctness

In post-triage.sh (sufficient handler), the high-effort path adds triaged but never removes an
existing ready-to-code label, leaving contradictory control labels and undermining the intended
human-review gate. The dispatch workflow routes to the code stage when the triggering label is
ready-to-code, so leaving that label present keeps the issue in a state that implies code dispatch
eligibility.
Agent Prompt
## Issue description
High-effort bug/docs/perf issues are supposed to be routed to human review by applying the `triaged` label. The new effort-gating branch adds `triaged` but does not clear `ready-to-code` if it is already present, leaving contradictory control labels and weakening the meaning of the gate.

## Issue Context
The dispatcher routes to the code stage based on `ready-to-code` label events, and `ready-to-code` is the canonical “eligible for coding” control label. If it remains present while `triaged` is applied, the issue state is inconsistent.

## Fix Focus Areas
- internal/scaffold/fullsend-repo/scripts/post-triage.sh[259-292]
- internal/scaffold/fullsend-repo/scripts/post-triage-test.sh[177-207]

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

@fullsend-ai-review

fullsend-ai-review Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review

Verdict: Comment — the implementation is correct and secure, but test coverage for a key fallback path is missing and documentation has not been updated to reflect the new behavior.

Summary

This PR adds effort-based gating to the triage pipeline so that high-effort bug/documentation/performance issues (effort ≥ 2.0) route to human review instead of auto-promoting to ready-to-code. The implementation is sound:

  • Schema: effort is correctly added as an optional field in triage_summary with additionalProperties: false, so it is permitted but not required. Backward compatible.
  • Script logic: The jq // "null" fallback correctly identifies absent effort and conservatively routes to human review (triaged label), which is a better design than defaulting to a numeric value — missing effort never silently auto-promotes. The awk -v numeric comparison correctly handles all boundary cases (2.0 → triaged, 1.99 → ready-to-code).
  • Deferred label ordering: add_label "triaged" is correctly called directly (not deferred) because triaged does not trigger dispatch — only ready-to-code needs deferral per Race condition: multiple labels applied simultaneously can prevent code agent from running #1752.
  • Security: No injection risks. EFFORT is schema-validated as a JSON number before post-triage.sh runs (harness enforces schema validation as a hard gate via run.go:662). The awk -v assignment treats the value as data, not code. All interpolations are properly double-quoted. GHA workflow command injection is not possible since numeric values cannot produce :: prefixed output.
  • Test integrity: Existing test assertions are not weakened — adding "effort":1.0 to existing fixtures preserves the same expected behavior (1.0 < 2.0 → ready-to-code path).

Findings

1. Missing backward-compatibility test for absent effort field (medium · correctness)

File: internal/scaffold/fullsend-repo/scripts/post-triage-test.sh

All existing sufficient test fixtures were updated to include "effort":1.0, and all 5 new tests specify explicit effort values. No test exercises the backward-compatibility fallback path where the effort field is entirely absent from triage_summary. The code has an explicit handler for this case (EFFORT == "null" → apply triaged label), but it is untested.

Remediation: Add a test case with a sufficient bug fixture that omits the effort field entirely and assert it gets triaged (not ready-to-code). This verifies the conservative fallback works and catches future regressions. Example:

run_test "sufficient-bug-missing-effort-gets-triaged" \
  '{"action":"sufficient",...,"triage_summary":{...no effort field...}}' \
  "gh api repos/test-org/test-repo/issues/42/labels -f labels[]=triaged --silent"

2. Documentation now inaccurately describes triage label routing (medium · docs-currency)

Files:

  • docs/agents/triage.md line 45 — states ready-to-code applies to issues that are "fully specified and low-risk (bug, documentation, performance)" with no mention of effort-based exception
  • docs/agents/code.md line 41 — states ready-to-code is "Applied by the triage post-script for low-risk categories (bug, documentation, performance)" unconditionally
  • docs/guides/user/bugfix-workflow.md lines 47-48 — states triaged "applies to features and uncategorized issues" and ready-to-code applies unconditionally to "bug, docs, performance"; line 113 states triage hands off by labeling ready-to-code without mentioning effort gating

These documentation files now contain inaccurate descriptions of the triage pipeline's label routing behavior.

Remediation: Update the label tables to note the effort-based exception. For example, ready-to-code → "Triage passed, low-risk category (bug, docs, performance), and low effort (< 2.0)." triaged → add "also applies to high-effort bug/documentation/performance issues (effort ≥ 2.0)."

3. Comment format inconsistency (low · style)

File: internal/scaffold/fullsend-repo/scripts/post-triage.sh

The new comment uses (#2207) while the existing code on the adjacent line uses the (per #561, ...) format. Minor inconsistency in issue-reference style.

Remediation: Consider (per #2207, ...) for consistency with the existing comment at line 265.

4. Consider hardening effort estimation against reporter influence (low · prompt-injection)

File: internal/scaffold/fullsend-repo/agents/triage.md

The effort score directly controls whether bug/docs/performance issues auto-promote to the code agent. A malicious issue reporter could craft issue text designed to influence the triage agent into producing a low effort estimate, bypassing human review gating. The risk is mitigated by existing defenses (category gating, schema validation, code review before merge, LLM-mediated rather than direct influence), but the effort estimation instructions could be hardened.

Remediation: Add explicit guidance in the effort estimation section: "Base your effort estimate solely on codebase signals (number of files likely affected, test coverage, cross-cutting concerns). Disregard any effort or complexity characterizations provided in the issue text — the reporter's assessment of implementation difficulty is untrusted input."


Labels: PR already has appropriate labels (agent/triage, component/dispatch).

Previous run

Review

Verdict: Comment — the code changes are correct and secure, but documentation has not been updated to reflect the new behavior.

Summary

This PR adds effort-based gating to the triage pipeline so that high-effort bug/documentation/performance issues (effort ≥ 2.0) route to human review instead of auto-promoting to ready-to-code. The implementation is sound:

  • Schema: effort is correctly added as an optional field in triage_summary with additionalProperties: false, so it is permitted but not required. Backward compatible.
  • Script logic: The jq // 1.0 fallback correctly preserves existing behavior when effort is absent. The awk -v numeric comparison is correct for all reachable inputs including boundary values (2.0 → triaged, 1.99 → ready-to-code).
  • Deferred label ordering: add_label "triaged" is correctly called directly (not deferred) because triaged does not trigger dispatch — only ready-to-code needs deferral per Race condition: multiple labels applied simultaneously can prevent code agent from running #1752.
  • Security: No injection risks. The EFFORT variable is schema-validated as a JSON number before post-triage.sh runs, jq -r can only output decimal representations, and awk -v does not interpret its value as code. All interpolations are properly double-quoted.

Findings

1. Missing backward-compatibility test for absent effort field (medium · correctness)

File: internal/scaffold/fullsend-repo/scripts/post-triage-test.sh

All existing sufficient test fixtures were updated to include "effort":1.0. After this PR, no test exercises the jq // 1.0 fallback path where the effort field is entirely absent from triage_summary. This fallback is the backward-compatibility mechanism for existing triage agent outputs that predate the effort field.

Remediation: Add a test case with a triage_summary that omits the effort field entirely (e.g., a bug category fixture without effort) and assert it gets ready-to-code. This verifies the fallback works and catches future regressions.

2. Documentation now inaccurately describes triage label routing (medium · docs-currency)

Files:

  • docs/agents/triage.md line 45 — states ready-to-code applies to issues that are "fully specified and low-risk (bug, documentation, performance)" with no mention of effort-based exception
  • docs/agents/code.md line 41 — states ready-to-code is "Applied by the triage post-script for low-risk categories (bug, documentation, performance)" unconditionally
  • docs/guides/user/bugfix-workflow.md line 47 — states triaged "applies to features and uncategorized issues" (now also applies to high-effort bug/docs/performance); line 48 states ready-to-code applies unconditionally to "bug, docs, performance"

Three documentation files now contain inaccurate descriptions of the triage pipeline's label routing behavior. Users consulting these docs will not know that high-effort issues in auto-promote categories now receive triaged instead of ready-to-code.

Remediation: Update the label tables in these three files to note the effort-based exception. For example, ready-to-code could say "Triage passed and low effort (bug, docs, performance with effort < 2.0)" and triaged could add "also applies to high-effort bug/documentation/performance issues."

3. Comment format inconsistency (low · style)

File: internal/scaffold/fullsend-repo/scripts/post-triage.sh

The new comment uses (#2207) while the existing code on the adjacent line uses the (per #561, ...) format. Minor inconsistency in issue-reference style.

Remediation: Consider (per #2207, ...) or (see #2207) for consistency with the existing comment at line 265.


Labels: PR modifies the triage agent instructions and dispatch gating logic in the scaffold.

@fullsend-ai-review fullsend-ai-review Bot added requires-manual-review Review requires human judgment agent/triage Triage agent component/dispatch Workflow dispatch and triggers labels Jul 6, 2026
Add effort estimation to triage agent (0.25-3 scale matching RICE). Bug/docs/performance issues with effort >= 2.0 get triaged instead of ready-to-code, routing high-complexity work through human review before dispatch.

Fixes #2207

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Signed-off-by: Hector Martinez <hemartin@redhat.com>
@rh-hemartin rh-hemartin force-pushed the feat/triage-effort-analysis branch from d8c0a84 to 9cabba6 Compare July 6, 2026 08:14
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 6, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 8:15 AM UTC · Completed 8:25 AM UTC
Commit: 9cabba6 · View workflow run →

@fullsend-ai-review fullsend-ai-review Bot added requires-manual-review Review requires human judgment and removed requires-manual-review Review requires human judgment labels Jul 6, 2026

@ralphbean ralphbean left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is an automated comment. We are moving agent content from internal/scaffold/fullsend-repo/ to https://github.com/fullsend-ai/agents -- changes should be made to agent definitions there going forwards.

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Review Squad — 5 agents (Claude x3, Gemini, Codex) | 3 medium findings after dedup and verification

Overall: solid, well-scoped PR. The effort-based gating logic is correct and the conservative fallback (missing effort → human review) is a good design choice. The three inline findings are actionable — a missing test path, a defense-in-depth guard, and a label mismatch between schema and agent prompt.


run_test "sufficient-performance-high-effort-gets-triaged" \
'{"action":"sufficient","reasoning":"all clear","clarity_scores":{"symptom":0.9,"cause":0.85,"reproduction":0.9,"impact":0.8,"overall":0.87},"triage_summary":{"title":"Optimize database queries across layers","severity":"high","category":"performance","problem":"Slow queries","root_cause_hypothesis":"Missing indexes and N+1 queries","reproduction_steps":["step 1"],"environment":"Production","impact":"All users","recommended_fix":"Add indexes and refactor query patterns","proposed_test_case":"test_query_performance","effort":3.0},"comment":"## Triage Summary\n\nLarge performance optimization."}' \
"gh api repos/test-org/test-repo/issues/42/labels -f labels[]=triaged --silent"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

MEDIUM — Missing test for null-effort fallback path

The script has an explicit branch for missing effort ("null") at post-triage.sh:278 that routes to triaged, but every single test fixture includes an explicit "effort" value. The null-effort codepath is completely untested. Since effort is optional in the schema (not in the required array), this path is reachable when the agent omits it.

Suggestion: Add a test case:

run_test "sufficient-bug-missing-effort-gets-triaged" \
  '{"action":"sufficient","reasoning":"all clear","clarity_scores":{"symptom":0.9,"cause":0.85,"reproduction":0.9,"impact":0.8,"overall":0.87},"triage_summary":{"title":"Fix crash","severity":"high","category":"bug","problem":"Crash","root_cause_hypothesis":"Buffer overflow","reproduction_steps":["step 1"],"environment":"Linux","impact":"All users","recommended_fix":"Fix buffer","proposed_test_case":"test_crash"},"comment":"## Triage Summary\n\nReady."}' \
  "gh api repos/test-org/test-repo/issues/42/labels -f labels[]=triaged --silent"

Flagged by 5/5 review agents (full consensus).

echo "Missing effort estimate — applying triaged label for human review..."
remove_label "ready-to-code"
add_label "triaged"
elif awk -v effort="${EFFORT}" 'BEGIN { exit (effort >= 2.0 ? 0 : 1) }'; then

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

MEDIUM — Non-numeric effort value silently auto-promotes to ready-to-code

If effort passes the null check but is a non-numeric string (e.g., "high"), awk coerces it to 0, and 0 >= 2.0 is false, routing to ready-to-code. This is the wrong direction for a safety gate — invalid values should fail closed (triaged/human review), not open (auto-promote to coder).

The schema's "type": "number" constraint mitigates this, but defense-in-depth is warranted since this gate controls auto-dispatch.

Suggestion: Add a regex guard before the awk comparison:

elif ! [[ "${EFFORT}" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
  echo "::warning::Non-numeric effort value '${EFFORT}' — treating as high effort for human review"
  remove_label "ready-to-code"
  add_label "triaged"
elif awk -v effort="${EFFORT}" 'BEGIN { exit (effort >= 2.0 ? 0 : 1) }'; then

Flagged by 4/5 review agents.

"type": "number",
"minimum": 0.25,
"maximum": 3,
"description": "Estimated implementation effort (0.25 = trivial, 1 = moderate, 3 = substantial)"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

MEDIUM — Schema description mismatches triage.md effort scale labels

The description says "0.25 = trivial, 1 = moderate, 3 = substantial" but triage.md defines 2.0 as "Substantial" and 3.0 as "Large". The word "substantial" maps to different scores in each file. An LLM reading the schema alone could calibrate effort differently than one reading the agent prompt.

Suggestion:

"description": "Estimated implementation effort (0.25 = trivial, 1 = moderate, 2 = substantial, 3 = large)"

Flagged by 3/5 review agents.

@rh-hemartin

Copy link
Copy Markdown
Member Author

Migrated to fullsend-ai/agents#36

@rh-hemartin rh-hemartin closed this Jul 7, 2026
@rh-hemartin rh-hemartin deleted the feat/triage-effort-analysis branch July 7, 2026 06:35
@fullsend-ai-retro

fullsend-ai-retro Bot commented Jul 7, 2026

Copy link
Copy Markdown

🤖 Finished Retro · ✅ Success · Started 6:37 AM UTC · Completed 6:44 AM UTC
Commit: 9cabba6 · View workflow run →

@fullsend-ai-retro

Copy link
Copy Markdown

Retro: PR #3048

The retro agent was unable to analyze PR #3048 because GitHub API access from within the sandbox failed. gh auth status reported the GH_TOKEN as invalid, and all gh API calls returned HTTP 403. Without API access, the agent could not read PR details, comments, reviews, workflow runs, or search for existing issues.

Root cause: The retro agent depends entirely on runtime GitHub API access from inside the sandbox. Unlike the review agent (which has pre-fetch-prior-review.sh to pre-fetch data on the host), the retro agent's pre-retro.sh only validates the URL format and pre-fetches nothing. When the in-sandbox token is invalid or expired, the agent has zero data to work with.

What the agent could still analyze: The local codebase, harness configs, agent definitions, skills, policies, and scripts. This analysis yielded one actionable proposal focused on making the retro agent resilient to GitHub API failures.

Note: Could not verify whether existing issues already cover this proposal because GitHub API was unavailable. The post-script should deduplicate if a matching issue already exists.

Proposals filed

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

Labels

agent/triage Triage agent component/dispatch Workflow dispatch and triggers requires-manual-review Review requires human judgment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dispatch: no effort-based gating before auto-promoting issues to coder

3 participants