Conversation
|
ndisidore
force-pushed
the
nathan/create-external-resource-google
branch
from
September 4, 2026 19:50
6011068 to
faee59d
Compare
Preview:
|
|
… a flat scalar map the kernel carries but never reads, validated by the vendor and reflected on its approval card.
GOOGLE_DOC_RESOURCE is the first creatable type. createResource() checks the account holds the doc grant (documents.create needs the write scope that grant already carries -- no new scopes), mints a provisional-<uuid> document id, and returns a GoogleDocGatekeeperImpl imbued with creation props. getGatekeeperClassFor refuses such an id, so a provisional URL that outlives its creation -- one a rejection stranded, or that a blueprint captured under suggestValue and an install auto-assigned -- cannot mint a binding whose document never resolves. The guard sits there rather than in parseResourceUrl, which must keep parsing these URLs for describe(). It accepts no creation options: assertNoCreationOptions refuses the whole map, quoting the type's own creatable.description, so a placement the agent supplies is a fixable rejection rather than a document silently created somewhere else. The refusal runs before the grant round-trip, because the agent can fix its own call within the turn while a missing grant ends it on a user action. The facet queues a createDocument action as pending action #1, so the existing in-order approval rule applies the creation before any queued edit. Until then the binding simulates over a synthetic empty snapshot with zero provider traffic (describe(), getMetadata(), and getContent() all answer locally); sourceMap/bodyEndIndex are safe to fake because materialization only runs at apply time, when the document exists. Apply calls documents.create and late-binds provisional-to-real via the kit's ProvisionalIds; edit actions resolve the real id before touching the API. Rejecting the creation invalidates every queued edit and marks the binding dead, so session methods explain instead of simulating against nothing. Observers are tracked rather than asserted. A provisional binding has no ACL to consult, and admitting one unchecked has to be paid for later: the overseer re-runs addObserver on every open but never on a session already open, so a collaborator who joined before the creation landed would keep observing the real document, including content written to it outside the workspace. The document is one tracked set in the package's ObserverTracker -- a binding minted against an existing document seeds it, keeping admission the hasDocAccess check it was, while a created one seeds nothing and the first read after the creation forward-excludes whoever joined before it. commit() runs only once the overseer authorizes, so the set is promoted only after every named observer was torn down or provably cannot reach it. Session reads funnel through one #authorizeRead, and removeObserver is real. Settling an action the facet already settled is a no-op, not an error. The overseer marks its record approved only after applyAction returns, so a decision whose reply is lost leaves a pending record with no facet-side counterpart; answering "Unknown pending" stranded a card that could then be neither approved nor rejected, blocking every queued edit behind it under the in-order rule and, for a creation, the binding itself. PendingActionStore.issued() separates a never-submitted id, which still throws, from a settled one -- the at-least-once contract gatekeeper-kit documents. A crash between documents.create and the binding write can still leak one duplicate document on a retried approval (the API has no idempotency key, and the edit write-marker protocol cannot cover creation); accepted for now. The workerd docs suite covers simulation-without-traffic, create-then-edit ordering, retried-approval idempotency, observer withholding across the creation, and the rejection cascade.
Document creation keeps its own action kind, separate from the edits one, so enabling hands-free creation is a distinct choice -- the case that wants it is a scheduled task minting a new doc each run, whose queued edits would otherwise stall in-order behind a creation card every time. Nothing is auto-applied without the user enabling the createDocument rule.
ndisidore
force-pushed
the
nathan/create-external-resource-google
branch
from
September 14, 2026 19:15
faee59d to
07dfdf2
Compare
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.
Google Docs is the first creatable resource. A doc title isn't globally contended, so this proves the kernel API without the approval-time rename that github repo names will need. Also supports a common use case, i.e. a scheduled task minting a doc each run, whose queued appends would otherwise wait on a human click every time
A created doc gets a
provisional-<uuid>id and resolves to the real id when the creation applies, via the kit's ProvisionalIds (cherry-picked at its own paths so nathan/gatekeeper-kit rebases cleanly). Before that, the binding simulates over an empty document and makes no provider calls. The existing in-order rule applies the creation before any queued edit. Rejecting the creation invalidates every queued edit and makes session methods fail with an explanation of what happened. No new OAuth scopes; the doc grant already carries write access.Creation is auto-approvable under its own opt-in rule, separate from edits.