Skip to main content

Auto-Generate bypass

The contract for what happens inside the Builder when a user lands there via the seeded onboarding flow. Aimed at integrators and operators who need to reason about the three calls the seeded Builder makes on its own, the intent flag that lets them succeed against a not-ready scope, and the boundary that keeps every other gate intact. The reference shapes live in the API reference; this page is the prose that ties them together.

Why this page exists

If you have followed Ethos onboarding up to the moment the Builder opens pre-seeded, this page picks up there. The seeded Builder does not wait for the user to click Generate — it runs Analyze, then materializes a request-scoped short-term memory, then runs Propose, all without manual intervention, so the user sees a draft enriched by the chosen seed rather than the raw seed body verbatim.

Three endpoints, one literal, one bypass, one window-closure event. The literal ("onboarding") is the same one used by PUT /api/session-scope during the no-Ethos scope handshake — the Intents table on the onboarding guide is the canonical reference for what the literal means and which endpoints accept it.

The auto-Generate chain

On landing in the seeded Builder, the client runs three calls without asking the user to click anything. Each carries intent: "onboarding" in its request body (or, for Analyze, as a multipart form field):

  1. POST /api/gnosis/analyze — computes validation and recommendations from the seed body. See the multipart form schema in the API reference (find POST /api/gnosis/analyze in the sidebar).
  2. POST /api/memory/short-term — materializes a request-scoped STM record holding the seed body and surrounding context. See the request body schema in the API reference under POST /api/memory/short-term.
  3. POST /api/gnosis/propose — runs Propose against the STM and returns a draft (proposal_markdown) enriched by the seed. See the request body schema under POST /api/gnosis/propose.

The Propose path can also create its own STM internally (when the request supplies a scope + inputs without an STM id), in which case the internal POST /api/memory/short-term invocation honors the same intent without needing a separate caller-visible flag.

The resulting draft replaces the raw seed body in the editor. From this point on, the user is in the normal Builder review loop — edit, iterate, save.

The bypass literal — intent="onboarding"

The intent field on each of the three endpoints is the same closed enum used by PUT /api/session-scope. Only the literal "onboarding" is accepted; any other value (including a misspelling like "onboard") returns 400 validation_error. Absence or null preserves the legacy path byte-for-byte — no existing caller is affected by this addition.

When the literal is present, the endpoint relaxes exactly one gate: the project_scope_not_ready refusal that fires when project_has_materialized_ethos(active_slug) returns false. That is the gate that would otherwise block the chain from completing — the user's scope is not-ready precisely because they have no Ethos yet, which is the whole reason they are in onboarding.

For the canonical definition of the literal and the full enumeration of endpoints that accept it, see Intents on the onboarding guide.

What the bypass does NOT do

The intent field is a narrow relaxation of one specific readiness gate. It is not a general-purpose authorization bypass and does not weaken any other axis these endpoints enforce.

  • Authentication. An unauthenticated request returns the same auth error regardless of intent. The literal cannot be used to call the endpoints without a valid session.
  • Capability. The existing capability requirements apply unchanged — builder.use for Analyze and Propose; one of chat.use, builder.use, or notes.use for STM-create. A request without the required capability returns the same 403 forbidden it returns today.
  • Payload validation. Malformed or incomplete payloads return the same validation error regardless of intent. Sending the literal does not make a bad request shape succeed.
  • Scope-selection guards. A project-scoped STM-create whose selected_project_id does not match the actor's active scope returns the same scope_validation_failed error it returns today.
  • Non-project_scope_not_ready readiness causes. If the readiness resolver returns any other code (a future cause such as project_archived, or any composite code where the missing Ethos is not the only unmet condition), the request still refuses with that code. The bypass triggers only on the missing-Ethos cause.

Analyze is an inert hedge today

POST /api/gnosis/analyze does not currently engage the project_scope_not_ready readiness gate — it processes uploaded files into media and does not touch the materialized-Ethos query. Sending intent="onboarding" to Analyze today is a no-op at the gate; the canonical operation timeline records bypass_applied=false for the request.

The field is accepted on Analyze for two reasons. First, the client sends intent uniformly across all three calls of the seeded chain (Analyze → STM-create → Propose); making Analyze reject the literal would force the client to special-case the call. Second, if a future change introduces a readiness gate on Analyze, the field is already in the request surface and will engage the same bypass without a contract change.

Save is not in the bypass set

POST /api/gnosis/save does NOT accept intent. Sending the literal on a save request returns 400 validation_error. This is intentional — the save's own ability to write an Ethos into a not-ready scope is governed by the no-Ethos session-scope path established by PUT /api/session-scope with intent="onboarding", not by a per-call intent on save.

The seeded onboarding chain is therefore three calls, not four — Analyze, STM-create, Propose. Save runs after the user reviews and confirms the draft, and it succeeds for the same scope-recognition reasons the onboarding guide describes.

Window closure

The bypass has no per-actor or per-scope persisted state. Every request that needs the relaxation must carry intent="onboarding" in its own body; the literal is not stored, not echoed in responses, and not inherited by subsequent calls.

The window closes naturally when the Builder save persists an Ethos at the user-selected scope. The next call to GET /api/auth/me/ethos/availability for that scope returns has_ethos=true, and the gate at the heart of the bypass — the project_has_materialized_ethos check — now returns true. The next gnosis call on the same scope succeeds without intent. There is no explicit exit endpoint and no TTL to wait out.

If the user closes the app after generating a draft but before saving, no persistent state changes. The next session starts with the same not-ready scope active (per the onboarding scope binding), the availability CTA re-engages, and the seeded onboarding can be restarted.