auth: internal mint-project-id endpoint (prerequisite for #1485)#1489
Merged
Conversation
…y minting) Adds POST /internal/project/mint-project-id (service-authed): mints a canonical prj_ id without creating an auth-side project, for OS operator/recovery creates with no owning organization. Purely additive — extracted from #1485 so auth deploys ahead of OS consuming it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jonastemplestein
added a commit
that referenced
this pull request
Jun 11, 2026
jonastemplestein
added a commit
that referenced
this pull request
Jun 11, 2026
…tercept dies, kernel shrinks, auth mints, legacy afterAppend deleted (#1485) ## What The remaining grand-cleanup workstreams in one deliberately breaking PR (prd gets redeployed). DECISIONS **D23** is the canonical record. Three main-side PRs landed mid-flight and overlap this work — all adopted wholesale in the merges: **#1482** (repos/workspace/worker as platform defaults with origin-carrying delegation), **#1487** (`fetch` is a shadowable cap, `define` absorbs `provide`, shared registry host), and **#1490** (intercept tunnel deleted, streams is a cap, best-effort `onRpcBroken`). This PR contributes the layers below on top of them. ### §9 finished: the egress pipe is stateless - #1487/#1490 made `fetch` a shadowable platform:project cap and deleted the tunnel, but kept the DEFAULT pipe inside the Project DO (`ProjectEgress.call` → `egressFetch`). This PR replaces that terminal with the stateless **`EgressPipe`** loopback. The Project DO still supervises every dispatch (live shadows resolve in its registry), but egress secrets are D1 rows scoped by the registry-injected `projectId`, so substitution + the real outbound fetch run in a plain isolate and **secret material never enters the DO**. - **The Project DO has no fetch surface at all** — no `fetch`, no `ingressFetch`, no `egressFetch`. ### Worker-loading unification - `itx/isolate.ts` is the ONE place the platform's trust posture (Law 4 ITERATE scoping, Law 5 egress outbound) is wired into loaded isolates; the registry's source caps and the project worker both use it. (The Workers-RPC-safe `onRpcBroken` guard this PR carried shipped independently in #1490 — main's version adopted.) ### `ProjectCapability` dissolved The hand-wired forwarder entrypoint is deleted; nothing called it. ### Auth is the ONLY project-id minter New auth internal route `POST /internal/project/mint-project-id` (service-authed); OS operator/recovery creates (project directory + `itx.projects.create`) round-trip through it. `mintProjectId` is deleted from OS — the `prj_` id space has exactly one source. ### Legacy afterAppend/runner-state deleted The agent, slack-agent, slack-integration, and repo DOs lose their `afterAppend` RPCs and fake runner shapes (delivery has been on the host model for a while). Agent runtime state is now the honest `{ agentPath, processors: { [slug]: snapshot } }`; slack `ensureReady` returns a plain snapshot; the agent-stream benchmark updated. ## Deferred to main's posture (from the original plan) - `project` stays a hardwired built-in (per #1482's kernel choice) rather than a durable-object default; `DIALABLE_DURABLE_OBJECTS` stays empty by default (config-gated). - The egress cap is named `fetch` (per #1487), not `egress`. ##⚠️ Merge order **#1489 must merge (and auth deploy) first** — this PR's create paths round-trip id minting through auth's new `/internal/project/mint-project-id`, and previews point at production auth. The preview e2e here 404s until that endpoint is live. ## Breaking changes (intended) - Agent `runtimeState` shape changed (consumers were shape-agnostic or updated). - `egressFetch` is gone from every surface; use `itx.fetch` / the `egress` cap. ## Testing - Full repo gates green (typecheck, lint, 35/35 apps/os test files). - Workers suites: project-ingress 6/6 (incl. live-shadow + revoke-restores-default), itx-stream-subscribe 13/13. - `project-mcp-server-connection` fails 2/3 **identically on the branch base** (verified in a clean worktree) — pre-existing. - Preview e2e exercises: the egress capability over capnweb (explicit + implicit doors), the new live-shadow helper, and auth-routed minting. ## Out of scope - Egress policy-as-data / hold-for-approval (the §9 follow-on). - Stream processors taking a synchronous SQL client (jam). 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **High Risk** > Breaking egress and secret-handling semantics (DO no longer substitutes secrets; interceptors see raw placeholders), new auth dependency for id minting, and changed agent runtimeState shape affect security-sensitive paths and deploy ordering. > > **Overview** > Completes **itx D23**: project egress is a shadowable **`fetch`** capability whose default terminal is the stateless **`EgressPipe`** (secret substitution + outbound fetch in a plain isolate), while the Project DO only supervises registry dispatch. **`fetch` / `egressFetch` are removed** from the Project DO; **`ProjectCapability`** is deleted. > > Adds **`itx/isolate.ts`** so project workers, source caps, and the run harness share one **ITERATE + `ProjectEgress` globalOutbound** wiring path. > > **Auth is the sole `prj_` minter**: OS drops local **`mintProjectId`**; operator/admin and **`itx.projects.create`** call auth’s **`mintProjectId`** internal route. > > Removes legacy **`afterAppend`** / runner-shaped RPCs on agent, slack, and repo DOs; agent **`runtimeState`** is **`{ agentPath, processors }`** (benchmark updated). Docs mark §8/§9 shipped; live **`fetch`** shadows see **raw** `getSecret(...)` placeholders (withheld-text mode removed). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit df5965b. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- CLOUDFLARE_PREVIEW --> ## Environment Config Lease <!-- CLOUDFLARE_PREVIEW_STATE --> <!-- { "apps": { "os": { "appDisplayName": "OS", "appSlug": "os", "status": "deployed", "updatedAt": "2026-06-11T10:23:48.699Z", "headSha": "df5965b9948016c979fa5a71ae3b991f66e8c42c", "message": null, "publicUrl": "https://os.iterate-preview-6.com", "runUrl": "https://github.com/iterate/iterate/actions/runs/27340067055", "shortSha": "df5965b" } }, "environmentConfigLease": { "dopplerConfig": "preview_6", "leasedUntil": 1781176786363, "leaseId": "9c50031d-b4ce-4f00-a8fe-66a3ff9f9df5", "slug": "preview-6", "type": "environment-config-lease" } } --> <!-- /CLOUDFLARE_PREVIEW_STATE --> Lease: `preview-6` Doppler config: `preview_6` Type: `environment-config-lease` Leased until: 2026-06-11T11:19:46.363Z ### OS Status: deployed Commit: `df5965b` Preview: https://os.iterate-preview-6.com [Workflow run](https://github.com/iterate/iterate/actions/runs/27340067055) Updated: 2026-06-11T10:23:48.699Z <!-- /CLOUDFLARE_PREVIEW --> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds
POST /internal/project/mint-project-id(service middleware) to the auth worker + contract: mints a canonicalprj_id without creating an auth-side project record.Why
#1485 makes auth the ONLY minter of the
prj_id space — OS's operator/recovery create path round-trips through this endpoint instead of minting locally. Previews point at production auth, so this must deploy from main BEFORE #1485 can pass preview e2e (its preview run currently 404s on this route).Purely additive — extracted verbatim from #1485; nothing calls it until that PR lands.
Testing
apps/auth+apps/auth-contracttypecheck green.🤖 Generated with Claude Code
Note
Low Risk
Additive internal route behind existing service auth; no DB writes and no production callers until a dependent PR lands.
Overview
Adds a service-only internal API so auth can hand out canonical
prj_*ids without creating an auth project row—intended for OS operator/recovery creates that have no owning organization.The auth-contract defines
POST /internal/project/mint-project-id(no input;{ id: string }output). The auth worker implements it behindserviceMiddleware, returninggenerateId("prj")and registersmintProjectIdon the internal project router. Nothing in this PR calls the route yet; follow-up work will route OS minting through auth instead of local id generation.Reviewed by Cursor Bugbot for commit 211c08a. Bugbot is set up for automated code reviews on this repo. Configure here.
Environment Config Lease
No active environment config lease.
OS
Status: released
Commit:
211c08aPreview: https://os.iterate-preview-2.com
Summary: Preview app released.
Workflow run
Updated: 2026-06-11T06:33:02.060Z