Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 29 additions & 5 deletions .claude/hooks/stop-lint-gate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,38 @@

cd "$CLAUDE_PROJECT_DIR" || exit 0

# Ensure node/yarn are on PATH via mise
eval "$(mise activate bash --shims)" 2> /dev/null
node_dir="$(mise where node 2> /dev/null)/bin"
[ -d "$node_dir" ] && export PATH="$node_dir:$PATH"
# Ensure node/yarn are on PATH via mise (if available)
if command -v mise > /dev/null 2>&1; then
eval "$(mise activate bash --shims)" 2> /dev/null
node_root="$(mise where node 2> /dev/null)"
[ -n "$node_root" ] && [ -d "$node_root/bin" ] && export PATH="$node_root/bin:$PATH"

Check failure on line 11 in .claude/hooks/stop-lint-gate.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ivuorinen_dotfiles&issues=AZ2SvlhANbA7A6bOafXp&open=AZ2SvlhANbA7A6bOafXp&pullRequest=344

Check failure on line 11 in .claude/hooks/stop-lint-gate.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ivuorinen_dotfiles&issues=AZ2SvlhANbA7A6bOafXq&open=AZ2SvlhANbA7A6bOafXq&pullRequest=344
fi

# Fall back to corepack shim locations if yarn is still the legacy v1
export PATH="$HOME/.local/bin:/usr/local/bin:$PATH"
if command -v corepack > /dev/null 2>&1; then
corepack enable --install-directory "$HOME/.local/bin" 2> /dev/null || true
fi
Comment on lines +14 to +18
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid unconditional fallback PATH prepend that can override mise binaries.

Line 15 always prepends $HOME/.local/bin:/usr/local/bin, which can shadow the PATH you just set from mise and reselect legacy yarn. Make this fallback conditional on missing/legacy yarn.

Proposed fix
-# Fall back to corepack shim locations if yarn is still the legacy v1
-export PATH="$HOME/.local/bin:/usr/local/bin:$PATH"
-if command -v corepack > /dev/null 2>&1; then
-  corepack enable --install-directory "$HOME/.local/bin" 2> /dev/null || true
-fi
+# Fall back to corepack shim location only when yarn is missing/legacy
+if ! command -v yarn > /dev/null 2>&1 || yarn --version | grep -q '^1\.'; then
+  export PATH="$HOME/.local/bin:$PATH"
+  if command -v corepack > /dev/null 2>&1; then
+    corepack enable --install-directory "$HOME/.local/bin" 2> /dev/null || true
+  fi
+fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Fall back to corepack shim locations if yarn is still the legacy v1
export PATH="$HOME/.local/bin:/usr/local/bin:$PATH"
if command -v corepack > /dev/null 2>&1; then
corepack enable --install-directory "$HOME/.local/bin" 2> /dev/null || true
fi
# Fall back to corepack shim location only when yarn is missing/legacy
if ! command -v yarn > /dev/null 2>&1 || yarn --version | grep -q '^1\.'; then
export PATH="$HOME/.local/bin:$PATH"
if command -v corepack > /dev/null 2>&1; then
corepack enable --install-directory "$HOME/.local/bin" 2> /dev/null || true
fi
fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/hooks/stop-lint-gate.sh around lines 14 - 18, The script
unconditionally prepends "$HOME/.local/bin:/usr/local/bin" to PATH which can
shadow the previously set mise binaries and reselect legacy yarn; change this to
only prepend when yarn is missing or is legacy v1: use command -v yarn and
inspect `yarn --version` (or `yarn -v`) to detect absence or a v1 version
string, and only then modify PATH (the PATH assignment) and run `corepack enable
--install-directory "$HOME/.local/bin"` as currently done; keep the existing
`command -v corepack` guard and `|| true` but make the PATH fallback conditional
around those checks so mise binaries stay first when a modern yarn is already
present.


output=$(yarn lint 2>&1)
# Ensure node_modules are installed (fast no-op if already up to date)
yarn install 2> /dev/null

output=$(yarn lint:biome 2>&1 && yarn lint:prettier 2>&1 && yarn lint:md-table 2>&1)
status=$?

# Run ec separately; skip if it fails due to binary download issues (network/rate-limit)
ec_output=$(yarn lint:ec 2>&1)
ec_status=$?
if [ $ec_status -ne 0 ]; then

Check failure on line 29 in .claude/hooks/stop-lint-gate.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ivuorinen_dotfiles&issues=AZ2DZ0uUs0Fbzs2j0WMf&open=AZ2DZ0uUs0Fbzs2j0WMf&pullRequest=344
if echo "$ec_output" | grep -q "rate limit\|Failed to download\|HttpError"; then
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

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

The grep pattern uses \| alternation without -E. On BSD/macOS grep, \| is treated as a literal |, so rate-limit download failures won't be detected and will incorrectly fail the gate. Switch to grep -E with | alternation (or run multiple grep -q checks) so the skip logic works cross-platform.

Suggested change
if echo "$ec_output" | grep -q "rate limit\|Failed to download\|HttpError"; then
if echo "$ec_output" | grep -Eq "rate limit|Failed to download|HttpError"; then

Copilot uses AI. Check for mistakes.
echo "Warning: editorconfig-checker skipped (binary download failed — GitHub rate limit)" >&2
else
output="$output
$ec_output"
status=$ec_status
fi
fi

if [ $status -ne 0 ]; then
echo "Lint failed — fix before finishing:" >&2
echo "$output" >&2
Expand Down
184 changes: 184 additions & 0 deletions .claude/skills/adversarial-reviewer/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
---
name: adversarial-reviewer
description: Deterministic adversarial code review focused on provable failures. Optimized for agent
execution, minimal tokens, and high signal findings across web applications.
---

# Adversarial Code Reviewer

## Core Directive

Find **provable failures**. Not opinions. Not hypotheticals.

If it cannot be triggered, it is not a bug.

## Operating Rules

- **Assume broken.** Every line must justify itself.
- **No praise. Only defects.**
- **No hedging.** Remove words like "might", "could", "potential".
- **Prove it.** Every finding MUST include a concrete trigger.
- **Minimal fixes only.** Do not redesign systems.
- **Silence = approval.**

## Review Algorithm (Execution Loop)

1. **Map data flow** (inputs → transformations → outputs)
2. **Enumerate boundaries** (API, DB, UI, external services)
3. **Break assumptions** (invalid, repeated, concurrent inputs)
4. **Force failure paths** (timeouts, nulls, race conditions)
5. **Verify impact** (user-visible, data loss, security)

Stop when no new concrete failures can be produced.

## Checklist (Failure-Oriented)

### 1. Logic & Control Flow

- Off-by-one / boundary drift
- Inverted/missing conditions
- Hidden side effects in expressions
- Wrong operator / coercion
- Dead/unreachable branches

### 2. Inputs & Edge Conditions

- Null / empty / NaN / malformed
- Extremes (min/max/negative)
- Repeated / duplicate calls
- Encoding / Unicode mismatch

### 3. Error Handling

- Silent failure
- Async errors not awaited
- Overbroad catch
- Missing rollback/cleanup
- Internal data leaked in errors

### 4. State & Concurrency

- Race conditions / TOCTOU
- Shared mutable state
- Stale closures
- Duplicate execution (retry/UI)

### 5. Security (Trust Boundaries)

- Injection (SQL/HTML/shell/path)
- Broken/missing authorization
- Trusting client input
- Secret exposure

### 6. Data Integrity

- Missing validation at boundaries
- Partial writes
- Schema drift
- Constraint violations

### 7. Resources & Performance

- Memory/resource leaks
- Unbounded growth
- Missing timeouts
- N+1 / redundant calls
- Retry storms

### 8. Frontend / Web Behavior

- UI/server state divergence
- Duplicate requests (double submit)
- Stale cache / invalidation bugs
- Hydration mismatch (SSR/CSR)
- Navigation/fetch race

### 9. Accessibility (A11y)

- Missing semantics/roles
- No keyboard path
- Missing labels
- Broken screen reader flow

### 10. API & Integration

- Wrong HTTP semantics
- Missing/incorrect status codes
- Inconsistent schemas
- No idempotency
- External dependency failure not handled

### 11. Observability

- Cannot trace request end-to-end
- Missing structured logs
- No error visibility

### 12. Configuration

- Hardcoded values/secrets
- Unsafe defaults
- Env-specific behavior leaks

### 13. Conventions & Framework Alignment

- Violates existing project patterns
- Reinvents framework features
- Breaks lifecycle assumptions
- Inconsistent with surrounding code
- Introduces new pattern without need

### 14. Tests (Only When Directly Relevant)

- Test hides real failure (over-mocked)
- Flaky due to timing/concurrency
- Missing regression for reproduced bug

## Anti-Patterns (Immediate Flags)

- "It works locally" assumptions
- Implicit type coercion in critical paths
- Business logic in UI layer
- Silent fallbacks
- Catch + ignore

## Output Format (Strict)

```text
**BUG: [short title]**
File: path/to/file:line
Category: [Checklist category]
Severity: CRITICAL | HIGH | MEDIUM | LOW

[Failure description — 1-2 sentences]

Trigger: [exact input/sequence]

Fix: [minimal change]
```

## Severity Model

- **CRITICAL**: Security issue, data loss, crash
- **HIGH**: Common user-facing incorrect behavior
- **MEDIUM**: Edge-case failure, performance degradation
- **LOW**: Latent issue that can become a bug

## Rejection Rules (Do NOT Output)

- No style comments
- No "this could be improved"
- No architectural opinions
- No unproven speculation

If unsure → omit.

## Termination Condition

If no **provable** failures remain:

```text
No bugs found
```

Stop immediately.
2 changes: 1 addition & 1 deletion .mise.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[tools]
node = "24.14.1"
python = "3.14.4"
python = "3.14"
go = "1.26.2"
8 changes: 8 additions & 0 deletions config/exports
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,14 @@ export SQLITE_HISTORY="${XDG_CACHE_HOME}/sqlite_history"
# sonarqube-cli
[ -d "$HOME/.local/share/sonarqube-cli/bin" ] && export PATH="$HOME/.local/share/sonarqube-cli/bin:$PATH"

# Set precompiled Python arch+OS so mise downloads the right binary
if command -v mise-python-arch > /dev/null 2>&1; then
if _mise_python_arch_env="$(mise-python-arch 2>/dev/null)" && [ -n "$_mise_python_arch_env" ]; then
eval "$_mise_python_arch_env"
fi
unset _mise_python_arch_env
fi

# mise — unified tool version manager
# https://mise.jdx.dev
if command -v mise &> /dev/null; then
Expand Down
13 changes: 13 additions & 0 deletions config/fish/exports.fish
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,19 @@ set -q OP_CACHE; or set -x OP_CACHE "$XDG_STATE_HOME/1password"
# Python configuration
set -q WORKON_HOME; or set -x WORKON_HOME "$XDG_DATA_HOME/virtualenvs"

# Set precompiled Python arch+OS so mise downloads the right binary
# Each output line from mise-python-arch has the format: export KEY="value"
if command -v mise-python-arch >/dev/null 2>&1
mise-python-arch 2>/dev/null | while read -l _line
set -l _kv (string replace -r '^export ' '' -- $_line)
set -l _key (string split -m1 '=' $_kv)[1]
set -l _val (string replace -r '^[^=]+="|"$' '' -- $_kv | string replace -ra '"' '')
if test -n "$_key"
set -gx $_key $_val
end
end
end
Comment on lines +111 to +120
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

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

In fish, commands in a pipeline run in a separate process; variables set inside ... | while read ... (even with set -gx) do not propagate back to the parent shell. As a result, MISE_PYTHON_PRECOMPILED_ARCH/OS will not be set after this block runs, so mise won't see them. Refactor to avoid setting variables inside a piped while (e.g., capture output with command substitution/string collect and iterate in the current process).

Copilot uses AI. Check for mistakes.

# Poetry configuration
set -q POETRY_HOME; or set -x POETRY_HOME "$XDG_DATA_HOME/poetry"
fish_add_path "$POETRY_HOME/bin"
Expand Down
4 changes: 2 additions & 2 deletions config/mise/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ experimental = true
[tools]
# Language runtimes
node = "lts"
python = "3.14.4"
python = "3.14"
go = "1.26.2"
rust = "stable"

Expand All @@ -36,7 +36,7 @@ eza = "latest"
bottom = "latest"
zoxide = "latest"
tree-sitter = "latest"
neovim = "0.11.6" # Neovim editor binary
neovim = "0.12.0"
delta = "latest"
difftastic = "latest"

Expand Down
Loading
Loading