Skip to content

feat: add generic critique agent - #87

Closed
ascerra wants to merge 20 commits into
mainfrom
feat/add-critique-agent
Closed

feat: add generic critique agent#87
ascerra wants to merge 20 commits into
mainfrom
feat/add-critique-agent

Conversation

@ascerra

@ascerra ascerra commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds a platform-agnostic adversarial reviewer agent that validates refinement plans against quality dimensions
  • Includes create-children.sh for child issue creation (GitHub sub-issues API + Jira hierarchy with fallbacks)
  • Test suite with 35 tests covering verdict routing, label logic, critique history, escalation, and JSON extraction
  • Depends on shared scripts from feat: add generic explore agent #11 (explore agent) — comment-helpers.sh, pre-explore.sh, and markdown-to-adf.py

Related Issue

Continuation of agent migration from konflux-ci/refinement to generic agents repo.

Changes

File Description
agents/critique.md Generic critique agent prompt (no Konflux-specific references)
harness/critique.yaml Harness config with env.runner/env.sandbox format
policies/critique.yaml Sandbox policy with read-only GitHub API access
schemas/critique-result.schema.json Output schema with description_clarity and project_routing dimensions
scripts/pre-critique.sh Context preparation (issue, exploration, refine result, platform, routing)
scripts/post-critique.sh Verdict handling (approved/revise/needs_input), label management, escalation
scripts/post-critique-test.sh 35-test suite covering all verdict paths and edge cases
scripts/create-children.sh Child issue creation for GitHub (sub-issues) and Jira (hierarchy with fallbacks)
env/critique.env Sandbox environment variables
docs/critique.md User-facing documentation
config.yaml Registers harness/critique.yaml
README.md Lists critique agent in agent table

Testing

  • bash scripts/post-critique-test.sh — 35/35 tests passing
  • Integration test with live issue (post-merge)

Checklist

  • No Konflux-specific references in agent code
  • Sandbox policy enforces read-only GitHub API access
  • PUT verb blocked in disallowedTools
  • Uses add_label helper consistently (not raw gh api)
  • No deprecated customized/ overlay references
  • Forge block uses env.runner/env.sandbox format
  • Pipeline labels parameterized via environment variables
  • description_clarity and project_routing in critique schema

Made with Cursor

@ascerra
ascerra requested a review from a team as a code owner July 9, 2026 17:45
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add generic critique agent with verdict routing and child-issue creation

✨ Enhancement 🧪 Tests 📝 Documentation ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Add a platform-agnostic critique agent to approve/revise/escalate refinement plans.
• Wire critique stage into the harness with read-only sandbox policy and output schema validation.
• Implement pre/post scripts, child issue creation, and a 35-case shell test suite.
Diagram

graph TD
A["Issue (GitHub/Jira)"] --> B["scripts/pre-critique.sh"] --> C[("refine-result.json") ] --> D["Critique agent (sandbox)"] --> E[("critique-result.json") ] --> F["scripts/post-critique.sh"] --> G["scripts/create-children.sh"] --> H["Child issues"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Move child creation logic to a small Python CLI
  • ➕ More robust JSON handling and error reporting than bash/jq for complex flows
  • ➕ Easier unit testing/mocking of GitHub/Jira APIs
  • ➕ Cleaner abstraction for platform-specific hierarchy/linking rules
  • ➖ Adds runtime/dependency surface area to the runner image
  • ➖ May diverge from existing repo convention if other agents are bash-first
2. Use a reusable GitHub Action / composite action for verdict routing
  • ➕ Standardizes label/comment behavior across agents
  • ➕ Makes post-script logic easier to share/version across pipelines
  • ➖ Harder to reuse outside GitHub Actions (e.g., local runs or other CI systems)
  • ➖ Still needs scripting for Jira APIs unless paired with a library/CLI

Recommendation: The PR’s approach (bash pre/post orchestration + sandboxed prompt + JSON schema contract) fits a repo that favors shell-based pipelines and keeps the agent read-only. The main follow-up worth considering is extracting the Jira/GitHub child-creation logic into a more testable module (Python CLI or shared library) if this script is expected to grow or be reused by other agents.

Files changed (12) +2188 / -0

Enhancement (4) +1454 / -0
critique.mdIntroduce platform-agnostic critique agent prompt and constraints +419/-0

Introduce platform-agnostic critique agent prompt and constraints

• Adds a new critique agent definition with explicit scoring dimensions, verdict criteria, and strict read-only/tooling constraints. Defines required inputs (context files, routing/platform context, history) and the JSON output contract expectations.

agents/critique.md

create-children.shCreate child issues in GitHub (sub-issues) or Jira (hierarchy with fallback) +473/-0

Create child issues in GitHub (sub-issues) or Jira (hierarchy with fallback)

• Implements child issue creation from an approved refinement plan, including topological ordering via parent_title, deduplication against existing children, and per-child platform/project overrides. Supports GitHub sub-issues linking and Jira parent creation with fallback to 'Relates' linking when hierarchy is rejected.

scripts/create-children.sh

post-critique.shRoute critique verdicts into comments, labels, escalation, and optional creation +332/-0

Route critique verdicts into comments, labels, escalation, and optional creation

• Adds the post-processing script that reads critique output, posts sticky comments, updates critique history, and attaches critique feedback for downstream use. Implements verdict handling for approved/revise/needs_input, including max-round escalation behavior and optional child creation through create-children.sh.

scripts/post-critique.sh

pre-critique.shAssemble critique context from issue, exploration, refine artifacts, and skills +230/-0

Assemble critique context from issue, exploration, refine artifacts, and skills

• Adds the pre-processing script that ensures issue context, downloads/extracts refine artifacts (with Jira attachment and GHA artifact fallbacks), and prepares critique history for later rounds. Loads optional routing skill and platform context, then exports all required paths into the environment.

scripts/pre-critique.sh

Tests (1) +357 / -0
post-critique-test.shAdd 35-case shell test suite for post-critique routing and jq extraction +357/-0

Add 35-case shell test suite for post-critique routing and jq extraction

• Adds an isolated bash test harness to validate verdict routing, label selection, critique history updates, iteration output discovery, and JSON field extraction. Avoids live API calls by mirroring key decision functions from post-critique.sh.

scripts/post-critique-test.sh

Documentation (2) +73 / -0
README.mdRegister Critique agent in the public agent table +1/-0

Register Critique agent in the public agent table

• Adds the Critique agent entry to the README agent matrix, describing it as the quality gate for refinement plans and its trigger label.

README.md

critique.mdAdd user-facing documentation for critique pipeline behavior +72/-0

Add user-facing documentation for critique pipeline behavior

• Documents how critique works, the verdict outcomes and labels, and how it fits into the explore→refine→critique pipeline. Describes when and how child issue creation happens via AUTO_CREATE and /fs-create.

docs/critique.md

Other (5) +304 / -0
config.yamlRegister critique harness in global agent config +1/-0

Register critique harness in global agent config

• Adds harness/critique.yaml to the list of agent harness sources so the critique stage is available to the platform.

config.yaml

critique.envDefine sandbox paths for critique stage inputs +6/-0

Define sandbox paths for critique stage inputs

• Adds environment variables pointing the sandbox to expected issue/explore/refine/history/routing/platform context file locations.

env/critique.env

critique.yamlAdd critique harness wiring (host files, env.runner/env.sandbox, schema validation) +75/-0

Add critique harness wiring (host files, env.runner/env.sandbox, schema validation)

• Introduces the critique harness definition including sandbox image, policy, host file mounts for context artifacts, and pre/post scripts. Adds schema validation loop for schemas/critique-result.schema.json and uses the env.runner/env.sandbox split (plus forge config).

harness/critique.yaml

critique.yamlAdd read-only sandbox policy for critique agent +71/-0

Add read-only sandbox policy for critique agent

• Defines filesystem and network restrictions for the critique sandbox, allowing read-only GitHub API access and read-only Jira API access while permitting model endpoints. Ensures the agent cannot mutate issues; mutations happen in post-script on the runner.

policies/critique.yaml

critique-result.schema.jsonDefine critique output schema including description_clarity and project_routing +151/-0

Define critique output schema including description_clarity and project_routing

• Adds a JSON schema for critique results with verdict-specific required fields and structured assessment dimensions. Includes conditional requirements for approved/revise/needs_input and caps for comment/summary length.

schemas/critique-result.schema.json

@fullsend-ai-review

fullsend-ai-review Bot commented Jul 9, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 5:47 PM UTC · Completed 6:03 PM UTC
Commit: 23d7556 · View workflow run →

@qodo-code-review

qodo-code-review Bot commented Jul 9, 2026

Copy link
Copy Markdown

Code Review by Qodo

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

Grey Divider


Action required

1. Docs overclaim no external access ✓ Resolved 📜 Skill insight ⚙ Maintainability
Description
docs/critique.md claims the critique agent cannot interact with external services, but the
harness/policy explicitly grants read-only access to GitHub and Jira APIs (and inference endpoints).
This contradiction can mislead operators about the system’s actual network capabilities.
Code

docs/critique.md[R11-13]

+The critique agent runs after the refine agent has produced a decomposition plan. It reads the original work item, exploration context, the proposed plan, and any prior critique history (for revision rounds). It evaluates the plan across seven dimensions — coverage, granularity, dependency coherence, implementability, scope accuracy, assumption grounding, and description clarity — and produces a structured verdict.
+
+The agent runs in a read-only sandbox. It cannot modify issues, create children, or interact with external services. Its only output is a structured JSON critique result consumed by the post-script, which posts a summary comment, attaches feedback, and applies labels to signal the next pipeline step.
Relevance

●●● Strong

Team fixes doc accuracy issues; e.g., corrected broken docs links/consistency in PR #15.

PR-#15

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1538422 requires documentation not to contradict current code/config behavior. The
documentation says no external service interaction, while the new policy/harness explicitly allow
network access to GitHub/Jira endpoints (and model endpoints).

docs/critique.md[11-13]
policies/critique.yaml[20-69]
harness/critique.yaml[5-7]
Skill: docs-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
Documentation states the agent cannot interact with external services, contradicting the configured network policies.

## Issue Context
The critique sandbox is configured with allowed egress to GitHub and Jira (read-only) and inference endpoints.

## Fix Focus Areas
- docs/critique.md[11-13]
- policies/critique.yaml[20-69]
- harness/critique.yaml[5-7]

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


2. Missing helper script dependencies ✓ Resolved 📜 Skill insight ≡ Correctness
Description
Several newly added critique/child-creation scripts hard-depend on helper artifacts
(comment-helpers.sh, pre-explore.sh, markdown-to-adf.py) that are not present in this
repository and are invoked without existence checks, causing the pipeline to fail at runtime before
key verdict handling or Jira child creation can run. This breaks the intended producer/consumer
contract for the critique and child-creation flow and makes critique runs brittle when optional
inputs are absent.
Code

scripts/post-critique.sh[R36-38]

+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+source "${SCRIPT_DIR}/comment-helpers.sh"
+
Relevance

●●● Strong

Missing companion scripts treated as real bug; fixed via workspace fallback in PR #41.

PR-#41

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The scripts demonstrate unconditional dependencies that will hard-fail when the referenced files are
missing: scripts/post-critique.sh runs under set -euo pipefail and immediately sources
scripts/comment-helpers.sh, so absence of that helper terminates the script before any
comment/label/attachment/child-creation logic executes. scripts/pre-critique.sh treats a missing
/tmp/workspace/issue-context.json as fatal unless scripts/pre-explore.sh exists, yet the harness
config marks issue-context.json as optional, making valid executions fail pre-agent. In the Jira
path, scripts/create-children.sh unconditionally shells out to `python3
${SCRIPT_DIR}/markdown-to-adf.py` to build the Jira payload, so Jira child creation cannot proceed
without that converter. This violates the runtime inter-component contract expectations (PR
Compliance IDs 1538370/1538315) because required helper artifacts are not shipped and there is no
fallback besides immediate failure.

scripts/post-critique.sh[36-38]
scripts/pre-critique.sh[36-43]
scripts/create-children.sh[125-127]
scripts/post-critique.sh[34-38]
harness/critique.yaml[23-25]
scripts/pre-critique.sh[35-44]
scripts/create-children.sh[120-127]
docs/critique.md[60-66]
Skill: pr-review
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 critique and child-creation scripts introduced/modified in this PR unconditionally `source` or execute helper files (`comment-helpers.sh`, `pre-explore.sh`, `markdown-to-adf.py`) that are not present in-repo and are not guarded by existence checks, leading to immediate runtime failures (often before verdict handling or Jira API calls can occur). Update the pipeline so these dependencies are either vendored into the repo/PR or resolved via robust fallback discovery with clear errors, and ensure critique does not fail simply because optional harness inputs are absent.

## Issue Context
- `post-critique.sh` runs with `set -euo pipefail` and unconditionally sources `scripts/comment-helpers.sh`, so the post phase terminates immediately if the helper is missing, preventing verdict handling (comments/labels/attachments/child creation).
- `pre-critique.sh` exits if `/tmp/workspace/issue-context.json` is missing and `scripts/pre-explore.sh` is not present, but the harness mounts `issue-context.json` as optional, making critique runs brittle and able to fail before the agent starts.
- `create-children.sh` always runs `python3 ${SCRIPT_DIR}/markdown-to-adf.py` in the Jira creation path with no fallback; without the converter, Jira child creation fails before issuing the Jira API request.
- Other scripts in the repo sometimes implement fallback discovery for companion scripts (e.g., searching workspace locations); critique currently does not.
- Docs indicate Jira child creation is supported, but the implementation assumes the converter exists locally.

## Fix Focus Areas
- scripts/post-critique.sh[34-38]
- scripts/pre-critique.sh[35-44]
- harness/critique.yaml[23-25]
- scripts/create-children.sh[120-127]
- docs/critique.md[60-66]

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


3. Null acceptance criteria crash ✓ Resolved 🐞 Bug ☼ Reliability
Description
scripts/create-children.sh assumes .children[].acceptance_criteria is always an array and calls
map(...) directly; if it is null/missing, jq errors and the script aborts due to set -e. This
can break auto-create even when all other child fields are usable.
Code

scripts/create-children.sh[R320-324]

+    CHILD_PARENT_TITLE=$(jq -r ".children[${i}].parent_title // \"\"" "${RESULT_FILE}")
+    CHILD_TYPE=$(jq -r ".children[${i}].type" "${RESULT_FILE}")
+    CHILD_DESC=$(jq -r ".children[${i}].description" "${RESULT_FILE}")
+    CHILD_AC=$(jq -r ".children[${i}].acceptance_criteria | map(\"- [ ] \" + .) | join(\"\n\")" "${RESULT_FILE}")
+    CHILD_LABELS=$(jq -c ".children[${i}].labels // []" "${RESULT_FILE}")
Relevance

●●● Strong

Team accepts jq/bash hardening to avoid set -e failures (robustness fixes accepted in PR #10).

PR-#10

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The script has set -euo pipefail enabled, and it runs map(...) over acceptance_criteria
without // [], which causes jq to exit non-zero on null input and abort the script.

scripts/create-children.sh[25-26]
scripts/create-children.sh[320-324]
scripts/create-children.sh[414-419]

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

### Issue description
`jq` will fail on `null | map(...)`, terminating child creation when a child omits `acceptance_criteria`.

### Issue Context
This failure occurs in both the main creation loop and the orphan fallback loop.

### Fix Focus Areas
- scripts/create-children.sh[25-26]
- scripts/create-children.sh[320-327]
- scripts/create-children.sh[414-419]

### Expected fix
Change the jq extraction to default to an empty array:
- `.children[i].acceptance_criteria // [] | map(...) | join("\n")`
Optionally omit the entire Acceptance Criteria section when the resulting string is empty.

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


View more (4)
4. Output filename mismatch ✓ Resolved 🐞 Bug ≡ Correctness
Description
harness/critique.yaml sets FULLSEND_OUTPUT_FILE=critique-result.json, but the critique agent
prompt and post-critique.sh both use agent-result.json. This will cause the validation loop to
look for the wrong output filename and fail the run even when the agent wrote valid JSON.
Code

harness/critique.yaml[R59-66]

+    REVIEW_ROUND: "${REVIEW_ROUND}"
+    MAX_REVIEW_ROUNDS: "${MAX_REVIEW_ROUNDS}"
+    AUTO_CREATE: "${AUTO_CREATE}"
+    FULLSEND_OUTPUT_FILE: critique-result.json
+  sandbox:
+    GH_TOKEN: "${GH_TOKEN}"
+    REVIEW_ROUND: "${REVIEW_ROUND}"
+    MAX_REVIEW_ROUNDS: "${MAX_REVIEW_ROUNDS}"
Relevance

●● Moderate

No close historical precedent found for FULLSEND_OUTPUT_FILE vs agent-result.json naming mismatches.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The harness forces schema validation to read output/${FULLSEND_OUTPUT_FILE}, but the critique
agent prompt instructs writing agent-result.json and the post-script searches for
agent-result.json in iteration outputs.

harness/critique.yaml[52-66]
agents/critique.md[250-257]
scripts/validate-output-schema.sh[27-40]
scripts/post-critique.sh[43-53]

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 critique harness config validates `output/critique-result.json`, but the critique agent prompt and post-script contract are `output/agent-result.json`, so validation will fail with “file not found”.

### Issue Context
`validate-output-schema.sh` uses `FULLSEND_OUTPUT_FILE` to decide which filename to validate. Other sandbox agents that write `agent-result.json` do not override `FULLSEND_OUTPUT_FILE`.

### Fix Focus Areas
- harness/critique.yaml[52-66]
- agents/critique.md[250-257]
- scripts/validate-output-schema.sh[27-40]

### Expected fix
Either:
1) Remove `FULLSEND_OUTPUT_FILE: critique-result.json` from the critique harness (so validation uses the default `agent-result.json`), OR
2) Change the critique agent prompt + post-script to write/read `critique-result.json` consistently (less consistent with existing agent conventions).

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


5. Policy adds network access unapproved ✗ Dismissed 📜 Skill insight ⛨ Security
Description
A new permission-declaring sandbox policy is introduced with explicit egress allowlists (GitHub,
Jira, and inference endpoints), but the PR does not provide a linked issue/ADR explicitly
authorizing and justifying this permission set. Permission-manifest changes require least-privilege
review with explicit authorization.
Code

policies/critique.yaml[R20-68]

+network_policies:
+  vertex_ai:
+    name: vertex-ai
+    endpoints:
+      - host: "api.anthropic.com"
+        port: 443
+        protocol: rest
+        enforcement: enforce
+        access: read-write
+      - host: "*.googleapis.com"
+        port: 443
+        protocol: rest
+        enforcement: enforce
+        access: read-write
+    binaries:
+      - path: "**/claude"
+      - path: "**/node"
+
+  github_api:
+    name: github-api
+    endpoints:
+      - host: "api.github.com"
+        port: 443
+        protocol: rest
+        enforcement: enforce
+        access: read-only
+      - host: "github.com"
+        port: 443
+        protocol: rest
+        enforcement: enforce
+        access: read-only
+      - host: "raw.githubusercontent.com"
+        port: 443
+        protocol: rest
+        enforcement: enforce
+        access: read-only
+    binaries:
+      - path: "**/gh"
+      - path: "**/git"
+      - path: "**/node"
+
+  jira_api:
+    name: jira-api
+    endpoints:
+      - host: "*.atlassian.net"
+        port: 443
+        protocol: rest
+        enforcement: enforce
+        access: read-only
Relevance

●● Moderate

Repo enforces permission/least-privilege justification in workflows (partially accepted in PR #25),
but no direct network-policy precedent.

PR-#25

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1538316 requires permission-manifest changes to follow least privilege and include
explicit justification/authorization. This PR adds a new policy file that grants network access to
multiple endpoints, but no explicit authorization artifact is provided in the PR content.

policies/critique.yaml[20-68]
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
A new permission manifest (sandbox policy) is added without an explicit linked authorization/justification for the allowed egress and capabilities.

## Issue Context
Compliance requires least-privilege review and an explicit issue/ADR for permission expansions/introductions.

## Fix Focus Areas
- policies/critique.yaml[20-68]

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


6. Protected paths modified in PR ✗ Dismissed 📜 Skill insight § Compliance
Description
This PR modifies multiple protected governance/infrastructure paths (agents/, harness/,
policies/, scripts/), which must not be auto-approved and require explicit review/justification.
A protected-path finding is required whenever these directories are touched.
Code

harness/critique.yaml[R1-7]

+---
+agent: agents/critique.md
+doc: docs/critique.md
+model: opus
+image: ghcr.io/fullsend-ai/fullsend-sandbox:latest
+policy: policies/critique.yaml
+
Relevance

●● Moderate

Protected-path review requirement appears in history but outcomes are “undetermined” (PRs #29, #59).

PR-#29
PR-#59

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1538392 mandates raising a finding whenever protected paths are modified, because
these are governance/infrastructure surfaces requiring human approval.

harness/critique.yaml[1-7]
policies/critique.yaml[1-19]
scripts/post-critique.sh[1-10]
agents/critique.md[1-15]
Skill: pr-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
Protected governance/infrastructure paths were modified and must be explicitly flagged for human review; these PRs must not be auto-approved.

## Issue Context
Protected paths include `agents/`, `harness/`, `policies/`, `scripts/`.

## Fix Focus Areas
- harness/critique.yaml[1-7]
- policies/critique.yaml[1-19]
- scripts/post-critique.sh[1-10]
- agents/critique.md[1-15]

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


7. No linked issue for feature ✗ Dismissed 📜 Skill insight § Compliance
Description
This PR is a non-trivial feature addition (new agent, harness, policy, schema, and multiple scripts)
but does not include a linked issue (e.g., Fixes #123 / Jira key URL) that authorizes the work.
Non-trivial changes require explicit authorization via a linked issue.
Code

scripts/post-critique.sh[R1-10]

+#!/usr/bin/env bash
+# post-critique.sh — Process critique agent output.
+#
+# Reads the critique result and performs one of:
+#   - verdict=approved + AUTO_CREATE=true: creates child issues immediately
+#   - verdict=approved + AUTO_CREATE=false: posts approval, adds label for human gate
+#   - verdict=revise + under iteration limit: posts feedback, signals refine via label
+#   - verdict=revise + at iteration limit: posts final plan for human decision
+#
+# Agents are decoupled — they communicate through labels and issue attachments.
Relevance

●● Moderate

No clear historical enforcement found requiring linked issue for non-trivial PRs; closest is release
workflow closing #26 in PR #25.

PR-#25

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1538390 requires a linked issue for non-trivial changes; the diff shows substantial
new feature/pipeline code, triggering the authorization requirement.

scripts/post-critique.sh[1-10]
Skill: pr-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
Non-trivial PR lacks an explicit linked authorizing issue.

## Issue Context
Add a concrete issue link (GitHub issue/PR or Jira ticket URL/key) in the PR description (e.g., `Fixes #...` / `Resolves PROJECT-...`) that authorizes this feature work.

## Fix Focus Areas
- scripts/post-critique.sh[1-10]

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



Remediation recommended

8. Escalation rewrites verdict ✓ Resolved 🐞 Bug ◔ Observability
Description
When max rounds are reached, post-critique.sh mutates the latest critique-history entry by
changing its verdict to approved. This loses audit fidelity by no longer preserving that the
agent actually returned revise for the final round (even though it does add escalated: true).
Code

scripts/post-critique.sh[R244-247]

+    if [[ -f "$CRITIQUE_HISTORY_FILE" ]]; then
+      UPDATED=$(jq '.rounds[-1].verdict = "approved" | .rounds[-1].escalated = true' "$CRITIQUE_HISTORY_FILE")
+      echo "$UPDATED" > "$CRITIQUE_HISTORY_FILE"
+    fi
Relevance

●● Moderate

No historical evidence found about preserving critique-history verdict vs mutating during
escalation.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The script first records the agent verdict in history, then later overwrites the last record's
verdict to approved during escalation, which changes the recorded outcome semantics.

scripts/post-critique.sh[89-106]
scripts/post-critique.sh[244-247]

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

### Issue description
On escalation, the script overwrites the recorded verdict from the agent. This makes critique-history.json ambiguous for consumers that expect verdict to reflect the agent's output.

### Issue Context
The script already appends a history record earlier in the run using the agent-provided verdict.

### Fix Focus Areas
- scripts/post-critique.sh[89-106]
- scripts/post-critique.sh[244-247]

### Expected fix
Do not change `.rounds[-1].verdict`. Instead, keep the original verdict and record escalation separately, e.g.:
- `.rounds[-1].escalated = true`
- optionally `.rounds[-1].escalation_reason = "max_rounds"` or a separate `final_state` field.

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


9. GitHub deduplication absent ✓ Resolved 🐞 Bug ☼ Reliability
Description
create-children.sh only populates EXISTING_TITLES (dedup) for Jira, but the docs claim re-runs
are deduplicated. On GitHub, re-running auto-create can create duplicate child issues with the same
title.
Code

scripts/create-children.sh[R255-283]

+# --- Fetch existing children for deduplication ---
+
+declare -A EXISTING_TITLES
+
+if [[ "${ISSUE_SOURCE:-}" == "jira" && -n "${JIRA_HOST:-}" && -n "${JIRA_EMAIL:-}" ]]; then
+  _dedup_auth=$(printf '%s:%s' "$JIRA_EMAIL" "$JIRA_API_TOKEN" | base64 -w0)
+
+  # Child work items (parent hierarchy)
+  _children_json=$(curl -sf \
+    -H "Authorization: Basic $_dedup_auth" \
+    -H "Accept: application/json" \
+    "https://${JIRA_HOST}/rest/api/3/search?jql=parent%3D${ISSUE_KEY}&fields=summary,status&maxResults=100" 2>/dev/null || echo '{"issues":[]}')
+
+  while IFS='|' read -r _ck _cs; do
+    [[ -n "$_ck" ]] && EXISTING_TITLES["$_cs"]="$_ck"
+  done < <(echo "$_children_json" | jq -r '.issues[]? | "\(.key)|\(.fields.summary)"')
+
+  # Linked issues (Relates)
+  _links_json=$(curl -sf \
+    -H "Authorization: Basic $_dedup_auth" \
+    -H "Accept: application/json" \
+    "https://${JIRA_HOST}/rest/api/3/issue/${ISSUE_KEY}?fields=issuelinks" 2>/dev/null || echo '{"fields":{"issuelinks":[]}}')
+
+  while IFS='|' read -r _lk _ls; do
+    [[ -n "$_lk" && -z "${EXISTING_TITLES[$_ls]:-}" ]] && EXISTING_TITLES["$_ls"]="$_lk"
+  done < <(echo "$_links_json" | jq -r '.fields.issuelinks[]? | (.outwardIssue // .inwardIssue) | "\(.key)|\(.fields.summary)"')
+
+  echo "Found ${#EXISTING_TITLES[@]} existing child/linked issue(s) for dedup"
+fi
Relevance

●● Moderate

Dedup-related reliability suggestions were accepted (PR #10), but no specific GitHub child-issue
dedup precedent found.

PR-#10

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The dedup fetch is guarded by ISSUE_SOURCE == jira, so GitHub executions never populate
EXISTING_TITLES, contradicting the documented behavior and allowing duplicates on reruns.

scripts/create-children.sh[255-283]
docs/critique.md[60-66]

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

### Issue description
Deduplication is only implemented for Jira; GitHub runs do not query existing sub-issues/linked issues, so `EXISTING_TITLES` stays empty and the dedup check never triggers.

### Issue Context
Docs explicitly advertise deduplication to avoid double-creation on re-runs.

### Fix Focus Areas
- scripts/create-children.sh[255-283]
- scripts/create-children.sh[306-318]
- docs/critique.md[60-66]

### Expected fix
Implement GitHub dedup by fetching existing children under the parent issue (sub-issues API) and/or searching issues by title within the repo, then populating `EXISTING_TITLES` similarly to the Jira path so repeated runs skip existing children.

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



Informational

10. ::warning:: interpolates title unescaped 📜 Skill insight ⛨ Security
Description
New scripts emit GitHub Actions workflow commands (e.g., ::warning::, ::notice::) while
interpolating untrusted variables like issue titles and API error output without sanitization. This
enables workflow-command injection via ::, %0A/%0D, ANSI, or control characters embedded in
those values.
Code

scripts/create-children.sh[R66-68]

+  result=$(printf '%s' "$body" | gh issue create "${args[@]}" --body-file - 2>&1) || {
+    echo "::warning::Failed to create issue '${title}': ${result}" >&2
+    echo "FAILED"
Relevance

● Weak

Workflow-command injection sanitization was explicitly rejected previously (Makefile ::debug:: case)
in PR #37.

PR-#37

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1538382 requires every interpolated value in GHA workflow commands to be sanitized
individually. The new code emits ::warning::/::notice:: while directly embedding variables like
${title} and ${result} (and other dynamic values) without any sanitize function.

scripts/create-children.sh[66-68]
scripts/create-children.sh[82-83]
scripts/post-critique.sh[139-143]
scripts/pre-critique.sh[33-33]
Skill: pr-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
GitHub Actions workflow commands are emitted with interpolated values that are not individually sanitized, allowing command injection.

## Issue Context
`scripts/create-children.sh`, `scripts/post-critique.sh`, and `scripts/pre-critique.sh` use `echo "::notice::..."` / `echo "::warning::..."` / `echo "::error::..."` while including variables such as titles, HTTP codes, and command output.

## Fix Focus Areas
- scripts/create-children.sh[66-83]
- scripts/create-children.sh[392-400]
- scripts/create-children.sh[469-469]
- scripts/post-critique.sh[139-143]
- scripts/post-critique.sh[149-180]
- scripts/pre-critique.sh[33-33]

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


Grey Divider

Context used
✅ Compliance rules (platform): 55 rules
✅ Skills: 4 invoked
  code-review
  code-implementation
  pr-review
  docs-review

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment thread scripts/post-critique.sh
Comment thread docs/critique.md Outdated
Comment thread policies/critique.yaml
Comment thread scripts/post-critique.sh
Comment thread harness/critique.yaml
Comment thread harness/critique.yaml
Comment thread scripts/create-children.sh
Comment thread scripts/create-children.sh
Comment thread scripts/post-critique.sh
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review

Findings

High

  • [logic-error] scripts/pre-explore.sh:596 — The validate_repo function uses jq -r '.private // true' to check whether a repo is public. However, jq's // (alternative) operator treats both null AND false as falsy. When a public GitHub repo returns {"private": false}, jq evaluates .private // true as true (the fallback), not false. The subsequent == "false" test therefore never succeeds, causing validate_repo to reject ALL repositories — public and private alike. Every referenced repo will be skipped with "not a public repo (or rate-limited)".
    Remediation: Replace .private // true with an explicit conditional, e.g. jq -r 'if .private == null then true else .private end' or use jq's exit code: jq -e '.private == false' >/dev/null 2>&1.

  • [protected-path] agents/critique.md, harness/critique.yaml, policies/critique.yaml, scripts/adf-to-markdown.py, scripts/comment-helpers.sh, scripts/compose-child-markdown.py, scripts/create-children-test.sh, scripts/create-children.sh, scripts/jira-project-schema.sh, scripts/markdown-to-adf.py, scripts/platform-github.md, scripts/platform-gitlab.md, scripts/platform-jira.md, scripts/post-critique-test.sh, scripts/post-critique.sh, scripts/pre-critique.sh, scripts/pre-explore.sh — This PR modifies 17 files under protected paths (agents/, harness/, policies/, scripts/). No linked issue provides authorization for these changes. Human approval is required for all protected-path modifications regardless of context.

Medium

  • [logic-error] scripts/create-children.sh:800 — In the orphan fallback loop, the target_platform == "gitlab" case is not handled. The main topological loop (lines 709–718) correctly skips GitLab children with a "not yet supported" message and continue, but the orphan loop (lines 800–808) only checks for github and jira platforms. A child with target_platform: gitlab falls through to the default creation path.
    Remediation: Add elif [[ "$CHILD_TARGET_PLATFORM" == "gitlab" ]] with a continue and skip message, matching the main loop's behavior.

Low

  • [api-contract] scripts/create-children.sh:307 — The jira_link_blocks function's inwardIssue/outwardIssue mapping relies on a specific Jira Cloud instance's Blocks link type orientation. The code comment documents verification (2026-08-08). If deployed against an instance with a non-standard Blocks definition, the direction could be inverted.

  • [edge-case] scripts/create-children.sh:856 — The dependency materialization guard checks for JIRA_HOST and JIRA_EMAIL but not JIRA_API_TOKEN. If the token is empty, every API call fails with HTTP 401.

  • [api-contract] schemas/critique-result.schema.json:206 — The program_grounding dimension object is missing additionalProperties: false, unlike all other dimension objects in the assessment schema.

  • [missing-dedup] scripts/create-children.sh — The existing-children deduplication block only runs for Jira source. For GitHub source, no dedup is performed — re-runs may create duplicate sub-issues.

  • [logic-error] scripts/post-critique.sh:258 — When AUTO_CREATE=true, source create-children.sh runs in the same shell with set -euo pipefail. If create-children.sh fails, post-critique.sh aborts after posting the approval comment but before posting the child creation summary, leaving the issue in an inconsistent state.

  • [injection-vuln] scripts/create-children.sh:346 — GHA workflow commands (::warning::) interpolate unsanitized values from Jira API responses ($body). While the most dangerous GHA command injections (set-env, add-path) are disabled by default on modern runners, cosmetic injection remains possible.

  • [secret-exposure] scripts/post-critique.sh — The script does not call ::add-mask:: for GH_TOKEN, PUSH_TOKEN, or JIRA_API_TOKEN. Every other post-script in the repo masks its tokens.


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
Previous run

Review

Findings

High

  • [protected-path] agents/critique.md, harness/critique.yaml, policies/critique.yaml, scripts/adf-to-markdown.py, scripts/comment-helpers.sh, scripts/compose-child-markdown.py, scripts/create-children-test.sh, scripts/create-children.sh, scripts/jira-project-schema.sh, scripts/markdown-to-adf.py, scripts/platform-github.md, scripts/platform-gitlab.md, scripts/platform-jira.md, scripts/post-critique-test.sh, scripts/post-critique.sh, scripts/pre-critique.sh, scripts/pre-explore.sh — This PR modifies 17 files under protected paths (agents/, harness/, policies/, scripts/). No linked issue provides authorization for these changes. Human approval is required for all protected-path modifications regardless of context.

Medium

  • [api-contract] scripts/create-children.sh:307 — The jira_link_blocks function's inwardIssue/outwardIssue mapping may be inverted. For the standard Jira Cloud "Blocks" link type, inwardIssue receives the "is blocked by" label and outwardIssue receives the "blocks" label. The code sets inwardIssue = blocker_key and outwardIssue = blocked_key, which per standard API semantics means "blocker is blocked by blocked" — the reverse of the intended direction. The comment claims "(verified 2026-08-08)" but if the tested instance's Blocks definition differs from the standard, the orientation would be wrong on other instances.
    Remediation: Verify the orientation against the Jira Cloud REST API documentation. For standard Jira Cloud, inwardIssue should be the blocked issue and outwardIssue should be the blocker.

  • [logic-error] scripts/create-children.sh:776 — In the orphan fallback loop, the target_platform == "gitlab" case is not handled. The main topological loop correctly skips GitLab children with continue (line 693), but the orphan loop only checks for github and jira platforms. A child with target_platform: gitlab that becomes an orphan falls through without the gitlab guard, causing it to be created on the wrong platform.
    Remediation: Add elif [[ "$CHILD_TARGET_PLATFORM" == "gitlab" ]] with a continue and skip message, matching the main loop's behavior.

Low

  • [injection-vuln] scripts/create-children.sh — New GHA workflow commands (::warning::, ::notice::) interpolate unsanitized values from Jira API responses ($body, $resolved) and agent-supplied JSON ($DEP_TARGET, $DEP_TYPE). The repo has gha_echo in lib/post-failure-report.lib.sh but this script does not source or use it.

  • [edge-case] scripts/create-children.sh:826 — The dependency materialization guard checks for JIRA_HOST and JIRA_EMAIL but not JIRA_API_TOKEN. If the token is empty, every API call fails with HTTP 401 producing noisy warnings.

  • [edge-case] scripts/create-children.sh:284 — When jira_resolve_link_type is called with "Blocks" and no match is found, the function uses the literal string "Blocks" and caches it. If the Jira instance names its blocking link type differently, link creation will fail with unclear error messages.

  • [api-contract] schemas/critique-result.schema.json:206 — The program_grounding dimension object is missing additionalProperties: false, unlike all other dimension objects in the assessment schema.

  • [missing-dedup] scripts/create-children.sh — The existing-children deduplication block only runs for Jira source. For GitHub source, no dedup is performed — re-runs may create duplicate sub-issues.

  • [logic-error] scripts/post-critique.sh:258 — When AUTO_CREATE=true, source create-children.sh runs in the same shell with set -euo pipefail. If create-children.sh fails, post-critique.sh aborts after posting the approval comment but before posting the child creation summary, leaving the issue in an inconsistent state.

  • [secret-exposure] scripts/post-critique.sh — The script does not call ::add-mask:: for GH_TOKEN, PUSH_TOKEN, or JIRA_API_TOKEN. Every other post-script in the repo masks its tokens.


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
Previous run (2)

Review

Findings

High

  • [protected-path] agents/critique.md, harness/critique.yaml, policies/critique.yaml, scripts/adf-to-markdown.py, scripts/comment-helpers.sh, scripts/compose-child-markdown.py, scripts/create-children-test.sh, scripts/create-children.sh, scripts/jira-project-schema.sh, scripts/markdown-to-adf.py, scripts/platform-github.md, scripts/platform-gitlab.md, scripts/platform-jira.md, scripts/post-critique-test.sh, scripts/post-critique.sh, scripts/pre-critique.sh, scripts/pre-explore.sh — This PR modifies 17 files under protected paths (agents/, harness/, policies/, scripts/). No linked issue provides authorization for these changes. Human approval is required for all protected-path modifications regardless of context.

Medium

  • [logic-error] scripts/create-children.sh:735 — In the orphan fallback loop, the target_platform == "gitlab" case is not handled. The main topological loop correctly skips GitLab children with continue, but the orphan loop only checks for github and jira platforms. A child with target_platform: gitlab that becomes an orphan falls through without the gitlab guard, causing it to be created on the wrong platform.
    Remediation: Add elif [[ "$CHILD_TARGET_PLATFORM" == "gitlab" ]] with a continue and skip message, matching the main loop's behavior.

  • [injection-vuln] scripts/create-children.sh — Multiple GHA workflow commands (::notice::, ::warning::) interpolate unsanitized agent-controlled values. The repo has established sanitize_gha() in post-scribe.sh and gha_echo() in lib/post-failure-report.lib.sh — none are used in this script. Affected variables include: project_key (line 229), title/result (line 297), body (lines 498, 536, 570 — from Jira API responses), CREATED_KEYS (line 859). See also: [injection-vuln] findings in post-critique.sh and jira-project-schema.sh.
    Remediation: Source lib/post-failure-report.lib.sh and use gha_echo for all workflow command emissions.

Low

  • [logic-error] scripts/compose-child-markdown.py:51 — The parts list uses "\n".join() but each appended string already starts with "\n\n", producing triple newlines between sections. The old inline shell template produced double newlines. While extra blank lines are harmless in markdown rendering, this changes the output shape fed to the ADF conversion pipeline.

  • [injection-vuln] scripts/jira-project-schema.sh — GHA workflow commands interpolate unsanitized values. Most affected variables (project_key) are validated by jira_schema_valid_project_key() which enforces ^[A-Z][A-Z0-9]{1,14}$, limiting injection risk. Field key from agent JSON custom_fields is less constrained.

  • [injection-vuln] scripts/post-critique.shecho "::notice::${CHILD_SUMMARY}" interpolates CHILD_SUMMARY which includes CREATED_CHILD_KEYS (Jira issue keys or GitHub issue numbers — constrained formats). Additional unsanitized workflow commands at other lines.

  • [secret-exposure] scripts/post-critique.sh — The script does not call ::add-mask:: for GH_TOKEN, PUSH_TOKEN, or JIRA_API_TOKEN. Every other post-script in the repo masks its tokens.

  • [api-contract] schemas/critique-result.schema.json:206 — The program_grounding dimension object is missing additionalProperties: false, unlike all other dimension objects in the assessment schema.

  • [missing-dedup] scripts/create-children.sh — The existing-children deduplication block only runs for Jira source. For GitHub source, no dedup is performed — re-runs may create duplicate sub-issues.

  • [logic-error] scripts/post-critique.sh:258 — When AUTO_CREATE=true, source create-children.sh runs in the same shell with set -euo pipefail. If create-children.sh fails, post-critique.sh aborts after posting the approval comment but before posting the child creation summary, leaving the issue in an inconsistent state.


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
Previous run (3)

Review

Findings

High

  • [protected-path] agents/critique.md, harness/critique.yaml, policies/critique.yaml, scripts/adf-to-markdown.py, scripts/comment-helpers.sh, scripts/create-children-test.sh, scripts/create-children.sh, scripts/jira-project-schema.sh, scripts/markdown-to-adf.py, scripts/platform-github.md, scripts/platform-gitlab.md, scripts/platform-jira.md, scripts/post-critique-test.sh, scripts/post-critique.sh, scripts/pre-critique.sh, scripts/pre-explore.sh — This PR modifies 16 files under protected paths (agents/, harness/, policies/, scripts/). No linked issue provides authorization for these changes. Human approval is required for all protected-path modifications regardless of context.

Medium

  • [logic-error] scripts/create-children.sh:735 — In the orphan fallback loop, the target_platform == "gitlab" case is not handled. The main topological loop correctly skips GitLab children with continue (line 647), but the orphan loop only checks for github and jira platforms. A child with target_platform: gitlab that becomes an orphan falls through without the gitlab guard, causing it to be created on the wrong platform.
    Remediation: Add elif [[ "$CHILD_TARGET_PLATFORM" == "gitlab" ]] with a continue and skip message, matching the main loop's behavior.

  • [injection-vuln] scripts/create-children.sh — Multiple GHA workflow commands (::notice::, ::warning::) interpolate unsanitized agent-controlled values. The repo has established sanitize_gha() in post-scribe.sh and gha_echo() in lib/post-failure-report.lib.sh — none are used in this script. Affected variables include: project_key (lines 153, 199), title/result (line 221), body (lines 319, 339, 411, 449, 483 — from Jira API responses), summary (line 411), CREATED_KEYS (line 786).
    Remediation: Source lib/post-failure-report.lib.sh and use gha_echo for all workflow command emissions.

Low

  • [injection-vuln] scripts/jira-project-schema.sh — GHA workflow commands interpolate unsanitized values. Most affected variables (project_key) are validated by jira_schema_valid_project_key() which enforces ^[A-Z][A-Z0-9]{1,14}$, limiting injection risk. Field key at line 125 from agent JSON custom_fields is less constrained.

  • [injection-vuln] scripts/post-critique.sh:261echo "::notice::${CHILD_SUMMARY}" interpolates CHILD_SUMMARY which includes CREATED_CHILD_KEYS (Jira issue keys or GitHub issue numbers — constrained formats). Additional unsanitized workflow commands at lines 361 and 371.

  • [data-shape-mismatch] scripts/create-children.sh:195 — The new fallback that synthesizes usable types from the allowlist produces objects with only {name, subtask} fields, while the normal path produces {name, subtask, hierarchyLevel, description}. Downstream consumers accessing hierarchyLevel would get null. Mitigated by being a fallback path.

  • [api-contract] schemas/critique-result.schema.json:206 — The program_grounding dimension object is missing additionalProperties: false, unlike all other dimension objects in the assessment schema.

  • [missing-dedup] scripts/create-children.sh:543 — The existing-children deduplication block only runs for Jira source. For GitHub source, no dedup is performed — re-runs may create duplicate sub-issues.

  • [logic-error] scripts/post-critique.sh:258 — When AUTO_CREATE=true, source create-children.sh runs in the same shell with set -euo pipefail. If create-children.sh fails, post-critique.sh aborts after posting the approval comment but before posting the child creation summary, leaving the issue in an inconsistent state.

  • [secret-exposure] scripts/post-critique.sh — The script does not call ::add-mask:: for GH_TOKEN, PUSH_TOKEN, or JIRA_API_TOKEN. Every other post-script in the repo masks its tokens.


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
Previous run (4)

Review

Findings

High

  • [protected-path] agents/critique.md, harness/critique.yaml, policies/critique.yaml, scripts/adf-to-markdown.py, scripts/comment-helpers.sh, scripts/create-children-test.sh, scripts/create-children.sh, scripts/jira-project-schema.sh, scripts/markdown-to-adf.py, scripts/platform-github.md, scripts/platform-gitlab.md, scripts/platform-jira.md, scripts/post-critique-test.sh, scripts/post-critique.sh, scripts/pre-critique.sh, scripts/pre-explore.sh — This PR modifies 16 files under protected paths (agents/, harness/, policies/, scripts/). No linked issue provides authorization for these changes. Human approval is required for all protected-path modifications regardless of context.

Medium

  • [logic-error] scripts/create-children.sh:720 — In the orphan fallback loop, the target_platform == "gitlab" case is not handled. The main topological loop correctly skips GitLab children with continue (line 630), but the orphan loop only checks for github and jira platforms. A child with target_platform: gitlab that becomes an orphan falls through without the gitlab guard, causing it to be created on the wrong platform.
    Remediation: Add elif [[ "$CHILD_TARGET_PLATFORM" == "gitlab" ]] with a continue and skip message, matching the main loop's behavior.

  • [injection-vuln] scripts/create-children.sh, scripts/jira-project-schema.sh, scripts/post-critique.sh — Multiple GHA workflow commands (::notice::, ::warning::) interpolate unsanitized agent-controlled values: child titles from agent JSON, Jira API error responses, target_project keys, custom_fields keys, and CHILD_SUMMARY. The repo has established sanitize_gha() in post-scribe.sh and gha_echo() in post-code.sh/post-fix.sh — none are used in these new scripts.
    Remediation: Import or redefine sanitize_gha() and apply to all interpolated variables in workflow commands across all three scripts.

Low

  • [api-contract] schemas/critique-result.schema.json:206 — The program_grounding dimension object is missing additionalProperties: false, unlike all other dimension objects in the assessment schema.

  • [missing-dedup] scripts/create-children.sh:530 — The existing-children deduplication block only runs for Jira source. For GitHub source, no dedup is performed — re-runs may create duplicate sub-issues.

  • [logic-error] scripts/post-critique.sh:258 — When AUTO_CREATE=true, source create-children.sh runs in the same shell with set -euo pipefail. If create-children.sh fails, post-critique.sh aborts after posting the approval comment but before posting the child creation summary, leaving the issue in an inconsistent state.

  • [secret-exposure] scripts/post-critique.sh — The script does not call ::add-mask:: for GH_TOKEN, PUSH_TOKEN, or JIRA_API_TOKEN. Every other post-script in the repo masks its tokens.


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
Previous run (5)

Review

Findings

High

  • [protected-path] agents/critique.md, harness/critique.yaml, policies/critique.yaml, scripts/adf-to-markdown.py, scripts/comment-helpers.sh, scripts/create-children-test.sh, scripts/create-children.sh, scripts/jira-project-schema.sh, scripts/markdown-to-adf.py, scripts/platform-github.md, scripts/platform-gitlab.md, scripts/platform-jira.md, scripts/post-critique-test.sh, scripts/post-critique.sh, scripts/pre-critique.sh, scripts/pre-explore.sh — This PR modifies 16 files under protected paths (agents/, harness/, policies/, scripts/). No linked issue provides authorization for these changes. Human approval is required for all protected-path modifications regardless of context.

Medium

  • [logic-error] scripts/create-children.sh:720 — In the orphan fallback loop, the target_platform == "gitlab" case is not handled. The main topological loop correctly skips GitLab children with continue (line 630), but the orphan loop only checks for github and jira platforms. A child with target_platform: gitlab that becomes an orphan falls through without the gitlab guard, causing it to be created on the wrong platform.
    Remediation: Add elif [[ "$CHILD_TARGET_PLATFORM" == "gitlab" ]] with a continue and skip message, matching the main loop's behavior.

  • [display-error] scripts/comment-helpers.sh:711format_assessment_table_md displays the overall score as ${overall}/100 but the critique agent and schema use a 0–5 scale (assessment.overall has maximum: 5). The post-critique.sh sticky comment correctly uses /5. The format_assessment_table_md helper will display e.g. "Overall: 4.2/100" instead of "Overall: 4.2/5".
    Remediation: Change line 711 from echo "**Overall: ${overall}/100**" to echo "**Overall: ${overall}/5**".

  • [injection-vuln] scripts/create-children.sh, scripts/jira-project-schema.sh, scripts/post-critique.sh — Multiple GHA workflow commands (::notice::, ::warning::) interpolate unsanitized agent-controlled values: child titles from agent JSON, Jira API error responses, target_project keys, custom_fields keys, and CHILD_SUMMARY. The repo has established sanitize_gha() in post-scribe.sh and gha_echo() in post-code.sh/post-fix.sh — none are used in these new scripts.
    Remediation: Import or redefine sanitize_gha() and apply to all interpolated variables in workflow commands across all three scripts.

Low

  • [api-contract] schemas/critique-result.schema.json:208 — The program_grounding dimension object is missing additionalProperties: false, unlike all other dimension objects in the assessment schema.

  • [missing-dedup] scripts/create-children.sh:530 — The existing-children deduplication block only runs for Jira source. For GitHub source, no dedup is performed — re-runs may create duplicate sub-issues.

  • [logic-error] scripts/post-critique.sh:258 — When AUTO_CREATE=true, source create-children.sh runs in the same shell with set -euo pipefail. If create-children.sh fails, post-critique.sh aborts after posting the approval comment but before posting the child creation summary, leaving the issue in an inconsistent state.

  • [secret-exposure] scripts/post-critique.sh — The script does not call ::add-mask:: for GH_TOKEN, PUSH_TOKEN, or JIRA_API_TOKEN. Every other post-script in the repo masks its tokens.


Labels: PR adds a new agent with 16 files under protected paths and has security findings (GHA workflow command injection)


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
Previous run (6)

Review

Findings

High

  • [protected-path] agents/critique.md, harness/critique.yaml, policies/critique.yaml, scripts/adf-to-markdown.py, scripts/comment-helpers.sh, scripts/create-children-test.sh, scripts/create-children.sh, scripts/jira-project-schema.sh, scripts/markdown-to-adf.py, scripts/platform-github.md, scripts/platform-gitlab.md, scripts/platform-jira.md, scripts/post-critique-test.sh, scripts/post-critique.sh, scripts/pre-critique.sh, scripts/pre-explore.sh — This PR modifies 16 files under protected paths (agents/, harness/, policies/, scripts/). No linked issue provides authorization for these changes. Human approval is required for all protected-path modifications regardless of context.

Medium

  • [logic-error] scripts/create-children.sh:720 — In the orphan fallback loop, the target_platform == "gitlab" case is not handled. The main topological loop correctly skips GitLab children with continue (line 633), but the orphan loop only checks for github and jira platforms. A child with target_platform: gitlab that becomes an orphan falls through without the gitlab guard, causing it to be created on the wrong platform.
    Remediation: Add elif [[ "$CHILD_TARGET_PLATFORM" == "gitlab" ]] with a continue and skip message, matching the main loop's behavior.

  • [injection-vuln] scripts/create-children.sh — Multiple GHA workflow commands (::notice::, ::warning::) interpolate unsanitized agent-controlled values throughout create-children.sh, post-critique.sh, and jira-project-schema.sh. Affected variables include child titles from agent JSON, Jira API error responses, GitHub API error output. The repo has established sanitize_gha() in post-scribe.sh and gha_echo() in post-code.sh/post-fix.sh — none are used in these new scripts.
    Remediation: Import or redefine sanitize_gha() and apply to all interpolated variables in workflow commands across all three scripts.

Low

  • [api-contract] schemas/critique-result.schema.json:208 — The program_grounding dimension object is missing additionalProperties: false, unlike all other dimension objects in the assessment schema.

  • [missing-host-file] harness/critique.yamlenv/critique.env sets ORG_KNOWLEDGE=/sandbox/workspace/org-knowledge.md but harness/critique.yaml has no host_files entry to inject this file into the sandbox. The pre-critique.sh generates this file on the runner, but without a host_files mapping it will never exist inside the sandbox, making program_grounding permanently un-scorable.

  • [missing-dedup] scripts/create-children.sh:530 — The existing-children deduplication block only runs for Jira source. For GitHub source, no dedup is performed — re-runs may create duplicate sub-issues.

  • [logic-error] scripts/post-critique.sh:150 — When AUTO_CREATE=true, source create-children.sh runs in the same shell with set -euo pipefail. If create-children.sh fails, post-critique.sh aborts after posting the approval comment but before posting the child creation summary, leaving the issue in an inconsistent state.

  • [secret-exposure] scripts/post-critique.sh, scripts/create-children.sh — Neither script calls ::add-mask:: for GH_TOKEN, PUSH_TOKEN, or JIRA_API_TOKEN. Every other post-script in the repo masks its tokens.

  • [schema-validation-gap] schemas/explore-result.schema.json — The explore-result schema's top-level object and several sub-objects lack additionalProperties: false, unlike the critique-result schema pattern.

  • [dead-code] scripts/comment-helpers.sh:745 — The --no-expand flag path for Jira Data Center in sticky_comment and new_comment is unreachable. validate_jira_host enforces *.atlassian.net, so any non-Cloud Jira host will fail validation before the comment code executes.

  • [edge-case] scripts/pre-explore.sh:773 — The comment-fetching loop does not validate that ADF conversion via python3 adf-to-markdown.py succeeds. If the conversion produces empty output without a non-zero exit code, the body file for that comment will be empty.


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
Previous run (7)

Review

Findings

High

  • [protected-path] agents/critique.md, harness/critique.yaml, policies/critique.yaml, scripts/adf-to-markdown.py, scripts/comment-helpers.sh, scripts/create-children-test.sh, scripts/create-children.sh, scripts/jira-project-schema.sh, scripts/markdown-to-adf.py, scripts/platform-github.md, scripts/platform-gitlab.md, scripts/platform-jira.md, scripts/post-critique-test.sh, scripts/post-critique.sh, scripts/pre-critique.sh, scripts/pre-explore.sh — This PR modifies 16 files under protected paths (agents/, harness/, policies/, scripts/). No linked issue provides authorization for these changes. Human approval is required for all protected-path modifications regardless of context.

Medium

  • [logic-error] scripts/create-children.sh:720 — In the orphan fallback loop, the target_platform == "gitlab" case is not handled. The main topological loop correctly skips GitLab children with continue (line 633), but the orphan loop only checks for github and jira platforms. A child with target_platform: gitlab that becomes an orphan falls through without the gitlab guard, causing it to be created on the wrong platform.
    Remediation: Add elif [[ "$CHILD_TARGET_PLATFORM" == "gitlab" ]] with a continue and skip message, matching the main loop's behavior.

  • [injection-vuln] scripts/create-children.sh — Multiple GHA workflow commands (::notice::, ::warning::) interpolate unsanitized agent-controlled values throughout create-children.sh, post-critique.sh, and jira-project-schema.sh. Affected variables include child titles from agent JSON, Jira API error responses, GitHub API error output, link-type names, and custom field keys. The repo has established sanitize_gha() in post-scribe.sh and gha_echo() in post-code.sh/post-fix.sh — none are used in these new scripts.
    Remediation: Import or redefine sanitize_gha() and apply to all interpolated variables in workflow commands across all three scripts.

Low

  • [missing-authorization] README.md — This PR adds a complete new agent (~6,000 lines) with no linked issue. Non-trivial changes require explicit authorization to establish scope.

  • [scope-clarity] README.md — The PR depends on shared scripts from feat: add generic explore agent #11 (explore agent). The dependency relationship and sequencing between PRs is unclear — the changed files since prior review (comment-helpers.sh, pre-explore.sh) are new in this diff but described as shared scripts from feat: add generic explore agent #11.

  • [api-contract] schemas/critique-result.schema.json:208 — The program_grounding dimension object is missing additionalProperties: false, unlike all other dimension objects in the assessment schema.

  • [missing-host-file] harness/critique.yamlenv/critique.env sets ORG_KNOWLEDGE=/sandbox/workspace/org-knowledge.md but harness/critique.yaml has no host_files entry to inject this file into the sandbox. The pre-critique.sh generates this file on the runner, but without a host_files mapping it will never exist inside the sandbox, making program_grounding permanently un-scorable.

  • [missing-dedup] scripts/create-children.sh:530 — The existing-children deduplication block only runs for Jira source. For GitHub source, no dedup is performed — re-runs will create duplicate sub-issues.

  • [logic-error] scripts/post-critique.sh:150 — When AUTO_CREATE=true, source create-children.sh runs in the same shell with set -euo pipefail. If create-children.sh fails, post-critique.sh aborts after posting the approval comment but before posting the child creation summary, leaving the issue in an inconsistent state.

  • [secret-exposure] scripts/post-critique.sh, scripts/create-children.sh — Neither script calls ::add-mask:: for GH_TOKEN, PUSH_TOKEN, or JIRA_API_TOKEN. Every other post-script in the repo masks its tokens.


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
Previous run (8)

Review

Findings

High

  • [protected-path] agents/critique.md, harness/critique.yaml, policies/critique.yaml, scripts/adf-to-markdown.py, scripts/comment-helpers.sh, scripts/create-children-test.sh, scripts/create-children.sh, scripts/jira-project-schema.sh, scripts/markdown-to-adf.py, scripts/platform-github.md, scripts/platform-gitlab.md, scripts/platform-jira.md, scripts/post-critique-test.sh, scripts/post-critique.sh, scripts/pre-critique.sh, scripts/pre-explore.sh — This PR modifies 16 files under protected paths (agents/, harness/, policies/, scripts/). No linked issue provides authorization for these changes. Human approval is required for all protected-path modifications regardless of context.

Medium

  • [logic-error] scripts/create-children.sh:720 — In the orphan fallback loop, the target_platform == "gitlab" case is not handled. The main topological loop correctly skips GitLab children with continue (line 633), but the orphan loop only checks for github and jira platforms. A child with target_platform: gitlab that becomes an orphan falls through to the GitHub or Jira creation path, creating the issue on the wrong platform.
    Remediation: Add elif [[ "$CHILD_TARGET_PLATFORM" == "gitlab" ]] with a continue, matching the main loop's behavior.

  • [injection-vuln] scripts/create-children.sh:771 — Multiple GHA workflow commands (::notice::, ::warning::) interpolate unsanitized agent-controlled values: child titles from agent JSON, Jira API error responses, GitHub API error output, and link-type names. The repo has established sanitize_gha() in post-scribe.sh and gha_echo() in post-code.sh/post-fix.sh — none are used here.
    Remediation: Import or redefine sanitize_gha() and apply to all interpolated variables in workflow commands in both create-children.sh and post-critique.sh.

Low

  • [injection-vuln] scripts/post-critique.sh:261::notice:: interpolates $CHILD_SUMMARY (containing $CREATED_CHILD_KEYS from create-children.sh) without sanitization. See also: [injection-vuln] finding in create-children.sh.

  • [api-contract] schemas/critique-result.schema.json:208 — The program_grounding dimension object is missing additionalProperties: false, unlike all other dimension objects in the assessment schema.

  • [missing-host-file] harness/critique.yaml:13env/critique.env sets ORG_KNOWLEDGE=/sandbox/workspace/org-knowledge.md but harness/critique.yaml has no host_files entry to inject this file into the sandbox. The pre-critique.sh generates this file via pack_org_knowledge(), but without the host_files mapping it will never exist in the sandbox, making program_grounding permanently un-scorable.

  • [missing-dedup] scripts/create-children.sh:530 — The existing-children deduplication block only runs for Jira source. For GitHub source, no dedup is performed — re-runs will create duplicate sub-issues.

  • [logic-error] scripts/post-critique.sh:150 — When AUTO_CREATE=true, source create-children.sh runs in the same shell with set -euo pipefail. If create-children.sh fails, post-critique.sh aborts after posting the approval comment but before posting the child creation summary, leaving the issue in an inconsistent state.

  • [secret-exposure] scripts/post-critique.sh, scripts/create-children.sh — Neither script calls ::add-mask:: for GH_TOKEN, PUSH_TOKEN, or JIRA_API_TOKEN. Every other post-script in the repo masks its tokens.

  • [scope-clarity] README.md — The PR depends on shared scripts from feat: add generic explore agent #11 (explore agent). The dependency relationship and sequencing between PRs is unclear — whether this PR is independently functional or requires feat: add generic explore agent #11 to land first.


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
Previous run (9)

Review

Findings

High

  • [protected-path] agents/critique.md, harness/critique.yaml, policies/critique.yaml, scripts/adf-to-markdown.py, scripts/comment-helpers.sh, scripts/create-children-test.sh, scripts/create-children.sh, scripts/jira-project-schema.sh, scripts/markdown-to-adf.py, scripts/platform-github.md, scripts/platform-gitlab.md, scripts/platform-jira.md, scripts/post-critique-test.sh, scripts/post-critique.sh, scripts/pre-critique.sh, scripts/pre-explore.sh — This PR modifies 16 files under protected paths (agents/, harness/, policies/, scripts/). No linked issue provides authorization for these changes. Human approval is required for all protected-path modifications regardless of context.

Medium

  • [logic-error] scripts/create-children.sh:722 — In the orphan fallback loop, the target_platform == "gitlab" case is not handled. The main topological loop correctly skips GitLab children with continue (line 633), but the orphan loop only checks for github and jira platforms. A child with target_platform: gitlab that becomes an orphan falls through to the GitHub or Jira creation path, creating the issue on the wrong platform.
    Remediation: Add elif [[ "$CHILD_TARGET_PLATFORM" == "gitlab" ]] with a continue, matching the main loop's behavior.

  • [injection-vuln] scripts/create-children.sh:217 — Multiple GHA workflow commands (::notice::, ::warning::) interpolate unsanitized agent-controlled values: child titles from agent JSON (line 217 via $title, line 771 via ${CREATED_KEYS[*]}), Jira API error responses (lines 315, 335, 396, 434 via $body), and project keys from agent JSON (lines 155, 195). The repo has established sanitize_gha() in post-scribe.sh and gha_echo() in post-code.sh/post-fix.sh — none are used here.
    Remediation: Import or duplicate sanitize_gha() and apply to all interpolated variables in workflow commands.

Low

  • [logic-error] scripts/post-critique.sh:1038 — When AUTO_CREATE=true, source create-children.sh runs in the same shell with set -euo pipefail. If create-children.sh fails, post-critique.sh aborts after posting the approval comment but before posting the child creation summary, leaving the issue in an inconsistent state.

  • [injection-vuln] scripts/post-critique.sh:1041::notice:: interpolates $CHILD_SUMMARY (containing $CREATED_CHILD_KEYS from create-children.sh) without sanitization. See also: [injection-vuln] finding in create-children.sh.

  • [api-contract] schemas/critique-result.schema.json:208 — The program_grounding dimension object is missing additionalProperties: false, unlike all other dimension objects in the assessment schema.

  • [edge-case] scripts/create-children.sh:564 — The script reads .children from RESULT_FILE without validating the field exists. If .children is absent, jq errors with "null has no length" and the script exits with a raw error message.

  • [missing-host-file] harness/critique.yaml:13env/critique.env sets ORG_KNOWLEDGE=/sandbox/workspace/org-knowledge.md but harness/critique.yaml has no host_files entry to inject this file into the sandbox. The agent will see ORG_KNOWLEDGE pointing at a nonexistent path.

  • [missing-dedup] scripts/create-children.sh:530 — The existing-children deduplication block only runs for Jira source. For GitHub source, no dedup is performed — re-runs will create duplicate sub-issues.

  • [secret-exposure] scripts/post-critique.sh, scripts/create-children.sh — Neither script calls ::add-mask:: for GH_TOKEN, PUSH_TOKEN, or JIRA_API_TOKEN. Every other post-script in the repo masks its tokens.


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
Previous run (10)

Review

Findings

High

  • [protected-path] agents/critique.md, harness/critique.yaml, policies/critique.yaml, scripts/adf-to-markdown.py, scripts/comment-helpers.sh, scripts/create-children-test.sh, scripts/create-children.sh, scripts/markdown-to-adf.py, scripts/platform-github.md, scripts/platform-gitlab.md, scripts/platform-jira.md, scripts/post-critique-test.sh, scripts/post-critique.sh, scripts/pre-critique.sh — This PR modifies 14 files under protected paths (agents/, harness/, policies/, scripts/). No linked issue provides authorization for these changes. Human approval is required for all protected-path modifications regardless of context.

  • [missing-dependency] scripts/create-children.sh:29create-children.sh sources jira-project-schema.sh at line 29, but this file is neither in this PR nor in the repository. All jira_schema_* functions used throughout create-children.sh are undefined. create-children-test.sh also sources it. With set -euo pipefail, source will fail immediately, aborting the auto-create flow. The PR description acknowledges "Depends on shared scripts from feat: add generic explore agent #11", but there is no merge-order guard.
    Remediation: Either include jira-project-schema.sh in this PR, add a runtime guard that checks for the file before sourcing, or enforce merge ordering via CI.

Medium

  • [logic-error] scripts/create-children.sh — In the orphan fallback loop, the target_platform == "gitlab" case is not handled. The main topological loop correctly skips GitLab children with continue, but the orphan loop only checks for github and jira platforms. A child with target_platform: gitlab will be created on the wrong platform instead of being skipped.
    Remediation: Add the same gitlab platform check in the orphan fallback loop.

  • [logic-error] scripts/post-critique.sh:208 — When AUTO_CREATE=true, source create-children.sh runs in the same shell with set -euo pipefail. If create-children.sh fails (e.g., missing jira-project-schema.sh, API error), post-critique.sh aborts after posting the approval comment but before posting the child creation summary, leaving the issue in an inconsistent state.
    Remediation: Run create-children.sh as a subprocess (bash "$(_resolve_companion create-children.sh)") or wrap the source in error handling.

  • [injection-vuln] scripts/create-children.sh — Multiple ::notice:: and ::warning:: GHA workflow commands interpolate unsanitized values from agent JSON output (child titles, project keys) and Jira API error responses. The repo has established sanitize_gha() in post-scribe.sh and gha_echo() in post-code.sh/post-fix.sh — none are used here.
    Remediation: Import and apply sanitize_gha() or gha_echo() to all interpolated values before emitting workflow commands.

  • [injection-vuln] scripts/post-critique.sh::notice:: and ::warning:: commands interpolate $CHILD_SUMMARY (from create-children.sh with agent-controlled content), $ISSUE_KEY, and other values without sanitization.
    Remediation: Sanitize all interpolated values using the established sanitize_gha() or gha_echo() patterns.

Low

  • [api-contract] schemas/critique-result.schema.json — The schema's conditional validation only requires assessment when verdict is approved. The revise and needs_input blocks do not require it. post-critique.sh unconditionally reads .assessment.overall // 0 and displays "Score: 0/100" for all verdicts when assessment is absent. In practice the agent prompt instructs assessment for all verdicts, making the mismatch unlikely but worth noting.

  • [schema-inconsistency] schemas/critique-result.schema.json — The program_grounding dimension object is missing additionalProperties: false, which is present on all other dimension objects in the assessment schema.

  • [injection-vuln] scripts/pre-critique.sh::notice:: interpolates $ISSUE_KEY and $ISSUE_SOURCE without sanitization. These are runner-side environment variables set by the harness (lower risk than agent-controlled values in findings above).

  • [logic-error] scripts/post-critique.sh — Jira label handling is only implemented for the revise under limit verdict path. The approved, escalation, and needs_input paths only add labels on GitHub via add_label. Jira issues will not receive pipeline-control labels for non-revise verdicts.

  • [edge-case] scripts/create-children.sh — The script reads .children from RESULT_FILE without validating the field exists. If absent, jq returns 0 and the script silently creates no children with no warning.

  • [missing-host-file] harness/critique.yamlenv/critique.env sets ORG_KNOWLEDGE=/sandbox/workspace/org-knowledge.md but harness/critique.yaml has no host_files entry to inject this file. The env var will always point to a nonexistent path.

  • [secret-exposure] scripts/post-critique.sh, scripts/create-children.sh — Neither script calls ::add-mask:: for GH_TOKEN, PUSH_TOKEN, or JIRA_API_TOKEN. Every other post-script in the repo masks its tokens.

  • [error-message-format] scripts/create-children.sh — Error messages use inconsistent prefixes: ERROR: (early validation) vs ::warning:: and ::notice:: (runtime). Other post-scripts use ::error:: or gha_echo error for fatal messages.


Labels: PR adds a new critique agent with supporting infrastructure — enhancement label fits the content classification convention.


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
Previous run (11)

Review

Findings

High

  • [protected-path] agents/critique.md, harness/critique.yaml, policies/critique.yaml, scripts/create-children.sh, scripts/post-critique-test.sh, scripts/post-critique.sh, scripts/pre-critique.sh — This PR modifies 7 files under protected paths (agents/, harness/, policies/, scripts/). No linked issue provides authorization for these changes. Human approval is required for all protected-path modifications regardless of context.

Medium

  • [api-contract] schemas/critique-result.schema.json — The schema's conditional validation only requires assessment when verdict is approved. The revise and needs_input blocks do not require it. However, post-critique.sh unconditionally reads .assessment.overall // 0 and displays "Score: 0/100" when assessment is absent, which is misleading.
    Remediation: Add assessment to the required arrays for revise and needs_input, or conditionally omit the Score row when .assessment is null.

  • [logic-error] scripts/post-critique.sh:60 — The guard checks only ${SCRIPT_DIR}/comment-helpers.sh and exits if missing, but the subsequent source uses _resolve_companion which also searches ${GITHUB_WORKSPACE}/.fullsend/scripts and ${FULLSEND_DIR}/scripts. In harness-base composition deployments, the guard exits prematurely before _resolve_companion can find the file.
    Remediation: Replace the guard with _resolve_companion itself, which already provides descriptive error messages on failure.

  • [logic-error] scripts/post-critique.sh:204 — When AUTO_CREATE=true, source create-children.sh runs in the same shell with set -euo pipefail. If create-children.sh fails (e.g., missing markdown-to-adf.py), the entire post-critique.sh aborts after posting the approval comment but before posting the child creation summary, leaving the issue in an inconsistent state.
    Remediation: Run create-children.sh as a subprocess (bash "${SCRIPT_DIR}/create-children.sh"), or wrap the source in error handling.

  • [injection-vuln] scripts/create-children.sh — Multiple ::notice:: and ::warning:: GHA workflow commands interpolate unsanitized values from agent JSON (.children[].title) and Jira API error responses ($body). The repo has established sanitize_gha() in post-scribe.sh and sanitize_gha_log_output()/gha_echo() in scripts/lib/post-failure-report.lib.sh — none are used here.
    Remediation: Apply sanitize_gha() or gha_echo() to all interpolated values before emitting workflow commands.

  • [injection-vuln] scripts/post-critique.sh::notice:: and ::warning:: commands interpolate $CHILD_SUMMARY, $ISSUE_KEY, and other env vars without sanitization. The repo convention (post-code.sh, post-fix.sh, post-scribe.sh) is to sanitize all values in workflow commands.
    Remediation: Sanitize all interpolated values using the established sanitize_gha() or gha_echo() patterns.

  • [injection-vuln] scripts/pre-critique.sh::notice:: interpolates $ISSUE_SOURCE, $ISSUE_KEY, $REVIEW_ROUND, and $MAX_REVIEW_ROUNDS without sanitization.
    Remediation: Apply sanitize_gha() to $ISSUE_KEY and $ISSUE_SOURCE.

Low

  • [logic-error] scripts/post-critique.sh — Jira label handling is only implemented for the revise under limit verdict path (curl PUT). The approved, escalation, and needs_input paths only add labels on GitHub. Jira issues will not receive pipeline-control labels for non-revise verdicts.

  • [test-inadequate] scripts/post-critique-test.sh — Tests define standalone copies of determine_reply_target, determine_verdict_action, and determine_labels rather than testing the actual post-critique.sh code paths. If the inline logic diverges, tests pass while production behavior is broken.

  • [edge-case] scripts/create-children.sh — The script reads .children from RESULT_FILE without validating the field exists. If absent, jq returns 0 and the script silently creates no children with no warning.

  • [missing-host-file] harness/critique.yamlenv/critique.env sets ORG_KNOWLEDGE=/sandbox/workspace/org-knowledge.md but harness/critique.yaml has no host_files entry to inject this file. The env var will always point to a nonexistent path.

  • [secret-exposure] scripts/post-critique.sh, scripts/create-children.sh — Neither script calls ::add-mask:: for GH_TOKEN, PUSH_TOKEN, or JIRA_API_TOKEN. Every other post-script in the repo masks its tokens.

Previous run (12)

Review — #87

Verdict Comment
Reviewed 13d4552
Findings 3 medium, 3 low
Re-review 1 of 4 prior findings addressed

Summary

The latest commit (13d4552) resolves the highest-severity finding from the prior review: post-critique-test.sh is now registered in the Makefile script-test target. Additional improvements include additionalProperties: false throughout the schema, shellcheck fixes, a curl fallback pattern fix, and grouped env exports.

The three medium-severity findings from the prior review remain unresolved and are carried forward unchanged. No new issues were introduced by the latest commit. The PR is functional for the primary GitHub flow; the remaining findings affect Jira integration completeness, display accuracy for edge-case verdicts, and defense-in-depth security hardening.


Medium

1. GHA workflow command injection via unsanitized interpolated values (unresolved from prior review)

create-children.sh, post-critique.sh, and pre-critique.sh interpolate unsanitized values into ::notice:: and ::warning:: GHA workflow commands. The repo has an established sanitize_gha() pattern in post-scribe.sh that strips ::, %0A, %0D, and newline characters. The highest-risk emissions are:

  • create-children.sh: $title and $summary (from agent JSON .children[].title), $body (raw Jira API error response — can contain arbitrary content), $CHILD_TITLE, $CREATED_KEYS
  • post-critique.sh: $CHILD_SUMMARY (contains API-returned issue keys), $ISSUE_KEY
  • pre-critique.sh: $ISSUE_KEY, $ISSUE_SOURCE

An attacker controlling the refine agent's output JSON (e.g., via prompt injection through an issue description) can craft child titles containing %0A::set-env name=... sequences to inject additional workflow commands.

Remediation: Import or duplicate sanitize_gha() from post-scribe.sh and apply to all interpolated variables in workflow commands.

2. Schema does not require assessment for non-approved verdicts (unresolved from prior review)

The JSON schema's allOf conditional validation only requires assessment when verdict is approved. The revise and needs_input conditional blocks do not include assessment in their required arrays. However, post-critique.sh unconditionally reads .assessment.overall // 0 and displays it in the comment table for all verdict paths. When the agent validly omits assessment for a revise or needs_input result (which the schema allows), the posted comment shows "Score: 0/100", which is misleading — it implies the plan scored zero rather than that the score was not computed.

Remediation: Either (a) add assessment to the required arrays for revise and needs_input in the schema, or (b) conditionally omit the Score row from the comment table when .assessment is null/absent.

3. Jira label handling missing for 3 of 4 verdict paths (unresolved from prior review)

The revise under limit verdict path adds labels to Jira issues via a curl PUT to /rest/api/3/issue/${ISSUE_KEY} with label update payload. The other three verdict paths — approved, revise at limit (escalation), and needs_input — only add labels on GitHub via add_label. Jira issues will not receive refine-approved, refine-needs-human, refine-escalated, or refine-needs-input labels, breaking label-based pipeline signaling for Jira-sourced work items.

Remediation: Add Jira label handling (matching the existing pattern in the revise under limit path) to the approved, escalation, and needs_input verdict paths.


Low

  • Tests re-implement logicpost-critique-test.sh defines its own copies of determine_reply_target, determine_verdict_action, and determine_labels rather than testing the actual post-critique.sh code paths. If the script's inline logic diverges from the test's copy, tests will pass while the real script has bugs.
  • Missing token maskingpost-critique.sh does not call ::add-mask:: for GH_TOKEN, PUSH_TOKEN, or JIRA_API_TOKEN. Every other post-script in the repo masks its tokens at the top of the file (post-review.sh, post-fix.sh, post-scribe.sh, post-retro.sh, post-code.sh).
  • Implicit contract in create-children.sh — The script assumes RESULT_FILE contains a .children array (from the refine result) but has no validation beyond JSON parsing. If the wrong file is passed, jq '.children | length' returns 0 and the script exits successfully with zero children created and no warning.
Previous run (13)

Review — #87

Verdict Request Changes
Reviewed 6d0c112
Findings 1 high, 3 medium
Re-review 5 of 9 prior findings addressed

Summary

The fix commit addresses the most critical findings from the prior review: the cross-platform parent key mismatch (via resolve_github_parent_number()), the unguarded source, the disallowedTools bypass, the FULLSEND_OUTPUT_FILE mismatch, sandbox GH_TOKEN leakage, and the refine-approved/refine-escalated label disambiguation. The escalation history mutation is also corrected — verdict is now preserved as revise with an escalated flag rather than being rewritten to approved.

However, three prior findings remain unresolved (Makefile test registration, GHA workflow command injection, schema/post-script assessment contract mismatch), and one new logic gap was found (Jira label handling is only implemented for one of four verdict paths).


High

1. Test suite not registered in Makefile (unresolved from prior review)

scripts/post-critique-test.sh (35 tests) is not added to the script-test target in the Makefile. CI runs make test via the script-test target. Every other agent's test suite is registered (triage, prioritize, code, review, fix, retro, scribe, validate-output-schema). Critique tests are never executed in CI.

Remediation: Add $(call run-timed,bash scripts/post-critique-test.sh) to the script-test target in the Makefile.


Medium

2. GHA workflow command injection via unsanitized interpolated values (unresolved from prior review)

create-children.sh, post-critique.sh, and pre-critique.sh interpolate unsanitized values into ::notice:: and ::warning:: GHA workflow commands. The repo has an established sanitize_gha() pattern in post-scribe.sh that strips ::, %0A, %0D, and newline characters.

3. Schema does not require assessment for non-approved verdicts (unresolved from prior review)

The JSON schema's allOf conditional validation only requires assessment when verdict is approved.

4. Jira label handling missing for 3 of 4 verdict paths

The revise under limit verdict path adds labels to Jira issues. The other three verdict paths only add labels on GitHub.


Low

  • Tests re-implement logic
  • Missing token masking
  • Implicit contract in create-children.sh
Previous run

Review — #87

Verdict Request Changes
Reviewed 23d7556
Findings 3 high, 6 medium

Summary

This PR adds a well-structured critique agent following the repo's established pre-script → sandbox → post-script pipeline. The agent prompt is thorough, the schema uses conditional validation correctly, and the test suite covers core verdict routing. However, there are several code-level issues.

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review

fullsend-ai-review Bot commented Jul 9, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 6:12 PM UTC · Completed 6:42 PM UTC
Commit: 6d0c112 · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review

fullsend-ai-review Bot commented Jul 9, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 7:57 PM UTC · Completed 8:07 PM UTC
Commit: 13d4552 · View workflow run →

@fullsend-ai-review
fullsend-ai-review Bot dismissed stale reviews from themself July 9, 2026 20:06

Superseded by updated review

@fullsend-ai-review fullsend-ai-review Bot added the requires-manual-review Review requires human judgment label Jul 9, 2026
Comment thread env/critique.env

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.

Move this to the harness, then env.sandbox.

@rh-hemartin rh-hemartin 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.

I want to move some vars to the harness file.

@ascerra

ascerra commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

Update for konflux-ci/refinement base: consumption (020dd01)

Refinement PR https://github.com/konflux-ci/refinement/pull/18 now pins this harness via ADR 0045 base: so we can test generic agents before this PR merges to main.

This push adds (generic only):

Still install-only (stays in refinement, not this PR):

  • Konflux skill URL pins (konflux-architecture, red-hat-konflux-teams)
  • program-decomposition skill
  • jira-routing / stage create allowlists
  • pack-org-knowledge.sh + curated Path B / Drive Path A
  • local pre/post that pack ORG_KNOWLEDGE

Reviewer note: Prior review threads that were already fixed in earlier commits remain fixed. New work is the ORG_KNOWLEDGE contract + companion resolution for base: testing from refinement. When this merges, refinement will flip base: from this branch SHA to main.

@ascerra ascerra mentioned this pull request Jul 24, 2026
8 tasks
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 24, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 7:48 PM UTC · Ended 8:03 PM UTC
Commit: 020dd01 · View workflow run →

@ascerra
ascerra force-pushed the feat/add-critique-agent branch from 020dd01 to 94e934c Compare July 24, 2026 20:03
@ascerra

ascerra commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

CI fix pass (94e934c)

Rebased onto current main and squashed to a single conventional commit so checks pass:

  • commit-lint: tip subjects no longer end with :; explore’s non-conventional root commit removed via squash
  • detect / functional-tests: branch now includes .github/scripts/select-eval-agents.sh from main (required because pull_request_target checks out PR head)
  • test / shellcheck (explore): fixed SC2015 / SC2129 / SC2034 / SC2295 in pre-explore.sh + comment-helpers.sh

Harness file #sha256= unchanged — only the commit OID moves for refinement base: pins.

@fullsend-ai-review

fullsend-ai-review Bot commented Jul 24, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 8:05 PM UTC · Ended 8:12 PM UTC
Commit: 94e934c · View workflow run →

@ascerra
ascerra marked this pull request as draft July 24, 2026 20:09
Introduce critique harness, agent prompt, scripts, and schema. Consume
optional ORG_KNOWLEDGE for install-injected org context and score
program_grounding when a real pack is present. Resolve companion script
helpers for base-composition installs.

Signed-off-by: Adam Scerra <ascerra@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@ascerra
ascerra force-pushed the feat/add-critique-agent branch from 94e934c to 71d0509 Compare July 24, 2026 20:11
@ascerra

ascerra commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto latest main (d7afc9c) so the branch is no longer out of date. Tip: 71d0509 (harness #sha256= unchanged).

@fullsend-ai-review

fullsend-ai-review Bot commented Jul 24, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 8:13 PM UTC · Completed 8:32 PM UTC
Commit: 71d0509 · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot removed the requires-manual-review Review requires human judgment label Jul 24, 2026
fullsend-ai-review[bot]

This comment was marked as outdated.

Remove /tmp/workspace host_files from the URL base (fullsend 0.34.0
rejects absolute paths there — install overlays mount them). Score
0.0–5.0 with one decimal. Rename key→issue_id for redaction safety.

Assisted-by: Cursor
Signed-off-by: Adam Scerra <ascerra@redhat.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 8, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 5:04 PM UTC · Completed 5:20 PM UTC

Commit: 96af908 · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

format_assessment_table_md hardcoded /100 after scores moved to 0–5.

Co-authored-by: Cursor <cursoragent@cursor.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 8, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 6:21 PM UTC · Completed 6:34 PM UTC

Commit: 361fca5 · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

Pass --wrap-detail to markdown-to-adf so Epic/Feature detail after the
first HR collapses like parent issues. Harden jq --argjson inputs and
silence createmeta parse noise when the live types API returns empty.

Co-authored-by: Cursor <cursoragent@cursor.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 8, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 7:04 PM UTC · Completed 7:20 PM UTC

Commit: ca99854 · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

Stop re-appending Acceptance Criteria when the child description already
has them, promote Requirements behind an explicit Detailed Specification
heading, and peel the generator footer out of the expand so Jira children
are scannable once Description is shown.

Co-authored-by: Cursor <cursoragent@cursor.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 8, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 7:38 PM UTC · Completed 7:56 PM UTC

Commit: 94c3fef · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

Walk children[].dependencies after create and open directed Jira Blocks
edges so triage can see sequencing. Cache link-type resolution per
preferred name so Relates never shadows Blocks, and teach critique not
to praise all-KONFLUX when routing lists team projects.

Signed-off-by: Adam Scerra <ascerra@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 8, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 9:52 PM UTC · Ended 10:09 PM UTC

Commit: bb708d5 · View workflow run →

Stage Jira create API needs inwardIssue=blocker and outwardIssue=blocked
to read back as blocker blocks blocked. The prior mapping inverted every
dependency edge.

Signed-off-by: Adam Scerra <ascerra@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 8, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 10:10 PM UTC · Completed 10:32 PM UTC

Commit: 4947f44 · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

Companion fetch must match explore tip so critique/create companions stay
aligned on public-only authenticated clones.

Signed-off-by: Adam Scerra <ascerra@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 8, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 11:08 PM UTC · Ended 11:13 PM UTC

Commit: db6e0b8 · View workflow run →

Reject explicit target_project values outside parent ∪
project-field-config ∪ issue-context routable_projects so LLM-invented
keys cannot create issues in arbitrary Jira projects.

Signed-off-by: Adam Scerra <ascerra@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 8, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 11:14 PM UTC · Completed 11:33 PM UTC

Commit: 861c7d5 · View workflow run →

@fullsend-ai-review fullsend-ai-review 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.

See the review comment for full details.

Comment thread scripts/pre-explore.sh
local response http_code body
response=$(GIT_TERMINAL_PROMPT=0 curl "${curl_args[@]}" \
"https://api.github.com/repos/${ref}" 2>/dev/null || printf '\n000')
http_code=$(printf '%s' "$response" | tail -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.

[high] logic-error

The validate_repo function uses jq -r '.private // true' to check whether a repo is public. However, jq's // (alternative) operator treats both null AND false as falsy. When a public GitHub repo returns {"private": false}, jq evaluates .private // true as true (the fallback), not false. The subsequent == "false" test therefore never succeeds, causing validate_repo to reject ALL repositories. Every referenced repo will be skipped.

Suggested fix: Replace .private // true with an explicit conditional, e.g. jq -r 'if .private == null then true else .private end' or use jq's exit code: jq -e '.private == false' >/dev/null 2>&1.

CHILD_SCOPE=$(jq -r ".children[${i}].estimated_scope // \"M\"" "${RESULT_FILE}")

FULL_BODY="$(compose_child_markdown "$CHILD_DESC" "$CHILD_AC" "$CHILD_PRIORITY_TEXT" "$CHILD_SCOPE")"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[medium] logic-error

In the orphan fallback loop, the target_platform == 'gitlab' case is not handled. The main topological loop (lines 709-718) correctly skips GitLab children with a 'not yet supported' message and continue, but the orphan loop (lines 800-808) only checks for github and jira platforms. A child with target_platform: gitlab falls through to the default creation path.

Suggested fix: Add elif [[ "$CHILD_TARGET_PLATFORM" == "gitlab" ]] with a continue and skip message, matching the main loop's behavior.

fi

if [[ -z "$resolved" ]]; then
echo "::warning::Could not discover Jira issue link type for '${preferred}'; using '${preferred}'" >&2

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] api-contract

The jira_link_blocks function's inwardIssue/outwardIssue mapping relies on a specific Jira Cloud instance's Blocks link type orientation. The code comment documents verification (2026-08-08). If deployed against an instance with a non-standard Blocks definition, the direction could be inverted.

# triage cannot see blocked/blocking edges.
DEP_LINKS_OK=0
DEP_LINKS_SKIP=0
if [[ "${ISSUE_SOURCE:-}" == "jira" && -n "${JIRA_HOST:-}" && -n "${JIRA_EMAIL:-}" ]]; 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.

[low] edge-case

The dependency materialization guard checks for JIRA_HOST and JIRA_EMAIL but not JIRA_API_TOKEN. If the token is empty, every API call fails with HTTP 401.

}
}
},
"program_grounding": {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] api-contract

The program_grounding dimension object is missing additionalProperties: false, unlike all other dimension objects in the assessment schema.

Comment thread scripts/post-critique.sh
fi

export RESULT_FILE="$REFINE_RESULT_FILE"
source "$(_resolve_companion create-children.sh)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] logic-error

When AUTO_CREATE=true, source create-children.sh runs in the same shell with set -euo pipefail. If create-children.sh fails, post-critique.sh aborts after posting the approval comment but before posting the child creation summary, leaving the issue in an inconsistent state.

body=$(echo "$response" | sed '$d')

if [[ "$http_code" -ge 400 ]]; then
echo "::warning::Failed Blocks link ${blocker_key} blocks ${blocked_key} (HTTP ${http_code}): ${body}" >&2

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] injection-vuln

GHA workflow commands (::warning::) interpolate unsanitized values from Jira API responses ($body). While the most dangerous GHA command injections (set-env, add-path) are disabled by default on modern runners, cosmetic injection remains possible.

@ascerra

ascerra commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

Closing without merge — keep the branch

Closing #87 (critique). Critique / create-children is not cancelled.

Same situation as #11 / #86: open draft PR + pin-by-SHA iteration kept re-triggering fullsend review. We considered extending /fs-stop so review would stay off; decided not to rush that platform fix. Closing the PR is the right move for this case — continue testing and updating feat/add-critique-agent without review on every push. Reopen when critique is ready for review.

Team decision 2026-08-10 (notes).

Upstream: explore #11 (feat/add-explore-agent), refine #86 (feat/add-refine-agent). Pin installs to branch SHAs.

@ascerra ascerra closed this Aug 11, 2026
@fullsend-ai-retro

fullsend-ai-retro Bot commented Aug 11, 2026

Copy link
Copy Markdown

🤖 Finished Retro · ✅ Success · Started 12:41 AM UTC · Completed 12:55 AM UTC

Commit: 861c7d5 · View workflow run →

@fullsend-ai-retro

Copy link
Copy Markdown

Retro: PR #87 — feat: add generic critique agent

Timeline

PR #87 added a generic critique agent to fullsend-ai/agents (6,787 additions, 24 files, 20 commits over 33 days). The review bot triggered 22 review runs (14 completed, 7+ cancelled), including 8 on a single day (Aug 8). The PR was closed without merge on Aug 11 as a deliberate team decision to stop review re-triggering, alongside PRs #11 and #86 — all three bulk-closed within 3 seconds. The author noted: "We considered extending /fs-stop so review would stay off; decided not to rush that platform fix."

Findings

1. Protected-path finding was a permanent, unresolvable blocker. All 24 files fell under protected paths (agents/, harness/, scripts/, skills/, etc.). Since the PR had no linked issue (Fixes #N), the finding was always High severity, forcing request-changes on every review run. The PR's detailed body was not recognized as authorization context — the only downgrade path requires a linked issue. This is the subject of the proposal below.

2. Identical findings repeated verbatim 9–14 times. Core findings (GitLab orphan loop, GHA injection vulnerability, missing additionalProperties:false, GitHub dedup) were reported word-for-word in every review run after first appearance. No mechanism existed to mark them as acknowledged or deferred. This directly supports agents#721 (content-based finding identifiers for cross-round dedup) and agents#685 (explicitly resolve or persist prior findings on re-review).

3. No manual mechanism to pause review on a PR. The team's decision to close 3 PRs simultaneously to escape review noise strongly supports fullsend#5650 (/fs-stop <agent> slash command). The draft-PR-still-triggering pattern supports fullsend#1715 (skip review for draft PRs). The 22 total dispatches over 33 days supports fullsend#3034 (per-PR circuit breaker) and fullsend#2587 (hard cap on review dispatches).

4. Review quality was high where it ran. The review agent correctly identified real bugs (jq // operator logic error in validate_repo, GHA workflow command injection vulnerabilities). The human reviewer (rh-hemartin) caught one architecture concern — env vars should live in the harness config, not a separate env file — which is a repo-convention issue that a generic review agent would not flag without explicit guidance.

5. Significant token waste from redundant runs. 14 full review runs on a 6,787-line PR, each dispatching sub-agents across 6 dimensions, with diminishing returns after the first 2–3 runs. This supports agents#343 (scope re-review to finding verification when push only addresses prior findings).

Proposals filed

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

Labels

enhancement New feature or request security

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants