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
4 changes: 2 additions & 2 deletions .claude/pending-lessons.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ Reviewed and promoted via `/lesson`. Delete each entry once promoted to a rule/h
- Draft: When the user frames a GLM-5.2 scenario as "opencode + Zen" / "opencode go + zen", the access + billing route is the **opencode Zen gateway** (provider "OpenCode Go", `opencode.ai/zen`, slug `opencode-go/glm-5.2`, metered pay-as-you-go). Do NOT price it as Z.ai's direct GLM Coding Plan subscription. GLM-5.2 is upstream a Z.ai/Zhipu model — cite Z.ai only as the model maker / benchmark source, never as the billing route unless the user explicitly says "Z.ai" or "GLM Coding Plan".

## 2026-07-14 — sweep-merge can race a re-triggered review on a BEHIND PR → merges past CHANGES_REQUESTED
- Trigger: `.claude/night-run/merge-sweep-cov.sh` merging any PR that is BEHIND main (require-up-to-date) and therefore needs an update-branch. Hit once on orbit-api #403 (a HIGH backend-contract finding shipped to main + deployed before the re-review landed; the fix went to the orphaned head branch, not main).
- Trigger: `tools/merge-sweep-cov.sh` merging any PR that is BEHIND main (require-up-to-date) and therefore needs an update-branch. Hit once on orbit-api #403 (a HIGH backend-contract finding shipped to main + deployed before the re-review landed; the fix went to the orphaned head branch, not main).
- Type: checkable (the sweep script can enforce this deterministically).
- Proposed home: a guard inside `merge-sweep-cov.sh` (gitignored night-run tooling) — after its update-branch step, re-poll `gh pr view <n> --json reviewDecision` until the re-triggered `review` check reaches a terminal state, and BLOCK the merge unless it re-settles to APPROVED (never merge on the pre-update APPROVED snapshot). Secondary signal to detect a past occurrence: the PR's head branch survives deletion (a post-merge push re-created it) = an orphaned fix that never reached main — scan for surviving head branches after a sweep.
- Proposed home: a guard inside `tools/merge-sweep-cov.sh` — after its update-branch step, re-poll `gh pr view <n> --json reviewDecision` until the re-triggered `review` check reaches a terminal state, and BLOCK the merge unless it re-settles to APPROVED (never merge on the pre-update APPROVED snapshot). Secondary signal to detect a past occurrence: the PR's head branch survives deletion (a post-merge push re-created it) = an orphaned fix that never reached main — scan for surviving head branches after a sweep.
- Draft: In the sweep, sequence = update-branch → wait-for-checks-terminal (INCLUDING `review`) → re-read reviewDecision → if APPROVED and required checks green (or coverage-only), merge; else abort + report. Do not read reviewDecision once before the update-branch and reuse it.
- Interim operational guard (until promoted): for every BEHIND-PR sweep tonight, after merge re-check `reviewDecision` + whether the head branch still exists; if flipped/orphaned, fix-forward onto main.

Expand Down
7 changes: 7 additions & 0 deletions .claude/research/agent-memory-guardrails-operating-model.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Operating model: why the "know-better-but-ship-worse + write-a-memory" loop happens, and the fix

> **At a glance** - why the "knows the rule but ships the worse default, then writes a memory" loop happens, and the fix.
> - The one change: stop writing "never do X" memory rules; encode every checkable rule as a deterministic guardrail (hook / lint / CI / type).
> - Keep memory and CLAUDE.md a lean, pruned pointer-index of load-bearing FACTS, not behavioral commandments.
> - For unmechanizable judgment, only external-signal verification helps (run the build / tests / an independent critic), never a remembered rule.
> - More rules lower adherence monotonically; prohibitions decay worse than requirements (all cited).
> - Read the whole doc for the mechanism, the citations, and what was applied to this repo.

Deep-research session 2026-07-06 (7 parallel research subagents, primary sources verified live). Triggered by the recurring failure: agent picks the conventional/worse default (JWT-claim admin auth over a live DB check; emits banned em-dashes it "knows" are banned), gets corrected, writes a "never do X" memory rule, repeats.

## The one operating change
Expand Down
7 changes: 7 additions & 0 deletions .claude/research/ai-environment-overhaul.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# AI Environment Overhaul: Plan, Runbook & Evidence

> **At a glance** - the locked plan and runbook for the 2026-07-07 AI environment overhaul.
> - Core principle: an instruction is a probabilistic bias that decays; reliability comes from architecture (where a rule lives), not phrasing.
> - Minimize what is always loaded, push every machine-checkable rule to a deterministic gate, load everything else just in time.
> - Two layers: a ~50-line global behavioral CLAUDE.md, and the Orbit-specific stack loaded on top (scoped CLAUDE.md + `.claude/rules/` + the enforcement stack).
> - Phased: wiring, budget cut, prose-to-gates, memory rebuild, then design plus the gated graduating `/lesson` loop.
> - Read the whole doc for the per-phase runbook and the cited evidence.

Source: `/deep-research` (6 parallel research agents, all live-doc verified), 2026-07-07.
Status: decisions locked; executing locally, phase by phase, no commits.

Expand Down
7 changes: 7 additions & 0 deletions .claude/research/harness-upgrade-plan.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Harness Upgrade — Execution Checklist

> **At a glance** - the actionable, stage-by-stage execution checklist for the harness upgrade (companion to `research.md`).
> - Run one stage per fresh session, keep each under ~100k tokens; this file IS the durable state a new session resumes from.
> - Guiding principle: autonomy within a phase, a human gate between phases, never a headless self-improving loop.
> - Locked (do not re-litigate): no Codex; opencode returns later; `opusplan` is out; keep `/execute` and `/feature`.
> - Encode each rule at its authority tier: hook = enforcement, rule = proactive guidance, skill = procedure, CLAUDE.md = fact.
> - Read the whole doc to pick up the next unchecked stage.

**Companion to `research.md` (repo root)**, which holds the full rationale + sources. This file is the *actionable* plan. Date: 2026-07-09.

## How to use this file
Expand Down
7 changes: 7 additions & 0 deletions .claude/research/opencode-glm52-go-zen-vs-openrouter.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# OpenCode + GLM‑5.2: Go + Zen vs OpenRouter

> **At a glance** - Go + Zen vs OpenRouter for running GLM-5.2 in the opencode agent, for a solo dev.
> - Bottom line: OpenCode Go primary + Zen spillover wins; the flat $10/mo (up to ~$60/mo at-cost draw) beats OpenRouter's per-token edge at realistic volume.
> - Go and Zen serve vetted full-precision weights; OpenRouter is a quantization lottery unless you pin the provider.
> - Make-or-break: model-routing discipline - reserve GLM-5.2 for hard tasks or you hit the caps in hours.
> - "Go" and "Zen" are OpenCode's own products (the opencode Zen gateway), not Z.ai's subscription.
> - Re-verify pricing before betting on it, it moves. Read the whole doc for the crossover math and the config.

**Question:** For running GLM‑5.2 and other open‑weight models in the OpenCode coding agent, which is the better setup for a solo dev — **(A)** OpenCode **Go** (flat sub) spilling over to **Zen** when capped, or **(B)** OpenCode + **OpenRouter** pay‑as‑you‑go?

**Researched:** 2026‑07‑09 (all facts verified live that day; re‑verify pricing before betting on it — it moves).
Expand Down
2 changes: 2 additions & 0 deletions .claude/skills/audit-tests/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ Parse `$ARGUMENTS` into a `{scope}` token: blank → `both`; `api`/`backend` →
| `orbit-ui-mobile` | Vitest. `apps/web/**/*.{test,spec}.{ts,tsx}`, `apps/mobile/**`, `packages/shared/**/__tests__/`. Factories: `packages/shared/src/__tests__/factories.ts`. Configs: `*/vitest.config.ts`. |
| `orbit-api` | xUnit + FluentAssertions in `tests/`. Test accounts via `TEST_ACCOUNTS` env. |

`TESTING.md` (repo root) is the canonical suite catalog: where each suite lives, its exact command, and what it proves.

Load `rubric.md` (the workflow's finders read it — it defines what "intelligent" means) and
**`.claude/skills/_shared/verification-protocol.md`**. **Unit only** — if the return flags
an integration/E2E/real-DB harness, treat it as out-of-policy (it was deliberately
Expand Down
34 changes: 34 additions & 0 deletions .claude/skills/make-tool/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
name: make-tool
description: Turn a repeated shell incantation into a reusable, agent-callable script under tools/. Use when you have run the same multi-flag command twice, or when a one-liner has grown into a pipeline worth naming and re-running. Not for a genuine one-off (that stays in your shell history or the scratchpad).
argument-hint: [what the tool should do]
---

# Make tool: promote a repeated incantation into `tools/`

**Input**: $ARGUMENTS (what the tool should do)

## When to reach for this

- You have typed the **same multi-flag command a second time** (rule 6: the third real use is the extract point, so the second is the signal to build it now).
- A one-liner has become a **pipeline worth a name** that you will run again.
- A future agent would need to rediscover an incantation you already worked out.

Do **not** build a tool for a true one-off. That stays in your shell history or the scratchpad. `tools/` is for scripts that earn their keep by running more than once.

## Steps

1. **Name the single purpose.** One sentence, one verb. If it needs an "and", that is two tools.
2. **Write it to the `tools/` contract** in `tools/CONVENTIONS.md`: `--help`/`-h`, meaningful exit codes, non-interactive, cwd-safe (resolve paths from the script location), stdin for large payloads, no secrets in argv.
3. **Pick the shells.** Author the POSIX `.sh` (the baseline: night-run bash loop, CI, Git Bash). Add a `.ps1` twin **only when the tool must run in the user's PowerShell shell** as an interactive path; the twin mirrors the `.sh` flags, stdin shape, and exit codes exactly. Give any `.sh` LF line endings.
4. **Prefer delegating over reimplementing.** If a vetted helper already does the hard part (a `.mjs`, a `gh` call), the tool is a thin wrapper over it. Do not re-derive its logic in shell.
5. **Catalog it.** Add a row to `tools/README.md` (tool, what it does, usage) in the same change.
6. **Point to it from `CLAUDE.md` only if broadly useful** across the workflow. A niche tool just lives in the `tools/` catalog.
7. **Prove it.** Run `--help` in each shell you shipped (exit 0) and one real smoke of the happy path. Fix the cause of any failure; do not paper over it.

## Guardrails

- **No premature abstraction (rule 6).** Do not build a shared shell library for the first two small wrappers. Extract on the third real use.
- **stdin over argv** for a claim, a diff, a file list, or any large payload.
- **No secrets in argv** (process table + shell history leak them). Read them from the environment or a file.
- **One purpose per script.** A flag matrix that forks behavior is a sign you are hiding two tools in one file.
1 change: 1 addition & 0 deletions .claude/skills/pr-review/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ In parallel:
- `C:\Users\thoma\Documents\Programming\Projects\orbit-api\CLAUDE.md` (root + scoped
project `CLAUDE.md`) — only if the diff touches backend.
- `DESIGN.md` — only if the diff touches `apps/*` UI files.
- `TESTING.md` - the suite catalog and test-writing conventions; consult it for suite semantics when the diff touches tests.
- The plan in `.claude/plans/completed/` if the PR body references one.
- **`.claude/skills/pr-review/rubric.md`** — the dimensions, severities, and finding
template this review walks.
Expand Down
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
packages/shared/src/types/__generated__/*.generated.ts text eol=lf
.claude/workflows/*.mjs text eol=lf
.claude/skills/**/*.mjs text eol=lf
tools/*.sh text eol=lf
18 changes: 17 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,26 @@ Auth: web cookie is httpOnly + sameSite strict + secure; mobile tokens live in S
- Never create an `AGENTS.md` — opencode reads this CLAUDE.md natively; an AGENTS.md would shadow it.
- `.opencode/agents/*.md` are thin pointers to the `.claude/agents/*.md` bodies — when adding an agent, create BOTH. Hooks and memory are Claude-Code-only machinery (inert under opencode).
- C# LSP for orbit-api is wired via `.mcp.json` — the Roslyn-backed CWM.RoslynNavigator MCP server (install once: `dotnet tool install -g CWM.RoslynNavigator`) pointed at orbit-api's `Orbit.slnx`; copy from `.claude/mcp.json.example`.
- Reusable agent scripts live in `tools/` (`agent-review`, the merge-sweep scripts) under the `tools/CONVENTIONS.md` contract; build a new one with `/make-tool` once you have run the same incantation twice; a one-off stays in the scratchpad.
- Git: one feature/fix per PR (cross-repo work opens paired PRs, cross-linked); branches `feature/`|`fix/`|`chore/`; `main` is protected (no direct or force push — enforced by the `git-guardrails` hook); squash-merge only; never `--no-verify`/`--no-gpg-sign`; never reuse a squash-merged branch.
- Testing: Vitest unit tests only; every feature needs behavior tests. The only sanctioned E2E is the post-deploy web smoke suite. Configs live in each workspace.
- Testing: Vitest unit tests only; every feature needs behavior tests. The only sanctioned E2E is the post-deploy web smoke suite. Configs live in each workspace. `TESTING.md` (repo root) is the suite catalog + how to write a test here.
- `/pr-review` is the canonical local diff review (orchestrates security-reviewer / contract-aligner / parity-checker / i18n-syncer + the backward-compat guard).

## Docs registry

Grep a doc's `At a glance` header before loading the whole file.

| Doc | Purpose |
|---|---|
| `DESIGN.md` | Authoritative UI spec: navy-violet anchor, semantic tokens, 412px shell. |
| `FEATURES.md` | Code-derived, gating- and platform-aware map of every capability. |
| `WORKFLOW.md` | Path-picking guide (tiny bug / real bug / medium feature / multi-issue). |
| `TESTING.md` | How to write tests here + the catalog of every suite and what each proves. |
| `research.md` | Agentic-harness research + the locked harness design decisions. |
| `.claude/research/*` | Deep-research dossiers behind the harness (memory model, env overhaul, opencode/GLM, upgrade plan). |

When you change a doc, update its `At a glance` header and this registry in the same edit.

## Path-picking & delegation

`WORKFLOW.md` (repo root) is the path-picking guide (tiny bug / real bug / medium feature / multi-issue) — read it before non-trivial work. Delegate independent/heavy work by default (3 concurrent cap; `Explore` for audits; paired worktrees for multi-issue).
7 changes: 7 additions & 0 deletions DESIGN.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Orbit Design System

> **At a glance** - the authoritative spec for every Orbit UI surface; it overrides generic and user-global design defaults.
> - Anchor (locked): navy-violet orbital - slate-950 canvas, violet-500 accent, violet gradient headers, pill CTAs, deliberate emoji.
> - Semantic tokens only (`--bg`, `--bg-elev`, `--fg-1..4`, `--primary`, `--primary-rgb`, `--gradient-header`, ...); no raw hex in UI.
> - Ships light AND dark, all 6 color schemes; mobile-first 412px shell.
> - Source of truth is the vendored handoff at `design/handoff/`; tokens live in `apps/web/app/globals.css` + `apps/mobile/lib/theme.ts` + `packages/shared/src/theme/`.
> - Read the whole doc before shaping, reviewing, or theming any surface.

Source of truth: the vendored handoff at `design/handoff/` (see its README for the canon table). This document is the distilled, authoritative spec. The token values live in `design/handoff/orbit/project/orbit-fig.css`; the primitive dimensions in `orbit-kit.jsx`; the screen compositions in the artboards of `Orbit App - Figma.html`.

**Authority note:** this DESIGN.md is authoritative over any generic or user-global design defaults — including the global anti-Inter and anti-violet rules. The handoff adopts Inter for display type and a violet accent deliberately; that deviation is documented here once and applies repo-wide. Deliberate emoji use (habit emojis, stat tiles, streak flame, celebrations) is part of the language and overrides the global anti-emoji rule for UI surfaces where the artboards show them.
Expand Down
7 changes: 7 additions & 0 deletions FEATURES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Orbit — Feature Inventory

> **At a glance** - the single code-derived, gating- and platform-aware map of every Orbit capability.
> - Downstream copy (Play listing, landing page, QA matrix) derives its rows from here, so nothing is undersold.
> - Gating: Free / Trial (7-day, full Pro except Retrospective) / Pro / Yearly-Pro, computed from `User` flags in `PayGateService.cs`.
> - Free limits: 10 top-level habits and 20 AI messages/month; Both = web + mobile (Expo, Android-only), with no iOS app.
> - Headline surfaces: Astra (61 AI tools), the MCP server (79 tools / 15 classes), the opt-in social layer, the core tracker.
> - Read the whole doc before writing store, marketing, or QA copy.

The single, code-derived, gating- and platform-aware map of everything Orbit does. Downstream copy — the Play listing, the landing page, the store description, and the pre-launch QA matrix — derives its rows from here, so no feature is undersold or invisible and nothing needs feature archaeology.

**How to read this doc.** Every capability lives in a per-domain table with five columns: **Feature**, **Description** (one line), **Gating**, **Platform**, and **Locale notes**. Astra and MCP are listed at feature/category granularity with tool counts, not one row per tool.
Expand Down
Loading
Loading