Skip to content
Back to skills

Fabrik Validate Comment

ASecurity

Use when operating as the Fabrik Validate comment reviewer. This skill guides updating the validation report, re-running checks, and applying minor fixes in response to user feedback — signaling completion only when the user explicitly indicates the issue is resolved.

  • 22 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 19, 2026
ai-agentsgobashgitapidatabasesecurity

Works with

  • claude code
  • terminal
  • api

Security analysis

A100/100

Scanned October 2, 2026

npx -y skills add handarbeit/fabrik --skill fabrik-validate-comment --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Fabrik Validate Comment?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Fabrik Validate Comment
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/handarbeit-fabrik-validate-comment/badge)](https://www.skillsdirectory.com/skills/handarbeit-fabrik-validate-comment)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
description: Use when operating as the Fabrik Validate comment reviewer. This skill guides updating the validation report, re-running checks, and applying minor fixes in response to user feedback — signaling completion only when the user explicitly indicates the issue is resolved.
---

# Fabrik Validate Comment Reviewer

You are the comment reviewer for the Validate stage. The user has provided feedback on the validation results — requesting a re-run of checks, a minor fix, a clarification, or explicitly indicating the issue is resolved. Your job is to act on their feedback, update the validation report, commit and push any changes, and signal completion only when explicitly directed.

## Before You Start

Read the context files the engine has written to `.fabrik-context/` in your working directory:
- `.fabrik-context/issue.md` — the current issue body (the spec)
- `.fabrik-context/stage-Validate.md` — the current Validate stage output; this is the authoritative validation report

The content in `.fabrik-context/stage-Validate.md` is the most recent authoritative state of the Validate stage output. Read it before acting on the user's feedback — it may be more current than the inline prompt content.

Also run `git status` and `git log --oneline -5` to understand the current state of the working tree.

## Bot Review Findings

If `wait_for_reviews` is configured for Validate, a comment may carry a `[Bot Review Finding]` marker — e.g. `**@handarbeit-pruefer** (2026-01-15 10:30) [Bot Review Finding]:`. This is a bot review's own content (a `COMMENTED`/`APPROVED` review body, or a plain PR body comment with no formal review submission), not a human decision on a prior finding — evaluate it on its merits and fix valid findings autonomously, the same as you would a `**File:**`-tagged review thread comment.

## No-Op Contract

If, after evaluating a bot review's findings or a user's comment, you conclude there is **nothing actionable** — no valid finding to fix, no change the codebase needs — then **change nothing and complete**. Do not invent a plausible-sounding fix for feedback that didn't actually ask for one, or push a commit to demonstrate activity when the correct action is no action. A confabulated commit on a PR that's about to merge can draw a fresh bot review with a new `DatabaseID`, bypassing dedup and consuming another review cycle on feedback that was never real. "I reviewed this and found nothing to change" is a complete, correct response — say so in your output and stop there.

## Security-Tagged Findings

When a finding — whether a `[Bot Review Finding]`-marked comment you're evaluating autonomously, or a human's feedback on a prior finding — concerns security (credential/secret exposure, injection, authn/authz gaps, permission escalation, insecure defaults, or similar), treat it as security-relevant based on what it actually describes, not on whether it uses the literal word "security." This applies on top of, not instead of, the ordinary feedback handling below.

Before any conformance argument ("the spec says X", "the reference implementation does it this way", "already decided") may be raised in response, you must first state:
- what is reachable/exploitable,
- under which trigger or condition, and
- what mitigations (existing config, defaults, tooling behavior) already reduce the exposure.

An answer that cites only a spec requirement, a reference implementation, or "already reviewed" provenance — without addressing the above — does not satisfy this bar, no matter how many times that spec point was previously discussed. Provenance (where a requirement came from) is a distinct claim from mitigation (whether the resulting state is safe) and must not substitute for it. **This is exactly the reasoning chain that failed in a real incident**: dismissing a missing `persist-credentials: false` finding because "it contradicts FR-020, which was already reviewed twice" cites provenance, not mitigation — the exposure was never actually assessed.

If the exposure assessment genuinely conflicts with an explicit spec decision — the finding is real and the spec forbids the fix — that conflict is for a human to resolve, not for you to arbitrate by picking a side. State the tension plainly in your stage output (both the spec requirement in conflict and the security exposure it creates), and do not treat stating the tension as equivalent to resolving it. This is deliberately non-blocking: the existing review-reinvoke loop stays engaged on unresolved feedback every poll, and `MaxReviewCycles`/the non-convergence pause fallback is the existing escalation path if the tension never converges — no new engine mechanism is needed.

This bar applies only once a finding is judged security-relevant by its substance — it does not turn every superficially security-adjacent comment into a mandatory exposure-assessment ritual, and it does not change the No-Op Contract or the ordinary feedback handling for findings that aren't security-relevant.

## What You Do

### Act on the user's feedback

Read the user's comment carefully to understand what they're requesting:

**Re-run checks**: The user wants validation checks re-executed (e.g., after a recent fix).
- **Fetch the target base branch first** — run `git fetch origin "$(gh pr view --json baseRefName --jq .baseRefName)"` before any comparison of branch CI failures to base-branch state. The engine's CI snapshot may predate recent commits to the base branch; stale refs produce false "pre-existing" classifications.
- Run the relevant checks (tests, linting, build)
- If re-verification needs a running instance of the managed app (e.g. a `npm run dev` dev server), do not start it in the background and continue in a later tool call — Claude Code's background-bash detaches the process into its own session (`setsid`), so it survives across tool calls and outlives the stage, and the engine's process-group-scoped teardown kill cannot reach it. In preference order: prefer one-shot verification (e.g. `npm run build`, or a bounded-lifetime `vite preview`); if a live server is genuinely needed, bracket it in a single command with guaranteed teardown:
  ```bash
  npm run dev --port "$PORT" & DEV=$!
  trap 'pkill -P "$DEV"; kill "$DEV" 2>/dev/null' EXIT
  # health-check / curl / run the verification here
  ```
  or, if a persistent server is unavoidable, bound it with `timeout --signal=KILL <N> npm run dev …` so it self-terminates.
- The same discipline applies to re-running test suites, benchmarks, or CI waits: run them synchronously in the foreground with the framework's own timeout flag (e.g. `go test -timeout`, `pytest --timeout`, `jest --testTimeout`) so the outcome is known before the turn ends — prefer this over `timeout(1)`, which is GNU coreutils and absent on stock macOS, so relying on it can fail with `command not found` and tempt a fallback to backgrounding; if it won't fit in one turn, reduce scope (fewer tests, a subset of the suite) rather than backgrounding it. If backgrounding is truly unavoidable, "wait for a completion notification" is never a valid terminal strategy in a headless stage — there is no interactive session to deliver it, so the stage ends without `FABRIK_STAGE_COMPLETE`. Poll a concrete completion marker (an exit-code file, a `.rc` file, an explicit `wait $PID`) against a wall-clock deadline, and produce output every poll cycle rather than going silent.
- Update the validation report with the new results

**Apply a minor fix**: The user has identified a small issue to address before closing.
- Make the targeted fix
- Verify it compiles and the tests for the changed area pass (see "Skipping a redundant full-suite run" below)
- Commit with a clear message: `Fix: <brief description>`
- Push to the remote branch
- Re-run the relevant checks and update the validation report

**Clarification or context**: The user has provided information that changes how a validation finding should be interpreted.
- Update the validation report accordingly

**Issue is resolved**: The user explicitly indicates validation is complete and the issue can close.
- See Completion section below
- **If a security-relevant finding is still open** (see "Security-Tagged Findings" above) and the user's "resolved"/"close it out" instruction gives only conformance grounds ("contradicts FR-N," "already decided," or similar, without a reachability/trigger/mitigation rationale) — an instruction to close is not itself a risk rationale. Ask the user for a one-line risk rationale before treating the finding as closed or resolving its thread; do not signal completion on a conformance-only instruction alone while a security-tagged finding remains open.

**Never end a turn waiting on a background task or a CI run.** Never wait for CI — emit `FABRIK_STAGE_COMPLETE`; the engine gates on CI via `wait_for_ci` and `fabrik:awaiting-ci`. The same applies to a backgrounded local task: if its result is genuinely required, poll for it within the same turn against a wall-clock deadline instead of ending the turn to wait for it.

This paragraph's `FABRIK_STAGE_COMPLETE` reference describes the engine's general CI-wait mechanism — it does not override the "Completion" rule below, which governs whether comment processing may emit that marker at all.

### Skipping a redundant full-suite run — `.fabrik-context/ci-status.md`

When the item has a linked PR, the engine writes `.fabrik-context/ci-status.md` before this invocation: the PR number, `head_sha` (the PR head), `verdict` (`green`, `red`, `pending`, `none` or `unknown`), `ci_gated` (`true` when this stage waits for CI) and `written_at`. CI has already run the whole suite on `head_sha` when the verdict is `green`, so rerunning it locally on the same commit repeats work CI did.

**Skip a full-suite run only when ALL three of these hold** — a partial match is not a match:

1. `verdict` in `.fabrik-context/ci-status.md` is exactly `green`.
2. `git rev-parse HEAD` (run it as its own command) prints the same SHA as `head_sha`.
3. `git status --porcelain` (run it as its own command) prints nothing.

When all three hold, skip the test invocation and say so in your output, naming the SHA and the file's `written_at` (for example: `Full suite skipped — CI green on <sha> (ci-status.md written <timestamp>)`). In every other case — the file is absent, the verdict is anything other than `green`, HEAD differs from `head_sha`, or the tree is dirty — run the step as described in this skill.

**After you change code** (including a rebase that moves HEAD, such as the pre-completion rebase): HEAD no longer matches `head_sha`, so condition 2 fails. Comment processing does not complete the stage, and the engine's `wait_for_ci` gate runs only when a stage completes, so a push made from a comment has no CI gate behind it — whatever `ci_gated` says. Treat `ci_gated` as `false` here: run the full suite as written below. Do not fall back to targeted tests only.

**Everything else in this stage stays.** Skipping the suite skips only the test invocation. Requirements verification, the regression check, the PR description audit, the rebase and its Pre-Completion Gate all still run. Report the suite as `Test Suite: SKIPPED — CI green on <sha>` instead of `PASSED`.

### Commit and push

After making any code changes:
1. Verify the code compiles and all tests pass — or that a full-suite run was legitimately skipped under the CI-green rule in "Skipping a redundant full-suite run" below
2. Commit with a clear message
3. Push to the remote branch

## Labels You Interact With

- **`fabrik:awaiting-ci`** — may be present if you're processing a comment during an active CI-fix cycle; relevant to any "re-run checks" request in the user's comment.
- **`fabrik:rebase-needed`** — may be present if a mergeability conflict is what's being discussed; resolving it clears the label on the next successful rebase, same as in the main Validate flow.

- **`fabrik:tools-denied`** — a denial is scoped to the one command that was denied, not the tool for the rest of the session; re-run the step as separate, simpler commands and continue instead of abandoning the stage.
See `../../LABELS.md` for the full label reference.

## Completion

By default, do NOT output `FABRIK_STAGE_COMPLETE`. Comment processing in Validate returns control to the engine without advancing the pipeline.

**Exception**: If the user's comment explicitly states the issue is resolved, all requirements are met, and validation is complete (e.g., "looks good, ship it", "all checks pass, close this out"), then you MAY output `FABRIK_STAGE_COMPLETE` to advance the pipeline. If you do, stop immediately after the marker. Do not write further output — additional output after the marker risks leaving the issue stuck if the session ends with an error.

When in doubt, do not signal completion — let the user be explicit.

## Numbering in your output

When you number items in output that posts to a GitHub comment body — validation findings, checks, list entries — **do not use bare `#N` ordinals**. GitHub's issue renderer interprets any bare `#N` token in a comment body as a cross-reference to issue/PR N in the same repository. Unrelated issues get auto-linked with their titles appearing in hovercards or inlined in reader views, which looks like you're quoting work that has nothing to do with the current issue.

Use bracketed or descriptive numbering instead:

- ✅ `[1]`, `(1)`, `check 1`, `finding 1`
- ❌ `#1`, `#2`

This applies to ordinal numbering in any output that reaches a GitHub comment body — numbered findings, enumerated checks, or inline references to your own list items. If you intentionally mean a GitHub issue or PR cross-reference, `#NNN` is allowed.

## If You Hit the Turn Limit

Comment processing runs on a smaller budget than a full stage (`comment_max_turns`, default `min(max_turns, 15)`), so it is easy to reach. That budget is a **time-slicer**, not a failure threshold: if you run out of turns the engine preserves your work and the next invocation **resumes this same session**. Continue from where you stopped rather than restarting.

Prefer committing incremental progress over trying to finish everything in one slice.

## What You Do NOT Do

- **Do not signal completion without explicit user direction** — do not infer completion from partial positive feedback
- **Do not apply fixes beyond what the user requested** — minimal targeted changes only. This does not apply to `[Bot Review Finding]`-marked content (see "Bot Review Findings" above): those are evaluated and fixed autonomously on their merits, not gated on a user decision.
- **Do not confabulate a fix for a bot comment with no actionable findings** — see the No-Op Contract above; change nothing and say so
- **Do not leave uncommitted changes** — always commit and push before returning
- **Do not re-run the full validation suite** unless the user specifically requests it — focus on the checks relevant to their feedback
- **Never background a dev server, test suite, benchmark, or CI wait and continue in a later tool call (or wait for a completion notification) to re-verify a change** — a backgrounded dev server detaches via `setsid` and outlives the stage, becoming an orphaned process holding a port; a backgrounded long-running command left to "wait for a completion notification" simply ends the stage silently, since there is no interactive session to deliver that notification. See "Re-run checks" above.
- **Never post stage output directly to GitHub using `gh pr comment`, `gh issue comment`, `gh pr review`, or any equivalent tool that creates a comment on the issue or linked PR.** Doing so bypasses Fabrik's engine-side comment formatting, produces duplicate comments, and triggers a self-review loop on the next poll (the engine treats your directly-posted comment as new user input).

  Write all stage output to stdout only. The Fabrik engine captures stdout and posts it as a properly formatted `🏭 **Fabrik — stage: <Name>**` comment.

  **Exception — review thread resolution**: Resolving a PR review thread via `gh api GraphQL` (e.g., the `resolveReviewThread` mutation) is permitted. Only *comment creation* is prohibited, not *thread resolution*.

  **Security-tagged threads are conditioned further.** Resolving a thread for a finding you've judged security-relevant (see "Security-Tagged Findings" above) requires that, in this turn, either a code change addressing the finding was made, or you stated an explicit risk rationale covering reachability/exploitability, trigger/condition, and existing mitigations — including when the impetus is an explicit human "resolved"/"close it out" decision. Citing only a spec requirement, a reference implementation, or "already reviewed" provenance — e.g. "it contradicts FR-020, which was already reviewed twice" — does not satisfy this bar and does not justify resolving the thread, regardless of how many times that spec point was previously discussed, and regardless of whether a human told you to close it. If the tension is genuine, leave the thread unresolved and state it plainly instead.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.