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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
16 changes: 8 additions & 8 deletions .claude/skills/contributing-to-loopover/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ opening a **fresh** PR. This is the entire reason to get it right before you pus
git clone https://github.com/<you>/gittensory && cd gittensory
git remote add upstream https://github.com/JSONbored/gittensory # to sync main later
nvm use # Node 22 (.nvmrc)
npm ci # installs the whole workspace, incl. apps/gittensory-ui — required before any check
npm ci # installs the whole workspace, incl. apps/loopover-ui — required before any check
```

All `npm run …` commands run from the **repo root**. As an external contributor you **push to your
Expand Down Expand Up @@ -125,7 +125,7 @@ pasted JSON block will not work in Codex). You'll use these tools in Phases 1 an
- **Run the pre-start checks** via MCP: `loopover_check_before_start` (is it claimed / a duplicate
cluster / already solved?) and, if linking an issue, `loopover_validate_linked_issue`.
- **Stay in scope.** The gate's `wantedPaths` are `src/`, `packages/`, `test/`, `migrations/`,
`scripts/`, `review-enrichment/`, `.github/workflows/`, `wrangler.jsonc`, `apps/gittensory-ui/`. Avoid `blockedPaths`
`scripts/`, `review-enrichment/`, `.github/workflows/`, `wrangler.jsonc`, `apps/loopover-ui/`. Avoid `blockedPaths`
(`site/`, `CNAME`, `**/lovable/**`). Keep the PR narrow — one coherent change.

---
Expand Down Expand Up @@ -198,13 +198,13 @@ Run the matching command(s) and **commit the regenerated file(s)** — CI fails

| You changed… | Run | Commit |
|---|---|---|
| API routes or OpenAPI schemas (`src/`) | `npm run ui:openapi` | `apps/gittensory-ui/public/openapi.json` |
| API routes or OpenAPI schemas (`src/`) | `npm run ui:openapi` | `apps/loopover-ui/public/openapi.json` |
| A Cloudflare binding/var in `wrangler.jsonc` | `npm run cf-typegen` | `worker-configuration.d.ts` |
| Drizzle schema (`src/db/schema.ts`) | `npm run drizzle:generate` | the new `migrations/NNNN_*.sql` |
| Added a raw-SQL migration | (none — just author it) | next **contiguous** `migrations/NNNN_snake.sql` |
| `src/selfhost/**` (or a few other scanned files — see `scripts/gen-selfhost-env-reference.mjs`'s `DEFAULT_SOURCE_ROOTS`) adding/removing an `env.SOMETHING` read | `npm run selfhost:env-reference` | `apps/gittensory-ui/src/lib/selfhost-env-reference.ts` — the doc cites the file only (not `file:line`, deliberately, so an unrelated line shift elsewhere in the file never makes this go stale) |
| `src/selfhost/**` (or a few other scanned files — see `scripts/gen-selfhost-env-reference.mjs`'s `DEFAULT_SOURCE_ROOTS`) adding/removing an `env.SOMETHING` read | `npm run selfhost:env-reference` | `apps/loopover-ui/src/lib/selfhost-env-reference.ts` — the doc cites the file only (not `file:line`, deliberately, so an unrelated line shift elsewhere in the file never makes this go stale) |
| CLI command surface | `npm run command-reference` | the generated command-reference doc |
| UI files (`apps/gittensory-ui/**`) | `npm --workspace @loopover/ui run format` | formatted files |
| UI files (`apps/loopover-ui/**`) | `npm --workspace @loopover/ui run format` | formatted files |

Migrations must use the **next free number** (contiguous, no gaps, no reuse) and match
`NNNN_snake_case.sql`; `db:migrations:check` enforces it.
Expand Down Expand Up @@ -264,17 +264,17 @@ merge instead of a one-shot close.
below needs real, clickable thumbnail URLs — here's how to get them when you can't drag-and-drop into
GitHub's web editor (which needs a human browser session an AI coding tool can't drive end-to-end):

1. **Local dev server:** `npm --prefix apps/gittensory-ui run dev` (Vite forces port **8080** regardless
1. **Local dev server:** `npm --prefix apps/loopover-ui run dev` (Vite forces port **8080** regardless
of what you request — use that port in any launch config, or `preview_screenshot`-style tooling just
hangs waiting for the server). For an auth-gated page, use the sanctioned local-preview escape hatch
instead of real GitHub OAuth: `useSession().signInPreview()` (`apps/gittensory-ui/src/lib/api/session.ts`),
instead of real GitHub OAuth: `useSession().signInPreview()` (`apps/loopover-ui/src/lib/api/session.ts`),
gated on `import.meta.env.DEV` — it sets a synthetic session client-side with no network write. Click
the "Continue with local preview" button in the sign-in wall rather than calling the hook indirectly
(the real `fetchBrowserSession()` call can race in afterward and silently overwrite it back to `null`);
overriding `window.fetch` for `/v1/auth/session` to return the same authenticated shape closes that
race either way.
2. **Fixed viewport, never a full-page/`fullPage: true` capture.** gittensory-ui is a **dark-mode-only
build** (`apps/gittensory-ui/src/components/site/theme-toggle.tsx` — the toggle was removed; there is
build** (`apps/loopover-ui/src/components/site/theme-toggle.tsx` — the toggle was removed; there is
no light theme left to force), so there's no theme dimension to multiply out. Capture at whichever
viewport(s) your change actually affects — mobile (375×812) and desktop (1280×800) cover most cases;
add a caption per state either way (`"Loaded state"`, `"Mobile layout"`, etc., matching the existing
Expand Down
8 changes: 4 additions & 4 deletions .claude/skills/contributing-to-loopover/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ path filter matched; on push to `main`, everything runs.
| lint → migrations | migration guard | `npm run db:migrations:check` | duplicate/gap/misnamed migration number |
| lint → cf-typegen | worker types drift | `npm run cf-typegen:check` | committed `worker-configuration.d.ts` is stale (run `npm run cf-typegen`) |
| lint → schema-drift | `src/db/schema.ts` vs `migrations/` | `npm run db:schema-drift:check` | a Drizzle table's schema doesn't match the migration history |
| lint → selfhost-env-reference | self-host env-var doc drift | `npm run selfhost:env-reference:check` | committed `apps/gittensory-ui/src/lib/selfhost-env-reference.ts` is stale (run `npm run selfhost:env-reference`) — triggers when `src/selfhost/**` (+ a few other scanned files) adds/removes an env var read; a pure line shift of an existing read does NOT trigger it, since the doc cites the file only, not `file:line` (#env-reference-churn) |
| lint → selfhost-env-reference | self-host env-var doc drift | `npm run selfhost:env-reference:check` | committed `apps/loopover-ui/src/lib/selfhost-env-reference.ts` is stale (run `npm run selfhost:env-reference`) — triggers when `src/selfhost/**` (+ a few other scanned files) adds/removes an env var read; a pure line shift of an existing read does NOT trigger it, since the doc cites the file only, not `file:line` (#env-reference-churn) |
| lint → observability | Grafana/Prometheus/alert config validation | `npm run selfhost:validate-observability` | a self-host observability config (dashboard/rule/datasource) is malformed |
| lint → typecheck | `tsc --noEmit` | `npm run typecheck` | any backend type error |
| test (1/2) | sharded vitest + coverage | `npm run test:coverage` (unsharded) | any failing `test/**/*.test.ts` (excl. `test/workers/**`) |
Expand All @@ -51,7 +51,7 @@ path filter matched; on push to `main`, everything runs.

**One command for everything except `security`:** `npm run test:ci`. There is **no** CodeQL/Analyze
workflow in this repo. There is **no** root-level Prettier gate — Prettier is enforced only inside
`ui:lint` (so it only bites `apps/gittensory-ui/**`).
`ui:lint` (so it only bites `apps/loopover-ui/**`).

**Local-only checks with no separate named CI status — `npm run test:ci` is the only thing that catches
these for a normal PR:**
Expand All @@ -65,7 +65,7 @@ these for a normal PR:**
This is a real, previously-hit gap, not a hypothetical: a past PR shipped a genuine, undetected
`codecov/patch`-adjacent regression in the engine package specifically because `test --workspace
@loopover/engine` isn't part of `ci.yml`. If your change touches
`packages/gittensory-engine/**`, running `npm run test:ci` locally (not just watching the PR's CI
`packages/loopover-engine/**`, running `npm run test:ci` locally (not just watching the PR's CI
checks go green) is the only way to know you didn't break it.

---
Expand Down Expand Up @@ -117,7 +117,7 @@ Implications for you:
`.loopover.yml` (the public config you can predict against) sets the gate *modes* (`linkedIssue:
advisory`, `duplicates: block`, `readiness: advisory/60`, AI review off) and the focus manifest
(`wantedPaths`: `src/ packages/ test/ migrations/ scripts/ review-enrichment/ .github/workflows/
wrangler.jsonc apps/gittensory-ui/`; `blockedPaths`: `site/ CNAME **/lovable/**`; `linkedIssuePolicy: preferred`;
wrangler.jsonc apps/loopover-ui/`; `blockedPaths`: `site/ CNAME **/lovable/**`; `linkedIssuePolicy: preferred`;
`testExpectations: npm run test:ci`). But the **modes are inputs to the disposition above** — the
engine still auto-merges the clean case and auto-closes the adverse case. The MCP `predict_gate` uses
the public config + safe defaults; a clean prediction is necessary but not sufficient (it can't see
Expand Down
8 changes: 4 additions & 4 deletions .claude/skills/contributor-pipeline-gardening/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

Two products, self-host-first:

- **AMS (Autonomous Miner System)** — `packages/gittensory-miner` (npm: `@loopover/miner`) +
`packages/gittensory-engine` (npm: `@loopover/engine`, shared core also used by ORB) +
`apps/gittensory-miner-ui` + `apps/gittensory-miner-extension`. The contributor/miner side: finds
- **AMS (Autonomous Miner System)** — `packages/loopover-miner` (npm: `@loopover/miner`) +
`packages/loopover-engine` (npm: `@loopover/engine`, shared core also used by ORB) +
`apps/loopover-miner-ui` + `apps/loopover-miner-extension`. The contributor/miner side: finds
issues, plans, writes code, opens PRs, autonomously. Self-host (a local Miner Node) is the only
shipped deployment target; hosted AMS is a later phase (see "AMS/ORB Cloud Readiness" below).
- **ORB (Owner/One-shot Review Brain)** — `src/**` (the Worker app: `src/review`, `src/queue`,
Expand All @@ -21,7 +21,7 @@ Two products, self-host-first:
**Standing priorities named by the maintainer (2026-07-14), not yet issue-backed:**
- **AMS selfhost hardening, round 2.** Miner Wave 4 ("AMS Hardening & Packaging") fully closed
(151/151) on 2026-07-14 — that backlog is empty, not hiding more maintainer-only work. Getting more
requires a fresh gap-audit (read the current `packages/gittensory-miner`/`-engine` code against what
requires a fresh gap-audit (read the current `packages/loopover-miner`/`-engine` code against what
Wave 4 already covered — coverage gate, ledger races, MCP scaffolding — and find what's still
genuinely thin), not relabeling existing issues.
- **Unified AMS+ORB self-host harness** — letting one operator install/run both products together in
Expand Down
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ REDIS_URL=redis://redis:6379 # REQUIRED for the self-host review
# LOOPOVER_REPORTING_SOURCE_DB=/appdb/loopover.sqlite # if DATABASE_PATH=/data/custom.sqlite, set /appdb/custom.sqlite
#
# AMS (loopover-miner) ledger dashboards — only useful when a miner ALSO runs on this same host (see
# packages/gittensory-miner/docs/observability.md). Requires --profile ams-observability, separate from the
# packages/loopover-miner/docs/observability.md). Requires --profile ams-observability, separate from the
# general observability profile above: an engine-only deployment has nothing for this exporter to read.
# Grafana never mounts the live ledgers directly — this exporter reads them read-only and writes a redacted
# snapshot (free-form attempt_log_events.reason/.payload_json dropped) into the same reporting volume.
Expand Down
Loading
Loading