Skip to content
Merged
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
22 changes: 22 additions & 0 deletions .lore.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!-- Managed by lore (https://github.com/BYK/loreai) — manual edits are imported on next session. -->

## Long-term Knowledge

### Architecture

<!-- lore:019e00de-f55a-7c50-9b12-4ea9f3e69318 -->
* **opentower handler.ts: CORS scoped to /api/\* by default, not global**: Prior to the CORS fix, \`hono/cors\` was only applied to \`/api/\*\` routes, leaving \`/healthz\` inaccessible from browser origins. The correct pattern is to register \`app.use('\*', cors({...}))\` as the first middleware before \`app.onError\` and before any route. \`allowMethods\` must include \`POST\` for webhook routes if browser preflight checks are needed.

### Gotcha

<!-- lore:019e049d-8b73-737f-9827-63d19abac7aa -->
* **@loreai/opencode 0.13.0–0.13.3 unusable in bun workspaces due to fastembed workspace deps**: \`@loreai/opencode\` versions 0.13.0–0.13.3 and \`@loreai/core\` 0.13.3 transitively depend on \`fastembed@^2.1.0\`, which declared unresolvable \`workspace:\*\` deps (\`gearhash-jit\`, \`@huggingface/blake3-jit\`). Bun failed with "Workspace dependency not found" during install. This was resolved in 0.13.4 — \`fastembed@2.1.0\` on npm no longer carries the broken workspace deps. Note: bun's registry cache may lag npm by minutes — a version appearing in \`npm view ... versions\` may not resolve immediately in bun.

<!-- lore:019e0124-c974-7caf-8f4d-3c25402415c4 -->
* **Biome expects 2-space indentation; tabs cause CI failure**: The repo's \`biome.json\` enforces \`indentStyle: 'space'\` with \`indentWidth: 2\`. Files written with tabs will fail the \`biome check\` CI step. Fix: run \`bunx biome check --write\` (or \`node\_modules/.bin/biome check --write\`) from the repo root to auto-convert all files before committing. Also note: \`useExhaustiveDependencies\` warns when stable setter functions are listed as dependencies — suppress intentional cases with \`// biome-ignore lint/correctness/useExhaustiveDependencies: intentional\`.

<!-- lore:019e0121-de4a-758d-bd3f-baeb2ab25110 -->
* **bun.lock goes stale when adding packages inside a workspace subdirectory**: Running \`bun add\` inside a workspace package (e.g. \`packages/dashboard\`) updates that package's local state but may not update the root \`bun.lock\`. CI uses \`bun install --frozen-lockfile\` at the repo root, so a stale root lockfile causes build failure with "lockfile had changes, but lockfile is frozen". Fix: always run \`bun install\` from the repo root after adding any dependency, then commit the updated \`bun.lock\`.

<!-- lore:019e00de-f555-75cf-90a0-b08a79b4474b -->
* **Hono middleware registration order: /healthz bypasses app.use('\*') registered after it**: In \`handler.ts\`, \`/healthz\` is registered before \`app.use('\*', ...)\` middleware. Hono evaluates routes/middleware in registration order — any middleware registered after a matched route won't run for that route. To apply CORS (or any global middleware) to ALL routes including \`/healthz\`, register it before any route definitions, as the very first call on the \`app\` instance.
1 change: 1 addition & 0 deletions agents/github-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ load the situation skill for the task at hand.
- `pr` — create a draft PR
- `mark-pr-ready` — promote draft to ready-for-review
- `apply-fixes` — apply review findings as code changes
- `auto-merge` — merge small, non-disruptive PRs after checks pass

### Multi-repo investigation

Expand Down
53 changes: 53 additions & 0 deletions skills/apply-fixes/SPEC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# apply-fixes — Specification

## Intent

Turn structured review findings into minimal code changes, committed
and pushed. Used on the bot's own PRs after the `review` skill
produces findings.

## Scope

### In scope

- Parsing the findings JSON array
- Implementing one finding at a time as the smallest possible change
- Running tests when available
- Loading `deslop` before committing
- Reporting which findings were addressed and which were skipped

### Out of scope

- Opening new PRs or branches
- Force-pushing
- Fixing findings that require architectural changes

## Invocation

Loaded by `review-pr` when findings exist on the bot's own PR, or
by any skill that needs to apply structured fixes.

## Runtime contract

### Input

- JSON array of findings: `[{ kind, file, line, summary, suggested_fix }]`

### Output

- Commit SHA, list of findings addressed, list of findings skipped with reasons

### Side effects

- Commits and pushes to the current feature branch

## Evaluation criteria

- Each finding is addressed with the smallest possible change
- Skipped findings have clear, valid reasons
- Only files that were edited are staged
- The `deslop` skill runs before committing

## Maintenance

- The findings schema must stay in sync with the `review` skill's output format
57 changes: 57 additions & 0 deletions skills/auto-merge/SPEC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# auto-merge — Specification

## Intent

Automatically merge small, non-disruptive PRs after they pass all
checks and have no review objections. Acts as the final step after
`mark-pr-ready` for trivial changes that don't need human review.

## Scope

### In scope

- Verifying PR state, target branch, and CI status
- Evaluating the size gate (lines, files, sensitive paths)
- Checking for review objections and unresolved threads
- Squash-merging with branch cleanup

### Out of scope

- PRs that were created as ready-for-review from the start
- PRs targeting non-default branches
- PRs with review objections or unresolved threads
- PRs exceeding the size gate

## Invocation

Loaded by `github-agent` after `mark-pr-ready` completes, or in
response to a `pull_request.ready_for_review` webhook for a PR
that transitioned from draft.

## Runtime contract

### Input

- PR number and repository context

### Output

- Merge confirmation comment, or a comment explaining why auto-merge was skipped

### Side effects

- Merges the PR (squash) and deletes the feature branch
- Uses `--auto` to respect branch protection rules

## Evaluation criteria

- All six preconditions are verified before merging
- The size gate correctly identifies sensitive files (CI, lockfiles, migrations, auth, public API)
- PRs that need human review are never auto-merged
- The `--auto` flag is always used (never bypasses branch protection)

## Maintenance

- The size gate thresholds (150 lines, 5 files) may need tuning based on experience
- New sensitive file patterns may need to be added to the size gate
- The GraphQL query for unresolved threads depends on GitHub's API schema
15 changes: 12 additions & 3 deletions skills/deslop/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,23 @@ slop introduced in this branch.

- Extra comments that a human wouldn't add or that are inconsistent
with the rest of the file (no `// loop through items`, no
`# increment counter`).
`# increment counter`, no `// Handle the error case`).
- Extra defensive checks or try/catch blocks that are abnormal for
that area of the codebase, especially when called from
trusted/validated code paths.
- Casts to `any` (or `as unknown as X`) that exist purely to silence
the type checker.
the type checker. If a type assertion is needed, use the narrowest
correct type instead.
- Inline imports in Python — move to the top of the file alongside the
other imports.
other imports. Group with the appropriate import section (stdlib,
third-party, local).
- Redundant type annotations where TypeScript inference handles it
(e.g., `const x: string = "hello"` → `const x = "hello"`).
- Unnecessary `else` after `return`, `throw`, `continue`, or `break`.
- Console.log / print statements left from debugging.
- Overly verbose variable names that don't match the file's naming
convention (e.g., `isCurrentlyLoadingDataFromServer` when neighbors
use `loading`).
- Any other style that's inconsistent with the file (string quote
choice, brace style, trailing commas, etc.).

Expand Down
58 changes: 58 additions & 0 deletions skills/deslop/SPEC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# deslop — Specification

## Intent

Strip AI-generated noise from the diff before committing, ensuring
the final code reads as if a human wrote it. Clean diffs get merged
faster and avoid distracting reviewers.

## Scope

### In scope

- Removing unnecessary comments that restate the code
- Removing defensive try/catch blocks in trusted code paths
- Removing type casts (`any`, `as unknown as X`) that silence the checker
- Moving inline imports to the top of the file (Python)
- Removing redundant type annotations where inference handles it
- Removing unnecessary `else` after early returns
- Removing leftover debug logging (console.log, print)
- Replacing overly verbose variable names that break file conventions
- Fixing style inconsistencies with the surrounding file

### Out of scope

- Adding new functionality
- Refactoring code beyond slop removal
- Changing the logic or behavior of the code

## Invocation

Loaded as a utility skill before every commit, typically by
`resolve-issue`, `fix-ci`, `respond-to-comment`, and `apply-fixes`.

## Runtime contract

### Input

- A branch with uncommitted or committed changes ahead of the default branch

### Output

- A 1-3 sentence summary of what was cleaned up

### Side effects

- Modifies files in the working tree (removes slop patterns)

## Evaluation criteria

- Removed comments were genuinely redundant (not meaningful documentation)
- Removed try/catch blocks were genuinely unnecessary (not protecting against real failures)
- Style consistency with the surrounding file is improved, not degraded
- No behavioral changes introduced by slop removal

## Maintenance

- New AI slop patterns should be added as they are observed in practice
- Language-specific patterns (Python imports, TypeScript casts) may need expansion
11 changes: 7 additions & 4 deletions skills/fix-ci/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ prefix is required for counting but the rest should read naturally.

1. Find failed runs: `gh run list --branch <branch> --status failure`
2. Read logs: `gh run view <id> --log-failed`
3. Categorize: test failure, type/lint error, build error, snapshot
diff, flaky test, or infra issue.
3. Categorize the failure — see `references/failure-taxonomy.md` for
the full taxonomy and decision tree. Categories: test failure,
type/lint error, build error, snapshot diff, flaky test, or infra
issue.
4. Flaky? Re-run once (`gh run rerun <id> --failed`) and stop.
5. Infra/dependency issue? BLOCKED.
6. Otherwise: make the smallest fix. Reproduce locally if possible.
Expand All @@ -32,5 +34,6 @@ prefix is required for counting but the rest should read naturally.
how. Write it like a teammate explaining the fix, not a status
report.

Don't modify CI config unless the failure is specifically in it.
Don't bump dependency versions. Don't force-push. Don't merge.
Avoid modifying CI config unless the failure is specifically in it.
Avoid bumping dependency versions — the fix should target the code,
not the toolchain. Don't force-push. Don't merge.
59 changes: 59 additions & 0 deletions skills/fix-ci/SPEC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# fix-ci — Specification

## Intent

Diagnose and fix failing CI on a PR the bot authored, with a hard
budget of 3 attempts to prevent infinite fix loops.

## Scope

### In scope

- Reading CI failure logs
- Categorizing failures (test, type/lint, build, snapshot, flaky, infra)
- Making targeted fixes for test, type, lint, and build failures
- Re-running flaky tests once
- Loading `deslop` and `review` before committing fixes

### Out of scope

- Modifying CI configuration (unless the failure is specifically in it)
- Bumping dependency versions
- Fixing infrastructure issues (BLOCKED)
- Fixing failures unrelated to the bot's changes

## Invocation

Loaded by `github-agent` when a `check_suite` or `workflow_run` event
arrives with `conclusion: failure` for a PR the bot authored.
Requires `repo-setup` first.

## Runtime contract

### Input

- PR number and branch (from webhook payload)
- A prepared worktree on the PR's branch

### Output

- A fix commit pushed to the branch, or `BLOCKED: <reason>`

### Side effects

- Posts `fix-ci: attempt N` comments for budget tracking
- Commits and pushes fixes to the PR branch
- May re-run failed workflows for flaky tests

## Evaluation criteria

- The 3-attempt budget is respected (counted via comment prefix)
- Fixes are minimal — don't change more than necessary
- Flaky tests are re-run rather than "fixed"
- Infrastructure issues are correctly identified as BLOCKED
- The fix actually resolves the CI failure

## Maintenance

- The `gh run view --log-failed` output format may change across `gh` versions
- New CI failure categories may emerge (e.g., security scanning failures)
76 changes: 76 additions & 0 deletions skills/fix-ci/references/failure-taxonomy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# CI Failure Taxonomy

Categorize the failure before attempting a fix. The category
determines the response strategy.

## Categories

### 1. Test failure

**Signature:** Test runner output with `FAIL`, assertion errors,
expected/actual diffs.

**Response:** Read the failing test, understand what it asserts, check
if the test expectation is wrong (your change intentionally altered
behavior) or if the code has a bug. Fix the test if the expectation
is outdated; fix the code if the behavior is wrong.

### 2. Type / lint error

**Signature:** `tsc` errors (TS####), ESLint/Biome errors with rule
names, type mismatch messages.

**Response:** Fix the type or lint issue directly. These are usually
mechanical. For lint rules you disagree with, fix the code anyway —
don't modify lint config.

### 3. Build error

**Signature:** Bundler/compiler errors, missing modules, import
resolution failures.

**Response:** Check if your change broke an import path, removed an
export, or changed a file name. Fix the import/export. If the build
error is in unrelated code, note it and investigate whether it's
pre-existing.

### 4. Snapshot diff

**Signature:** Snapshot test failures showing before/after diffs.

**Response:** If your change intentionally altered the output, update
the snapshot (`--update-snapshots`, `-u`, etc.). If the diff is
unexpected, investigate why the output changed.

### 5. Flaky test

**Signature:** The test passes on retry. The failure involves timing,
network, or random ordering. The test name may appear in known-flaky
lists.

**Response:** Re-run once: `gh run rerun <id> --failed`. Do not
attempt to fix the test — flaky test fixes are out of scope for a
CI-fix skill.

### 6. Infrastructure issue

**Signature:** Network timeouts, registry errors (`npm ERR! 503`),
Docker pull failures, runner out of disk, GitHub Actions service
degradation.

**Response:** BLOCKED. These are transient or platform-level issues.
Post a comment noting the infrastructure failure and stop.

## Decision tree

```
Is it a test failure?
├── Yes → Did your change intentionally alter behavior?
│ ├── Yes → Update the test/snapshot
│ └── No → Fix the code bug
└── No → Is it a type/lint/build error?
├── Yes → Fix the type/lint/import issue
└── No → Is it intermittent / passes on retry?
├── Yes → Re-run once, then stop
└── No → Infrastructure issue → BLOCKED
```
Loading
Loading