linear-brutal-project-review/SKILL.md
Systematically reviews a project subsystem-by-subsystem with resumable .brutal-workspace state and creates Linear review finding issues for CRITICAL and MAJOR problems.
npx skillsauth add sssemil/skills linear-brutal-project-reviewInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Hybrid local-state / Linear-backed brutal project review. Use this when the
user asks for $linear-brutal-project-review, asks to review a project into
Linear, or asks for brutal-project-review behavior where findings become
Linear issues instead of local workspace task files.
This skill preserves the subsystem-by-subsystem review discipline, manifest
state tracking, subsystem reports, resume behavior, and review rigor of
brutal-project-review. The only intentional workflow difference is that
CRITICAL and MAJOR findings become Linear issues rather than
workspace/tasks/todo tickets.
AGENTS.md.AGENTS.md must name the Linear project to use. Accept clear wording such as
Linear project: <name> or "Use the Linear project <name>"..brutal-workspace files.workspace/review-state, workspace/tasks, or
workspace/plans files..brutal-workspace/review-state/ as the only local review-state
directory..brutal-workspace is local resumable state. The skill may create and update
it, but must not commit it unless the user explicitly asks..brutal-workspace, ensure .brutal-workspace/ is ignored by
the local repo, preferably through .git/info/exclude. Do not modify tracked
ignore files unless the user explicitly asks.type:plan, type:task, type:review-finding.$linear-task-worker for fixes. Do not recommend the local
task-worker workflow.Before any state initialization, review scoping, or artifact creation:
AGENTS.md.Todo for new finding issues when it
exists. If Todo does not exist, ask the user which unstarted intake status
to use before creating findings.docs/linear-workflow.md.TARGET.md if present.If multiple Linear projects match, ask the user to choose. If no project
matches, ask the user to correct AGENTS.md or create/provide the project.
After the Linear project has been resolved, check for an existing manifest:
ls -la .brutal-workspace/review-state/manifest.json 2>/dev/null
If manifest.json exists:
linear_project_id or linear_project_name does not match the resolved
project, stop and ask whether to archive the old state and start a fresh run..brutal-workspace/ is
ignored through .git/info/exclude or an existing ignore rule.linear_team_id, finding_intake_status_id, or their names are missing
from an older manifest, resolve them and update the manifest before review.parent_issue_id or parent_issue_identifier exists, resolve that Linear
issue. If it no longer exists, create or locate a replacement parent issue and
update the manifest.pending or in_progress, keep the manifest and proceed
to Step 3.done, keep the manifest and proceed to Step 3 so the
user can choose whether to re-review one subsystem or all subsystems.If manifest.json does not exist, initialize a fresh review in Step 2.
Create or reuse a parent Linear issue labeled type:plan with title:
Project Review: <repo or project name>
Reuse an existing parent only when it is in the resolved project, has
Source: linear-brutal-project-review in the body or comments, and clearly
matches the same repo/review run. Otherwise create a new parent.
Parent issue body:
Source: linear-brutal-project-review
State: `.brutal-workspace/review-state/manifest.json`
## Summary
Subsystem-by-subsystem brutal project review. CRITICAL and MAJOR findings are
created as child or related Linear issues labeled `type:review-finding`.
## Status
- Pending: <count>
- In Progress: <count>
- Complete: <count>
## Review Scope
<subsystem list or pending discovery note>
## Finding Issues
<created Linear identifiers, or None yet>
Create a Linear project document for the full review manifest only when Linear documents are available and useful. The local manifest remains authoritative for resume behavior.
mkdir -p .brutal-workspace/review-state/subsystems
mkdir -p .brutal-workspace/review-state/archive
Before writing source context, ensure .brutal-workspace/ is listed in
.git/info/exclude so temporary context and local state do not pollute normal
git status. This is local-only repo metadata, not a tracked project change.
Do not hardcode subsystem names or paths. Discover them from the repository on each fresh run.
.rs, .ts, .tsx, .js, .jsx, .css, .json, .sql,
.toml, and Markdown docs that define architecture or service behavior.git, node_modules, target,
dist, build, .next, coverage, vendor*/src/<segment>/..., use */src/<segment>/*/src/, use */src/*/app/..., use */app/apps/<name>/, libs/<name>/, packages/<name>/, services/<name>/,
or crates/<name>/id: zero-padded sequential IDs (01, 02, ...)name: slug from path, lowercase, with / and _ converted to -path: normalized discovered pathstatus: pendingreport_path: nullIf no subsystems are discovered, report that no source files were found and stop.
Write .brutal-workspace/review-state/manifest.json:
{
"version": 1,
"started_at": "<ISO timestamp>",
"last_updated_at": "<ISO timestamp>",
"linear_project_id": "<Linear project UUID>",
"linear_project_name": "<Linear project name>",
"linear_team_id": "<Linear team UUID>",
"linear_team_name": "<Linear team name>",
"finding_intake_status_id": "<Linear status UUID>",
"finding_intake_status_name": "<Todo or selected intake status name>",
"parent_issue_id": "<Linear parent issue UUID>",
"parent_issue_identifier": "<KEY-123>",
"selected_mode": null,
"subsystems": [
{
"id": "01",
"name": "<auto-generated-name>",
"path": "<auto-discovered-path>",
"status": "pending",
"report_path": null
}
],
"linear_issues_created": []
}
Get timestamps with:
date -u +"%Y-%m-%dT%H:%M:%SZ"
Update the parent Linear issue with the discovered subsystem count and scope.
Read the manifest and show all available subsystems before doing review work.
Print a concise table:
| ID | Name | Path | Status | Started | Completed | Report |
| --- | --- | --- | --- | --- | --- | --- |
| <id> | <name> | <path> | <pending|in_progress|done> | <in_progress_at or -> | <completed_at or never> | <report_path or -> |
Also report:
.brutal-workspace/review-state/manifest.json<identifier>started_atlinear_issues_created.lengthAsk the user which subsystem to review now. Do not proceed until the user answers.
Accepted responses:
id, name, or path: review only that subsystem.all: review every subsystem in manifest order, including previously
completed subsystems.pending: review every subsystem whose status is pending or in_progress,
in manifest order.restart: archive the current local manifest and reports, then return to
Step 2 for fresh discovery.cancel: stop without changing review state.For restart, move the existing manifest and subsystem reports under
.brutal-workspace/review-state/archive/<timestamp>/. Do not delete the old
linear_issues_created mappings permanently; preserve them in the archive so
duplicate Linear findings can be investigated later.
If the user chooses a subsystem that is already done, re-review it by setting
it back to in_progress.
For each subsystem selected for review:
"in_progress" before gathering context."in_progress_at": "<ISO timestamp>"."completed_at" until Step 9 replaces it after the
new review finishes.selected_mode to the user's chosen mode and update
last_updated_at.For all or pending, run Steps 4 through 12 for each selected subsystem in
deterministic manifest order before reporting final completion.
For the selected subsystem:
.rs, .ts, .tsx, .js, .jsx, .css, .jsonAGENTS.mdTARGET.md.brutal-workspace/review-state/context-<subsystem-id>.md
Context files are temporary, may contain source snippets or secrets, must not be referenced from Linear issues, and must be deleted after each subsystem review.
Launch five parallel review subagents when available. Each subagent must read
.brutal-workspace/review-state/context-<subsystem-id>.md as its first action;
subagents do not inherit context automatically.
Perspectives:
Each finding must include:
Severity definitions:
CRITICAL: must fix before merge; correctness, data loss, security, or
forbidden production panic/unwrap patternsMAJOR: should fix; significant design, reliability, performance, or test
gapMINOR: worthwhile but not blockingNIT: optional cleanupUse the same rigorous review perspectives and tone as brutal-project-review:
question correctness, design, test coverage, error paths, security, performance,
maintainability, and unnecessary code.
After collecting findings:
Number findings sequentially by subsystem id:
<subsystem-id>-001
<subsystem-id>-002
Example: 03-001.
Write findings to:
.brutal-workspace/review-state/subsystems/<subsystem-name>.md
Report format:
# Review: <Subsystem Name>
**Path**: <subsystem path>
**Reviewed**: <ISO timestamp>
**Status**: Complete
**Linear Parent**: <parent issue identifier>
## Summary
- CRITICAL: <count>
- MAJOR: <count>
- MINOR: <count>
- NIT: <count>
## Findings
### [CRITICAL] <finding-id>: <brief description>
**File**: `<path>:<line>`
**Confidence**: <0-100>
**Linear Issue**: <identifier or pending>
**Issue**:
<detailed explanation>
**Code**:
```<lang>
<problematic code snippet>
```
**Fix**:
<actionable fix>
**Acceptance Criteria**:
- [ ] <criterion>
---
Update the subsystem's report_path in the manifest. After Linear finding
issues are created or updated in Step 8, rewrite this report so each
**Linear Issue** field contains the final Linear identifier instead of
pending.
For each CRITICAL or MAJOR finding, create or update a Linear issue.
Use a deterministic fingerprint as the stable key:
<subsystem-id>|<canonical-file>|<line-or-symbol>|<severity>|<normalized-title>
Normalize the title by lowercasing it, trimming whitespace, removing known
volatile tokens such as dates, timestamps, build IDs, and generated hashes, and
collapsing repeated spaces. Preserve meaningful numbers such as HTTP status
codes, size limits, timeouts, and version numbers. Store finding_id
separately; do not use the sequential finding ID as the duplicate-prevention
key because finding numbers can change between review runs.
Before creating an issue, search linear_issues_created for the same
fingerprint.
Create finding issues in the resolved project using:
type:review-findingfinding_intake_status_idparentId pointing to the review parent issuerelatedTo if parentId is unsupportedAlways mirror the parent issue identifier in the issue body even when Linear relationships are set.
Issue title:
Fix <subsystem>: <brief finding>
Issue body:
Source: linear-brutal-project-review
Review Parent: <parent issue identifier/title>
Subsystem: <subsystem path/name>
Severity: <CRITICAL|MAJOR>
Finding ID: <subsystem-id>-001
Confidence: <0-100>
File: `<path>:<line>`
Fingerprint: `<subsystem-id>|<canonical-file>|<line-or-symbol>|<severity>|<normalized-title>`
## Issue
<validated explanation>
## Suggested Fix
<specific fix>
## Acceptance Criteria
- [ ] Investigate and confirm the issue
- [ ] Implement the fix
- [ ] Add or update tests if applicable
- [ ] Run repo verification
## Implementation Notes
<repo rules, relevant constraints, edge cases, and review notes>
## Verification
<specific verification commands from AGENTS.md, repo scripts, or best available narrow checks>
## Dependencies
- Blocked by: None, unless a real blocker was identified
- Blocks: None, unless this finding blocks another issue
- Related: <parent issue identifier and any related finding IDs>
Use Linear relationships for blockedBy, blocks, or relatedTo when the MCP
tool supports them. Mirror those relationships in the body.
For each created or updated Linear issue, append or update an entry in
linear_issues_created:
{
"fingerprint": "<subsystem-id>|<canonical-file>|<line-or-symbol>|<severity>|<normalized-title>",
"linear_id": "<Linear UUID>",
"linear_identifier": "<KEY-123>",
"finding_id": "<subsystem-id>-001",
"subsystem_id": "<subsystem id>",
"subsystem_name": "<subsystem name>",
"severity": "<CRITICAL|MAJOR>",
"file": "<path>:<line>",
"title": "<normalized finding title>",
"status": "<created|updated|reopened>",
"created_at": "<ISO timestamp>",
"updated_at": "<ISO timestamp>"
}
Update last_updated_at after writing Linear issue mappings.
Rewrite the local subsystem report after issue creation so each CRITICAL/MAJOR finding includes its final Linear identifier. Do not create local task directories. Do not commit the manifest or report.
Update the manifest:
"done"."completed_at": "<ISO timestamp>"."in_progress_at"."last_updated_at": "<ISO timestamp>".After each subsystem review, add a concise comment to the parent Linear issue:
Review complete: <Subsystem>
- Report: `.brutal-workspace/review-state/subsystems/<subsystem-name>.md`
- Findings: <critical> CRITICAL, <major> MAJOR, <minor> MINOR, <nit> NIT
- Linear issues: <created or updated identifiers, or None>
- Remaining: <pending> pending, <in_progress> in_progress, <done> done
Update the parent issue body when useful to keep the status summary and finding
issue list current. The local manifest remains authoritative for resume state.
Compute counts after Step 9 so the just-reviewed subsystem is reported as
done, not in_progress.
Delete the temporary context file before user-facing progress or final reporting:
rm .brutal-workspace/review-state/context-<subsystem-id>.md
Do this even when the review found no CRITICAL or MAJOR issues. Also attempt this cleanup before stopping on errors, Linear failures, user cancellation after context creation, or interruption resumes.
Calculate and report:
Example:
## Subsystem Review Complete: <subsystem-name> (<reviewed>/<total>)
**Findings**: <critical> CRITICAL, <major> MAJOR, <minor> MINOR, <nit> NIT
**Linear Issues**: <count> (<KEY-123>, <KEY-124>)
**Manifest**: `.brutal-workspace/review-state/manifest.json`
**Remaining**: <pending> pending, <in_progress> in_progress, <done> done
Run `$linear-brutal-project-review` again to choose another subsystem,
`pending`, or `all`, or run `$linear-task-worker` to fix created findings.
Report:
$linear-task-worker for fixesBe direct and findings-first. Avoid praise and vague summaries.
CRITICAL - Must fix before merge. Bugs, data corruption risks, security
issues, forbidden production unwrap, or panic in library/production paths.
MAJOR - Should fix. Significant design issues, missing error handling,
performance problems, reliability risks, or inadequate testing.
MINOR - Recommended fixes. Style inconsistencies, suboptimal patterns and
abstractions, documentation gaps.
NIT - Optional improvements. Minor style preferences or micro-optimizations.
tools
Autonomous Linear task worker that selects Linear issues, implements them with TDD, self-reviews, commits, pushes, and moves finished work to In Review.
development
Collaborative, multi-perspective feature planning with rigorous requirements interrogation. Creates Linear project documents and Linear issues instead of local workspace plan/task files.
documentation
Compact the current conversation into a handoff document for another agent to pick up.
development
Delegate coding work to OpenCode through safe-opencode. Use when Codex should plan, route the job to a suitable DeepSeek model, review git diff, and validate instead of writing the main code itself.