Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
8 changes: 8 additions & 0 deletions .cursor/skills/lucky-ci-gate-recovery/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,15 @@ gh pr checks <PR#> --required
- `quality-gate`: coverage/duplication/new-code thresholds
- `workflow-runtime`: action/runtime failure
- `ruleset-mismatch`: required context name differs from workflow-reported check
- `deploy-checkout-drift`: deploy webhook blocked by dirty checkout/unmerged files

5. Apply minimal fix in this order:

- Ruleset/context mismatch first
- CI contract mismatch second
- then branch drift/rebase
- then quality/test deltas
- for deploy checkout drift: clean target host checkout before rerun

6. Merge safety:

Expand All @@ -69,6 +71,12 @@ gh pr merge <PR#> --squash --match-head-commit "$SHA"
- Pending informational checks (for example CodeRabbit/preview providers) are not blockers unless explicitly listed in the active ruleset.
- If a required status is missing entirely, treat as `ruleset-mismatch` until context names are reconciled.

## Deploy rerun policy

- `LOCK_CONTENTION`: one immediate rerun is allowed.
- `CHECKOUT_RECOVERY_FAILED`: require host checkout cleanup evidence before rerun.
- Repeated `CHECKOUT_RECOVERY_FAILED` without host cleanup is treated as operator error, not CI flake.

## Post-merge smoke contract

```bash
Expand Down
62 changes: 62 additions & 0 deletions .cursor/skills/lucky-deploy-recovery/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
name: lucky-deploy-recovery
description: Use when Lucky Deploy to Homelab fails due webhook lock contention, dirty checkout drift, or runtime precheck failures.
---

# Lucky Deploy Recovery

## When to use

- `Deploy to Homelab` is red on `main`
- Webhook response returns `another deploy is already running`
- Webhook response mentions local changes, overwritten merge files, or unmerged files
- Auth-config smoke never starts because webhook trigger failed

## Failure buckets

- `LOCK_CONTENTION`: concurrent webhook deploy already running
- `CHECKOUT_RECOVERY_FAILED`: target checkout drift or merge-conflict state
- `RUNTIME_PRECHECK_FAILED`: compose/migration/health precheck failed after webhook accepted

## Triage sequence

1. Confirm latest failing run and failed step log:

```bash
gh run list --branch main --workflow "Deploy to Homelab" --limit 5
gh run view <RUN_ID> --log-failed
```

2. Validate target host checkout state:

```bash
ssh server-do-luk 'cd /home/luk-server/Lucky && git status --short --branch'
```

3. If dirty checkout is present, archive drift and clean checkout:

```bash
ssh server-do-luk 'cd /home/luk-server/Lucky && git stash push -u -m "manual-deploy-unblock-$(date -u +%Y%m%dT%H%M%SZ)"'
ssh server-do-luk 'cd /home/luk-server/Lucky && git fetch origin main && git reset --hard origin/main && git clean -fd'
```

4. Rerun deploy workflow:

```bash
gh run rerun <RUN_ID>
gh run watch <RUN_ID> --exit-status
```

5. Post-deploy smoke:

```bash
curl -i https://lucky-api.lucassantana.tech/api/health
curl -i https://lucky-api.lucassantana.tech/api/health/auth-config
curl -i https://lucky-api.lucassantana.tech/api/auth/discord
```

## Rerun policy

- One immediate rerun is allowed for `LOCK_CONTENTION`.
- If rerun still fails with `CHECKOUT_RECOVERY_FAILED`, perform host checkout cleanup before another rerun.
- Do not keep blind rerunning on repeated `CHECKOUT_RECOVERY_FAILED`; require host cleanup evidence first.
13 changes: 12 additions & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,19 @@ jobs:
fi
done

failure_body_compact="$(echo "$selected_body" | tr '\n' ' ' | sed 's/[[:space:]]\+/ /g' | sed 's/^ //; s/ $//')"
if echo "$failure_body_compact" | grep -qi "another deploy is already running"; then
echo "::error title=LOCK_CONTENTION::Deploy webhook lock contention: $failure_body_compact"
elif echo "$failure_body_compact" \
| grep -Eqi "would be overwritten by merge|unmerged files|fatal: Exiting because of an unresolved conflict|Aborting"; then
echo "::error title=CHECKOUT_RECOVERY_FAILED::Deploy checkout recovery failed: $failure_body_compact"
elif echo "$failure_body_compact" \
| grep -Eqi "compose preflight|migration|health|required services|cloudflared|relation"; then
echo "::error title=RUNTIME_PRECHECK_FAILED::Deploy runtime precheck failed: $failure_body_compact"
fi

echo "::error::Deploy webhook failed with HTTP $selected_code"
echo "::error::Response body: $selected_body"
echo "::error::Response body: $failure_body_compact"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
exit 1

- name: Auth config smoke check
Expand Down
5 changes: 2 additions & 3 deletions .opencode/plugins/lucky-policy-lib.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,8 @@ export function commandTouchesSensitivePath(
'~/.aws/',
'~/.config/fish/config.fish',
'~/.local/share/opencode/auth.json',
`${repoRoot ?? ''}/.env`,
`${repoRoot ?? ''}/.cursor/.env.mcp`,
].filter(Boolean)
...(repoRoot && repoRoot !== '/' ? [`${repoRoot}/.env`, `${repoRoot}/.cursor/.env.mcp`] : []),
]

for (const candidate of candidates) {
if (command.includes(candidate) && !command.includes('.env.example')) {
Expand Down
40 changes: 20 additions & 20 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,23 @@ At the start of every session:

### Project skills (`.cursor/skills/`)

| Task | Skill |
| ------------------------------------------------- | ------------------------ |
| Add/change slash command | `discord-commands` |
| Play/queue/skip/volume, player lifecycle | `music-queue-player` |
| Schema, migrations, DB/Redis in shared | `prisma-redis-lucky` |
| Docker, compose, local run | `lucky-docker-dev` |
| Frontend (React, Vite, Tailwind) | `frontend-react-vite` |
| Backend (Express API, routes, services) | `backend-express` |
| E2E tests, Playwright, browser verification | `e2e-playwright` |
| Docs lookup, web search, MCP usage | `mcp-docs-search` |
| Moderation commands + AutoModService | `moderation-automod` |
| Bot event wiring (messageCreate, memberAdd, etc.) | `event-handlers` |
| Embed builder, custom commands, auto-messages | `management-features` |
| Unit tests, Jest ESM mocks, fixing disabled tests | `testing-lucky` |
| CI gate triage and required-check recovery | `lucky-ci-gate-recovery` |
| Recover GitHub MCP transport/auth failures | `mcp-github-recovery` |
| Task | Skill |
| ------------------------------------------------- | -------------------------- |
| Add/change slash command | `discord-commands` |
| Play/queue/skip/volume, player lifecycle | `music-queue-player` |
| Schema, migrations, DB/Redis in shared | `prisma-redis-lucky` |
| Docker, compose, local run | `lucky-docker-dev` |
| Workflow green but production stale deploy drift | `lucky-deploy-recovery` |
| Frontend (React, Vite, Tailwind) | `frontend-react-vite` |
| Backend (Express API, routes, services) | `backend-express` |
| E2E tests, Playwright, browser verification | `e2e-playwright` |
| Docs lookup, web search, MCP usage | `mcp-docs-search` |
| Moderation commands + AutoModService | `moderation-automod` |
| Bot event wiring (messageCreate, memberAdd, etc.) | `event-handlers` |
| Embed builder, custom commands, auto-messages | `management-features` |
| Unit tests, Jest ESM mocks, fixing disabled tests | `testing-lucky` |
| CI gate triage and required-check recovery | `lucky-ci-gate-recovery` |
| Recover GitHub MCP transport/auth failures | `mcp-github-recovery` |
| OpenCode config, plugins, attach, verification | `opencode-lucky-workflows` |

### Ecosystem skills (`.agent-skills/` — from skills.sh)
Expand Down Expand Up @@ -94,11 +95,11 @@ Superpowers are installed at **`~/.codex/superpowers`**. To use a skill in chat
| `superpowers:writing-plans` | You have a spec or requirements for a multi-step task |
| `superpowers:writing-skills` | Creating, editing, or verifying skills |

**Agent behavior:** When the user asks in chat or in a prompt to use a superpowers skill (e.g. “use brainstorming”, “follow TDD”, “run systematic debugging”), run `~/.codex/superpowers/.codex/superpowers-codex use-skill <skill-name>` with the matching name above, then follow the skill’s instructions. Use MCP tools (Context7, filesystem, GitHub, etc.) as needed while applying the skill.
**Agent behavior:** When the user asks in chat or in a prompt to use a superpowers skill (e.g. "use brainstorming", "follow TDD", "run systematic debugging"), run `~/.codex/superpowers/.codex/superpowers-codex use-skill <skill-name>` with the matching name above, then follow the skill's instructions. Use MCP tools (Context7, filesystem, GitHub, etc.) as needed while applying the skill.

## MCP tools – when to use

Use these MCPs when they fit the task; don’t force them.
Use these MCPs when they fit the task; don't force them.

| MCP | Use for |
| ---------------------------------------------------------------- | -------------------------------------------------------------------- |
Expand Down Expand Up @@ -127,7 +128,7 @@ Use these MCPs when they fit the task; don’t force them.

Use the **specific specialist and skills** for the task; use **MCP tools** to fix or implement when applicable.

1. **Scope**: Prefer the smallest change that solves the problem. Don’t refactor unrelated code or add abstractions “for the future.”
1. **Scope**: Prefer the smallest change that solves the problem. Don't refactor unrelated code or add abstractions "for the future."
2. **Comments**: No redundant or decorative AI comments. Code should be clear from names and structure; comment only when logic is non-obvious.
3. **Boilerplate**: Avoid extra layers, base classes, or indirection unless the codebase already uses them for that case.
4. **Secrets / env**: No hardcoded secrets, IPs, or ports. Use `.env` and `docs/` for required vars.
Expand All @@ -144,7 +145,6 @@ Use the **specific specialist and skills** for the task; use **MCP tools** to fi

Use Docker for local when available (`docker-compose.dev.yml`). Prefer scripts in `scripts/` for documented operations.


- Repo-local OpenCode behavior lives in `opencode.jsonc`, `.opencode/plugins`, and `.opencode/skills`.
- Host-local OpenCode auth, provider state, and MCP credentials stay in `~/.config/opencode`.
- Use `scripts/opencode-sync-project-skills.sh` after changing project skills or OpenCode skill bridges.
Expand Down
Loading