* insforge-debug: diagnose incident as the fast path for 504/down triage
The 504-across-paths recipe and the error-objects routing table now
lead with `diagnose incident` (CLI #228 + cloud-backend #814): the
report is built from platform-side sources, so it answers while the
instance is down or wedged — exactly when postgres.logs stops working.
The manual crash-recovery confirmation stays as the fallback for older
CLI/backend and --api-key link mode.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kbhm3x6R6B4vy5Z2H8mKb
* review round 1: diagnostics.md entry + availability caveat on routing rows
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kbhm3x6R6B4vy5Z2H8mKb
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* docs(compute): drop stale private-preview banner, fix scale-to-zero claim
Compute is GA — the CLI and public docs carry no preview gating, so the
banner only misled agents reading the skill.
The FAQ claimed v1 services scale to zero when idle. They don't: the
generated deploy config sets auto_stop_machines = false, so services run
until `compute stop` or process exit. Reworded the answer to match the
actual behavior and point at the fly.toml opt-in for source mode.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JzV7Bj3NBdQBrwYoRtLWYw
* docs(compute): frame idle behavior as deploy-time choice (always-on default vs opt-in scale-to-zero)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JzV7Bj3NBdQBrwYoRtLWYw
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* insforge-debug: 504-across-paths → OOM triage with upgrade path
The gateway-timeout recipe routed by URL subsystem but never named the
most common real cause on small instances: an OOM-killed Postgres turns
every in-flight request into a gateway timeout while crash recovery
runs. Add the OOM-first branch — confirm via the crash-recovery
aftermath in postgres.logs, then upgrade the instance
(projects upgrade-instance / dashboard Compute & Disk; paid plan first
on free) — and note the resize itself restarts the project, since no
separate user-facing restart exists and a bare restart only buys
minutes. metrics.md gains the matching 5xx-burst escalation signal.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kbhm3x6R6B4vy5Z2H8mKb
* review round 1: note the resize is async — poll projects get until operation_status clears
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kbhm3x6R6B4vy5Z2H8mKb
* external review: cross-link OOM branch from error-objects 5xx routing, require time correlation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kbhm3x6R6B4vy5Z2H8mKb
* review round 3: upgrade-instance confirm prompt note for unattended runs
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kbhm3x6R6B4vy5Z2H8mKb
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
- "every other CLI command targets the local backend" was wrong. `whoami`,
`list`, `orgs`, `billing`, `usage`, and `create` call the platform API whether
or not a directory is linked to a local instance, and still need an account.
Named both sets instead.
- "no account" is a constraint someone states, not a request for Docker. An
agent reading it as a trigger starts containers on a user who was only
grumbling about signup. Removed from the trigger list, with a note to ask.
- Common Mistakes offered `create` as a remedy for a failed login. It calls the
platform API, so it needs the authentication that just failed. Removed.
- The secret boundary for `.insforge/checkout/.env` was undefined. `local start`
writes `.insforge/.gitignore` covering `checkout/`, so `git add -A` cannot
commit it — said so, and that printing the file still leaks it.
Command classification verified against the source, and six of the seven
project-scoped ones were run against a local instance during release testing.
- "offline" was listed as a trigger, and the same file says a first start fetches
the setup script and pulls images. Only later starts of an existing instance
run without network; the trigger now says so instead of contradicting itself.
- Added a Credentials section. `.env.local` carries the API URL and the anon key
only — browser-safe, and what the app should read. `local start --json` carries
the API key, the admin password, and a databaseUrl holding the Postgres
password, which should not reach CI output or a committed file. `local status
--json` withholds all of it unless --show-keys.
- `--json` is a global option, not one of these commands' flags. Saying so beats
listing it under `local start`, which would imply the other two lack it.
- Moved the negative guidance into `## Common Mistakes`, the heading nine other
references already use.
Not taking the "use Setup / Usage Examples / Best Practices / Common Mistakes"
structure two reviewers asked for: that line in AGENTS.md sits under "Updating
Existing Documentation" and means keep the format of the file you are editing.
The corpus has no single structure — Syntax appears 10 times, Options 9, Common
Mistakes 9, Examples 7. Adopted the one heading that is actually conventional.
A reference of its own rather than a section in SKILL.md: read only when the user
asks for a backend on their own machine, so it costs nothing the rest of the time
and does not sit among the cloud capabilities as if it were one of them.
The main file gains one routing row and one sentence in Connection Setup, both
saying the same thing — a cloud project is the default, and `local` is never a
fallback for a login or `create` that is being inconvenient. Starting a local
instance to work around an auth problem moves the user onto a different backend
with different data, quietly.
The reference also states that self-hosting is deploy/setup.sh, not this. Local
start is a development backend: loopback ports, :latest images, one instance per
directory.
- Note realtime is channel pub/sub: pair subscriptions with a DB trigger
calling realtime.publish(); link insforge-cli realtime backend reference
- Poll probe now count:'exact' + newest updated_at so inserts/deletes and
edits are all detected (with system.update_updated_at() trigger note)
- Bounded select() example gains stable .order() so copied lists don't
shift between refreshes
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XHt48PzmxME9RgimRuoUqS
Agents following the skill verbatim write select() with no columns and no
limit, then wire it to a refresh interval; on real projects this shape
re-downloads whole tables continuously (~1 GB/day per open dashboard) and
is the top cause of free-tier egress exhaustion.
- Lead Select example now names columns; unbounded select() reframed as
detail-view-only with .limit() on lists
- New 'Bandwidth-efficient reads' section: realtime over polling, cheap
change probes, bounded lists, column selection, visibility-aware
refresh timers, cacheable storage URLs
- SKILL.md Important Notes pointer so the rule surfaces at skill level
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XHt48PzmxME9RgimRuoUqS
John-bot's suggestions, both taken: OOM evidence has no dedicated log
source — the observable signal is the Postgres crash-recovery aftermath in
postgres.logs ('terminating connection because of crash of another server
process' / 'automatic recovery in progress'), so the triage now names those
strings. And the upgrade destination is Project Settings → Compute & Disk,
matching the actual dialog (companion PR InsForge/InsForge#1890).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kbhm3x6R6B4vy5Z2H8mKb
Agents keep fielding 'my idle database sits at ~78% memory' as a leak. Teach
the healthy-steady-state read (Postgres turns idle RAM into shared buffers
and page cache), the real pressure evidence (OOM kills/restarts in logs,
rising 24h/7d trend, degrading performance), and the remedy: upgrade to a
paid plan + larger instance size; never restart to 'free' memory. New recipe
in SKILL.md routes the symptom; metrics.md carries the full rule.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kbhm3x6R6B4vy5Z2H8mKb
- document the self-hosted link flow (link --api-base-url --api-key) that the
backups section referenced but nothing defined
- split the backups restore blast radius by backend: cloud overwrites database
and storage, self-hosted is database-only pg_restore --clean
- name the exact poll fields for advisor scan (scan.status / scan.scanId,
verified against the live --json output)
- broaden the advisor routing entry beyond false positives
Not changed: version-pinning npx examples and removing <id>/a|b|c placeholder
syntax (both contradict the file's established conventions).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bare `npx <pkg>` asks "Need to install the following packages / Ok to
proceed?" before installing into the npx cache. npm only skips that
prompt when stdin is not a TTY or CI is detected (libnpmexec checks
`!process.stdin.isTTY || ciInfo.isCI`), so any pty-attached agent shell
or terminal session blocks on it with nobody there to answer. It also
recurs after a version bump, since the unpinned spec resolves to latest
and a stale cache entry no longer satisfies it.
`-y` pre-answers that prompt. Applied to every documented invocation:
- 455 `npx @insforge/cli` -> `npx -y @insforge/cli` across 57 files
- `npx @better-auth/cli migrate` (agent-run) in insforge-integrations
- `npx skills add` in README
`references/create.md` keeps its bare `npx skills add`, which documents
what the CLI spawns internally rather than a command the reader runs.
npx's `-y` is distinct from the CLI's own `-y`/`--yes`, so both can
appear in one line: `npx -y @insforge/cli link --project-id <id> -y`.
Noted that in the Global Options table, and recorded the rationale on
the core rule so the flag is not dropped as noise later.
Addresses user feedback 4070cc9c-2cdd-4b22-8a01-b4d95e6e1e9f (cli):
Branch create prompts in non-interactive execution
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The advisor is where pg_stat_statements actually lives: its
performance/slow-query rule (insforge-cloud-backend
src/services/advisor/rules/performance.rules.ts:52) reads it via
collectors/postgres.collector.ts:109 and emits the query text with
mean/total exec time and call counts.
Two corrections to the routing added in 30ae81a:
- Add --json. description and recommendation, which carry the query
text, are only emitted with --json; without it the table truncates
to the 100-char affectedObject column, so the pointer as written
didn't deliver what it promised.
- Replace "logs or advisor" with the actual split. They are not
interchangeable: the advisor carries aggregates with no
per-occurrence timestamp, so postgres.logs remains the only way to
correlate a query with a specific incident.
Also note the rule is silently skipped when the pg_stat_statements
extension isn't installed, so that route can come back empty for a
different reason than the one this doc already covers.
Shortens the SKILL.md recipe step back to the one-line form the file's
own preamble specifies.
'facts, decisions, and gotchas' reads like an enum listing because the
first two words are real --kind values. Enumerate the four real kinds
instead, and keep one explicit guard note that there is no gotcha kind.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The rehearsal pattern rolls back by raising, so the command always exits
1 and writes to stderr on both the pass and the fail path. The previous
wording ("once the rehearsal output looks correct") read as if success
were normal output, which invites treating the expected non-zero exit as
a failure and retrying.
Add a callout plus a table mapping the two stderr messages to their
meaning, note the --json shape, and key the apply step off the
"rehearsal ok:" message instead of "output looks correct".
Address review feedback on the email OTP docs:
- Note the minimum SDK version (@insforge/sdk 1.5.1+, the release that ships
signInWithOtp/verifyOtp) — the version reviewers cited (1.2.1) was the
shared-schemas version and was never a published SDK release.
- Clarify the retry guidance: a wrong entry can be retried with the same code;
request a fresh code only after expiry or the third failed attempt (was
ambiguous "on failure").
- State the disableSignup caveat: unknown emails are only auto-created when
signups are enabled; otherwise verifyOtp rejects them with 403.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Covers the passwordless email OTP flow now in the SDK (@insforge/sdk 1.2.1+):
- sdk-integration.md: new "Passwordless Sign In (Email OTP)" section with
signInWithOtp() + verifyOtp(), including the enumeration-safe send response,
first-time name handling, and the 5-min / single-use / 3-attempt limits.
- ssr-integration.md: include email OTP sign-in in the createAuthActions()
server-mutation surface.
- SKILL.md: add signInWithOtp() / verifyOtp() to the auth quick reference.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
db-health.md claimed the slow-queries check reads pg_stat_statements
(historical exec-time stats), but the CLI queries pg_stat_activity for
queries currently running >5s. Agents following the doc expected
historical results and got empty output despite postgres.logs showing
slow queries. Correct the checks table, how-to-read row, boundaries,
and example, and route historical slow-query analysis to postgres.logs
and diagnose advisor in both db-health.md and the SKILL.md recipe.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Important Notes bullet stated the invoke URL is /functions/{slug}
unconditionally, but the active function2 runtime serves the deployed
slug at root /{slug} on the functions deployment host; /functions/{slug}
there returns 404 Function not found. Only the project base URL keeps
the backward-compat /functions/{slug} proxy.
Recommend insforge.functions.invoke(slug) (SDK owns route construction)
and document both raw-HTTP routes explicitly.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The branch overview claimed provisioning takes 30–120 s, leading users to
report schema-only branches stuck in 'creating' after a few minutes as a
bug. Provisioning typically takes 2–5 minutes and can run longer; the CLI
polls for up to 15 minutes before failing. Update both claims in
skills/insforge-cli/references/branch/overview.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
db query rejects BEGIN/COMMIT/ROLLBACK/SAVEPOINT with 'Transaction control
statements are not allowed.' but the query reference never mentioned it,
leaving no supported path for a guarded dry-run/restore rehearsal.
Add a Restrictions section to references/database/query.md that documents
the rejection (mirroring the migrations.md wording) and a single-statement
DO $$ ... $$ rehearsal example that mutates, validates, and ends with
RAISE EXCEPTION so PostgreSQL rolls the statement back.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>