* docs(email,auth): clarify built-in email needs no SMTP / third-party packages
Agents have been scaffolding nodemailer / resend / sendgrid and asking
users for SMTP credentials, even though the InsForge platform ships a
built-in email service that works on every paid project out of the box
(EmailService.resolveProvider() falls back to CloudEmailProvider with no
SMTP env vars). A 2026-05-13 production scan found 17+ user projects had
RESEND_API_KEY set as a secret.
The skill already documents emails.send and lists the SES sender domain,
but the "no SMTP needed / don't install a third-party package" guardrail
was nowhere in the agent-discoverable surfaces. This patch adds it at
three layers so agents hit it regardless of which file they read first:
- skills/insforge/SKILL.md (Important Notes — surfaces before drilling
into the module file)
- skills/insforge/email/sdk-integration.md (top-of-file stop callout +
Common Mistakes entry)
- skills/insforge/auth/sdk-integration.md (auth emails — signup
verification, password reset, magic links, invites — also need no
SMTP setup; agents should not scaffold third-party packages here
either)
No code changes, 3 files, +7 / -1.
* fix: address review + tighten callouts for agent skim
- SKILL.md: split free/paid scoping (greptile P1) — auth emails ship on
every plan, only insforge.emails.send() is paid-only. Previous wording
"every paid project" wrongly implied agents must wire SMTP for auth on
free tier, exactly the anti-pattern this PR is preventing.
- auth/sdk-integration.md: add `postmark` to banned list (greptile P2);
previously inconsistent with the other two files.
- email/sdk-integration.md: collapse the MD028 blank quoted line into a
`>` separator (coderabbit).
All three callouts also tightened — lead with the rule, drop redundant
phrasing ("no SMTP setup, no API key, no SMTP_HOST env var, no
Resend/SendGrid account" → "no SMTP, no API keys"), agents will skim
not read.
---------
Co-authored-by: Gary <gary@insforge.dev>
* feat(skills): document insforge.toml config-as-code flow
Adds guidance for the new `npx @insforge/cli config export/plan/apply`
commands that ship with CLI #109 and backend #1216:
skills/insforge-cli/SKILL.md
- New "Configuration" command section listing export/plan/apply
- Calls out version-aware capability gating: supported sections apply,
unsupported go to skipped[] with an upgrade message; no PUT issued
for unsupported sections
- "TOML is for knobs only — never embed programs" rule with pointers
to the dedicated commands for SQL / functions / compute / frontend
- "Surface skipped[] verbatim" rule with sample agent message
- env(NAME) reference convention for sensitive fields (forward-looking;
CLI side ships with secrets-validation PR #110)
skills/insforge/auth/backend-configuration.md
- Recommends config apply over direct PUT /api/auth/config when
changing settings-page knobs
- Keeps PUT documented for the "flip one boolean from function code"
case
Both files reference behaviors not yet shipped on @insforge/cli@latest.
Hold this PR until CLI #109 and backend #1216 land so agents don't see
docs for commands they can't run.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(skills): remove auth/backend-configuration.md
The file mixed admin HTTP endpoint reference (PUT /api/auth/config,
List/Delete Users, Anon Token) with SDK-side discovery guidance.
That violated the parent skill's own scoping ("client-side @insforge/sdk
integration; for backend infrastructure, use the insforge-cli skill").
With config-as-code landing (CLI #109), auth backend config is now a
CLI workflow, not an HTTP-only escape hatch:
- Read settings: `npx @insforge/cli metadata --json`
- Change settings: `npx @insforge/cli config apply`
The SDK-relevant guidance (best practices, common mistakes, OAuth
provider checks, verification flow branching) was already duplicated in
auth/sdk-integration.md, so deleting the file loses nothing the SDK
developer needs. The few admin-only endpoints (List/Delete Users) are
better served as future CLI commands than as docs in the SDK skill.
Updated:
- skills/insforge/SKILL.md: drop the Auth row from the
"Backend Configuration (Not Yet in CLI)" table; add a pointer to
the new CLI Configuration section
- skills/insforge/auth/sdk-integration.md: replace two stale links to
backend-configuration.md with the corresponding CLI commands
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(insforge-cli): tighten config section and add references/config.md
Restructured the new Configuration content to match the conventions
the rest of the skill follows:
- Inline section in SKILL.md is now a tight command list + the three
load-bearing rules (TOML for knobs only, surface skipped[] verbatim,
env() refs for secrets), with a pointer to the deeper reference
- New references/config.md covers: typical end-to-end flow, output
shapes for export/plan/apply --json, partial-apply semantics, file
location, sensitive-field handling, --json consent rule, and a
common-mistakes table
- New "Configure project settings (insforge.toml)" entry under
Common Workflows so agents discover the flow from the workflow index
- New Non-Obvious Behavior bullet explaining the per-project version
drift and why direct API calls are unsafe
- Frontmatter description updated to mention insforge.toml as one of
the things this skill covers, so the trigger surface is right
Bumped skill version 1.4.0 → 1.5.0.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(insforge-cli): trim config docs to ship-only scope
Skill previously described forward-looking surface (SMTP example with
env(SMTP_PASSWORD), `ConfigValidationError` for sensitive-literal
rejection, password policy / OAuth providers / custom subdomain via
TOML). None of that ships in CLI #109 — only `auth.allowed_redirect_urls`
is wired in src/lib/config-schema.ts.
Trim to match reality:
- Narrow Configuration section to the one supported field
- Drop `env(NAME)` callout in SKILL.md (validation not implemented)
- Drop SMTP example block + sensitive-field section in references/
- Add explicit "Scope today" line + "Coming soon" stub for forward path
- Tighten cross-refs in insforge/SKILL.md and auth/sdk-integration.md
so they don't imply password-policy / OAuth providers are TOML-managed
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(compute): document scale-to-zero default and Fly.io mapping
Compute services now deploy with Fly's full scale-to-zero
(auto_stop_machines: stop, auto_start_machines: true,
min_machines_running: 0) — see InsForge/InsForge#1251.
Document this in the skill so agents:
- Know scale-to-zero is the default behavior
- Set the right cold-start expectation (~1s on shared-1x)
- Understand the CLI/skill can only dial it *up* toward always-on,
never below zero (it's already the floor on Fly)
- Map InsForge's behavior to Fly's exact field names so users
familiar with Fly can predict what they're getting
- Know that pre-existing services need a redeploy to pick up the
new defaults
Also notes that flags for `auto_stop_machines: off|suspend` and
`min_machines_running > 0` aren't yet exposed via the CLI —
route latency-critical services through support for now.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs: use Machines API field names (autostop/autostart)
The first draft documented the fly.toml field names
(`auto_stop_machines` / `auto_start_machines`). Companion fix in
InsForge/InsForge#1251 corrected the backend to send the Machines API
short names — `autostop` / `autostart` — because that's what the
`POST api.machines.dev/v1/apps/<app>/machines` body actually accepts
(`auto_*_machines` are silently ignored).
Rewrites the scale-to-zero section to:
- Show the body InsForge actually sends (short names)
- Cross-reference both spellings in one table so users coming from
fly.toml docs and users debugging via `flyctl machines list --json`
both see what they expect
- Note that `min_machines_running` is honored only in the app's
primary region
Authoritative schema reference: fly.MachineService in
https://docs.machines.dev/spec/openapi3.json
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs: commit to scale-to-zero as v1's only mode
Earlier draft hedged with "not yet exposed via the CLI" language for
autostop/min_machines override flags. Decision: don't build those for
v1. One mode, less surface area, simpler support story.
Rewrites both files to be explicit:
- "v1 is the only mode" — every service is scale-to-zero, no flags
- Removes the "What the CLI/skill can change" matrix that implied
flags were coming. Replaced with a short "Why no override flags"
paragraph explaining the tradeoff and the support escape hatch.
- Adds a direct instruction for agents: don't ask "set autostop to
off" or "keep N warm" — there's no flag, nothing the skill can
do, route to support instead. Prevents the agent from invoking
imaginary flags and confusing the user.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(skills): trim per writing-skills — drop content with no agent action
Compute scale-to-zero (v1):
- Drop the 33-line dedicated section in compute-deploy.md (fly.toml vs Machines
API field-name table, "Why no override flags", "Already-deployed services")
— v1 has one mode with zero flags, so there's no agent decision to support.
Replace with one FAQ line for agents debugging cold-start questions.
- Drop the SKILL.md callout paragraph for the same reason.
Config:
- Trim references/config.md from 898 to 335 words. Remove "Why this exists",
the TOML-is-for-knobs table, "Handling skipped[]" prose, and "Coming soon"
— all duplicate principles already loaded by SKILL.md's Configuration section.
Keep what's unique to the reference: output shapes for --json mode, file
location, and the common-mistakes table.
Net: -105 / +11 lines.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(config): clarify -y/--yes vs --auto-approve alias
REFACTOR pass from writing-skills TDD test. GREEN subagent flagged the
relationship between the global -y/--yes flag and the subcommand-local
--auto-approve as ambiguous. Single-row tweak in the common-mistakes
table: name which is global, which is the subcommand alias, and that
they have the same effect.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`compute update <id>` requires a pre-existing service id, which a freshly-
created (or first-switched-to) branch does not have — its runtime starts
empty. Switch the recommendation to `compute deploy` (which creates the
service), and rephrase the create-section bullet from "Redeploy / Re-run"
to "Deploy / Run" since on the branch's runtime this is the first deploy,
not a re-deploy. Same fix applied to the parallel switch-section reminder.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`pg_dump` copies `functions.definitions` rows but not the Deno Subhosting
bundles / Vercel / Fly.io state, so a freshly-created (or first-switched-to)
branch's runtime starts empty. Calls fail with `getaddrinfo ENOTFOUND deno`
or `Deployment not found` until each piece is redeployed against the new
backend. Surface this in branch.md (`create` + `switch` sections) and the
typical-flow snippet in SKILL.md so agents don't waste a debug loop.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add a dedicated `## Availability` section to references/posthog.md and
expand the SKILL.md callout to a three-line block (feature + 404
failure mode + supported frameworks), matching the structure used for
payments. Tells agents what to do when the rollout hasn't reached the
project, and warns against working around the gap by pulling a phc_
key from a separate PostHog account.
Address review feedback: replace bare `insforge ...` with
`npx @insforge/cli ...` per the skill's "no global install" rule.
Title also normalized to `# npx @insforge/cli posthog setup` to match
other reference files (login.md, db-query.md, payments.md, etc.).
Drop the Related link pointing to insforge-integrations/posthog.md —
that file doesn't exist on main.
Adds a new "Analytics Integration" command section to the InsForge CLI
skill, with a dedicated reference covering the templated SDK install
flow: framework auto-detection, per-framework templates (Next.js App/
Pages Router, Vite + React, SvelteKit, Astro), env var writes, and
the layout.tsx hand-off note.
Bumps insforge-cli skill to 1.4.0.
Templates moved BA's tables to a dedicated `better_auth` schema
(insforge-templates#28). The doc was still teaching the old
public+REVOKE model; sync it.
Removed:
- Entire "Lock down PostgREST exposure (REQUIRED)" section (15 lines).
- "DATABASE_URL must keep superuser-grade privileges" callout — no
more REVOKE means no risk of a tightened DATABASE_URL silently
breaking sign-up.
- Organization plugin REVOKE block (5-line SQL + verify curl text).
- Plugin REVOKE template table — every plugin's tables inherit
`search_path=better_auth` automatically.
- Two Common Mistakes rows: "Skipping the REVOKE block" and
"Connecting BA as anon/authenticated after REVOKE" — both no
longer applicable.
Replaced with:
- Three-line schema-layout intro at the top of the guide showing
auth.* / better_auth.* / public.* ownership.
- "Schema setup + first migrate" subsection with `CREATE SCHEMA`
one-liner + a callout explaining why this is sufficient (PostgREST
exposes only `public` by default; dashboard reaches `better_auth`
through the admin route's postgres superuser pool).
- New `lib/auth.ts` example with `pool.on('connect')` setting
`search_path TO better_auth, public` — the canonical pg method
per BA's own docs since pg.Pool doesn't take a schema option.
- New Common Mistakes rows: forgetting `CREATE SCHEMA` before
migrate; FK'ing without schema qualification.
Updated:
- Manual-integration numbered workflow: drop the REVOKE step,
insert the CREATE SCHEMA step.
- FK example in the database-setup section: `REFERENCES public."user"(id)`
→ `REFERENCES better_auth."user"(id)`.
- "FK to BA users" section: prescribed FK is now `better_auth.user(id)`
(not `public.user(id)`).
- Plugin section's "rule of thumb": `\dt better_auth.*` (not `public.*`).
- All REVOKE-template SQL in plugin sections — gone.
Net change: 96 lines edited (48 insertions, 48 deletions). Word count
4260 → 4482 (+5%) because the explanatory schema-layout + new Common
Mistakes rows are slightly longer than the dropped sections; acceptable
for the clarity gain.
Verified end-to-end against current insforge main (v2.1.0) via
insforge-templates#28's branch — see that PR for the test matrix.
Ran the writing-skills TDD methodology against the BA integration guide:
dispatched a baseline subagent to do the integration with no doc access
(RED), then a second subagent reading the doc (GREEN). Compared their
outputs to identify what the doc teaches well vs where it has gaps.
The doc PASSED retrieval testing — the GREEN agent produced correct
bridge route, REVOKE matrix, and requesting_user_id() helper just by
reading the relevant sections. But three real issues surfaced:
1. Hono bridge example contradicted the Next bridge on PII. The Next
route's comment says "Don't add email or other PII"; the Hono one
inlined `email: session.user.email` 400 lines later. GREEN agent
flagged this as an internal contradiction. Removed the email claim,
added a back-reference to the Next route's no-PII comment, and
added the same `Cache-Control: no-store` header for parity.
2. The "DATABASE_URL must keep superuser-grade privileges" warning was
buried in the Common Mistakes table near the bottom. Promoted it
into a callout immediately under the REVOKE block, where the foot-
gun actually fires (a user who tightens DATABASE_URL to the
`authenticated` role after the REVOKE silently breaks BA sign-up).
3. The doc taught `requireEnv()` as the canonical pattern at lines
60-66 but used `process.env.X!` 12 times after on the SERVER side
— internal inconsistency a junior copy-paster would inherit.
Standardized server-side reads on `requireEnv`. Kept `!` for
`NEXT_PUBLIC_*` (those are bundler-inlined; a module-load check
would just fire in the browser anyway) and added a one-line
comment near the requireEnv definition explaining the asymmetry.
Also tightened `skills/insforge-integrations/SKILL.md` description:
dropped the workflow-summary tail ("Covers provider-specific dashboard
setup, client/server code…") since per writing-skills CSO guidance, a
description that summarizes the body trains Claude to read the
description and skip the actual content. The description now states
only when to use the skill.
The Vite/React skeleton was demonstrating the same Vite-proxy +
Origin-rewrite pattern that's already documented in prose with full
code blocks (the "Vite / React-only setups" section, ~109 lines
including a complete vite.config.ts and Hono bridge route).
Same drift logic that retired examples/better-auth-nextjs: no
CLI/CI keeps the example accurate, every @insforge/sdk or BA bump
risks a stale snippet. The doc IS the canonical reference.
If a real "clone-and-run" Vite story becomes worth the maintenance,
ship it through the CLI: a `vite` base template + the existing
better-auth overlay, same model as nextjs.
PR #44 is now 2 files: the SKILL.md edit and the integration guide.
The Next skeleton was duplicating what `insforge create --auth
better-auth` (CLI #98) and the templates repo's auth-providers/
better-auth/ overlay produce. We just had drift between the two
copies — the project_admin REVOKE fix had to land twice — so the
duplication is real maintenance cost.
Drop the Next skeleton entirely; point the doc at the CLI command
instead. Vite/React skeleton stays — the CLI doesn't scaffold React
yet, so it's still the canonical reference for that pattern.
Reduces this PR from 33 files to 13.
The dashboard's record browser switched from /database/records (PostgREST
passthrough, runs as the project_admin Postgres role) to
/database/admin/tables/.../records (backend AdminRecordService → postgres
superuser pool). Studio inspection is now role-independent, so the
"REVOKE from project_admin only if you want full lockdown" caveat was
misleading — there's no trade-off, just REVOKE from it.
Updated the core REVOKE block, the Organization plugin block, and the
plugin REVOKE-template table.