We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
🔥 TOP SIGNAL
Codex’s usage reset exposes control-plane bugs in autonomous coding agents. @thsottiaux says paid Codex and ChatGPT Work users are being reset after thousands of reports, with expected usage 10%–50% further depending on how Codex is used; the audit found retained-image compaction loops, /goal overruns or retries that consumed 15%–70% of a weekly allowance, over-frequent automations, unexpected helper escalation, and duplicated or truncated MCP results.
Treat those as a regression suite: in a disposable repo, replay an image-heavy compaction, a /goal with a deliberate stop, a Stop-hook interaction, a custom schedule, and a large MCP result; log token deltas, helper selection, and whether the run terminates. This test plan is my recommendation, based on the failure modes the update says were fixed.
⚡ TRY THIS
Turn idea dumps into a pull queue. ThePrimeTime’s Linear MCP workflow is simple: finish a long brainstorm, have the agent turn the ideas into tickets, then—when you do not know what to work on—run: “Hey, Agent, go to Linear and tell me what I need to do next.” Resource: Linear Terminal.
Make a side-effecting agent draft-only by construction. Kent C. Dodds’s Kody pattern starts with the explicit grant “Create a draft reply. Never send.” Put that intent in the README and export docs; request
gmail.composeplusgmail.googleapis.com, addgmail.readonlyonly if inbox reading is required, callusers.drafts.createrather than a send endpoint, then publish a thin drafts-only package and lock it withchanges: { locked: true }. Gmail’s OAuth scope can still technically send, so the package lock—not the token—is the authority boundary; later publishes require the owner’s Promote this commit action.Use real file paths for remote context. In the T3 Code nightly, attach any file; the attachment is exposed to the agent as a real path. Upload a PDF, Markdown file, or MP3 and let the agent operate on that path instead of building a bespoke transfer step.
A/B a cheap model with a deterministic smoke test. Matthew Berman’s GLM workflow is replicable: create a Z.AI or OpenRouter API key, connect it to OpenCode—or another client supporting an OpenAI-compatible endpoint—and avoid sensitive data when using the China-served Z.AI endpoint. His baseline task was a Rubik’s Cube simulation; he checked scrambling, solving, cube size, colors, speed, camera, lighting, and materials.
📡 WHAT SHIPPED
GLM 5.3 Flash (Z.AI) is the main model-level release signal. Berman presents it as an open-weights mixture-of-experts model with 320B total parameters and 18B active, reporting Terminal Bench 84.3 and DeepSuite 63.4; he also cites a 1M-token context, 131K maximum output, and maximum reasoning by default. His cost estimate is about $0.09 per intelligence-index task, but the model uses about 47,000 output tokens on average versus roughly 20,000 for Luna; he still calls Luna the better pure cost/quality trade-off, while GLM buys open-weight control. His same-prompt demos are not a controlled benchmark: GPT 5.6 Soul had internet access in Codex while OpenCode did not.
Claude Code’s capacity schedule is changing on September 14. ClaudeDevs says the current 50% weekly-limit increase remains in place until then, after which standard limits for Pro, Max, Team, and seat-based Enterprise plans will be permanently 25% higher than the prior standard; the team characterizes that as a 17% reduction from today’s promotional level. Treat September 14 as the budget boundary for long-running agent work.
T3 Code’s adoption signal is now substantial. Theo reports more than 250,000 users and 70,000 weekly active users nine days after an earlier update, and says Linux became the most popular platform as of August 23. Omarchy 4.1 is slated to ship with T3 Code, with DHH describing setup as taking only a few seconds.
Provider exposure needs task-level accounting. In the Cursor discussion, @thsottiaux cautions that the cited 5% model-traffic share is not a proxy for revenue or value because token-efficient frontier models consume fewer tokens; a current-period video separately quotes Harrison Chase arguing that a harness owned by no model lab is the only architecture that works across every model.
🎬 GO DEEPER
- Matthew Berman — “Cancel your subscriptions, Ox-Alpha is here! (GLM 5.3 Flash)”: Watch the API hookup, Rubik’s Cube smoke test, and same-prompt comparison. The useful lesson is how to combine a deterministic artifact test with cost, token-efficiency, and tool-access caveats rather than trusting a leaderboard claim alone.
- OpenAI Sets a Date to Cut Cursor Off: Skip the ownership drama and watch the Amazon/Kiro workflow section. The video reports that, across roughly 50 Amazon Stores teams, merely adding AI produced under 3× prior deployment velocity while teams that changed how they worked reached 4.5× or better, with documentation, precise errors, compiler feedback, and locally mocked services offered as the practical levers. The figures are self-reported and deployment velocity is not the same as value shipped.
- Study Kody’s locked Gmail drafts guide: It is a compact example of separating authentication from declared authority: a published export creates a draft and returns its ID, while the human reviews and sends; the lock prevents this package’s jobs and exports from silently becoming a sender.
Editorial take: The highest-alpha agent work today is not adding autonomy; it is making autonomy observable, interruptible, and narrowly authorized—usage accounting, deterministic smoke tests, and locked side effects are becoming first-class features.
Direct answer. Reproduce the guide as a separate, thin Kody package with the explicit grant “Create a draft reply. Never send,” request Gmail’s gmail.compose scope, optionally add gmail.readonly only for inbox reading, allow gmail.googleapis.com, publish the package, and then set changes: { locked: true }. Later published changes require the owner’s Promote this commit action; an agent must not unlock the package.
Permission model
-
Gmail has no drafts-only scope:
gmail.composeis described as “Manage drafts and send emails,” so the Google token itself can send. The safety boundary is the Kody package’s published surface and lock, not OAuth scope granularity. - A Kody package is the declared-authority unit: its named exports, jobs, and other package-owned surfaces run the published tree, while an integration is authentication only and the Google token remains as broad as Google issued it.
locked_atkeeps this package serving its published tree; agents and the five-minute reconcile job cannot advancepublished_commit, andpackage_updateacceptschanges: { locked: true }. Agents cannot unlock; they must direct the owner to/@{username}/{kodyId}.-
The package lock does not revoke the token’s send capability, hide
createAuthenticatedFetchfromexecute, or stop a different unlocked package from sending; it prevents this package’s jobs and exports from silently becoming a sender. -
If access is through a connected MCP server, that is a separate grant: lock the server to the package so
executeand other packages cannot callkody.mcp["name"].
Exact setup
-
Put the intent in README
## Intentand the export JSDoc Purpose. If sending is later requested, treat it as a new grant: unlock on the website, change the Intent, and publish a send export only after confirmation. -
Load
integration_bootstrap,oauth, andprovider_google; requesthttps://www.googleapis.com/auth/gmail.compose, addgmail.googleapis.comtoallowedHosts, and addhttps://www.googleapis.com/auth/gmail.readonlyonly when inbox reading is required. Do not requesthttps://mail.google.com/orgmail.modify. -
After authorization, smoke-test
users.drafts.createfromexecuteand confirm that a Gmail draft appears. Do not callusers.messages.sendorusers.drafts.send. -
Save a thin drafts-only package following
package_authoringandpackage_lifecycle, with its ownkody.idsuch asgmail-drafts. Do not lock a full@kody/googlefork if it exports send; keep send off this package’s published surface, and make the searchable Purpose state that the export creates a draft and does not send. -
The export should encode an RFC 2822 message as
rawandPOSTit tohttps://gmail.googleapis.com/gmail/v1/users/me/drafts; never add/messages/sendor/drafts/send. The raw message containsTo,Subject,MIME-Version: 1.0, UTF-8text/plaincontent type, a blank line, and the body, then is base64url-encoded with+changed to-,/changed to_, and trailing=removed.
const googleFetch = await createAuthenticatedFetch('google')
const response = await googleFetch(
'https://gmail.googleapis.com/gmail/v1/users/me/drafts',
{
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({
message: { raw: rfc2822Raw(input) },
}),
},
)-
The export’s documented contract is that a human reviews and sends in Gmail; it returns a Gmail draft ID and does not send. On failure, throw with the HTTP status and response text; parse the JSON response, require
data.id, and return{ draftId: data.id }. A scheduled job must call this export only and must not add a send path “for convenience.”
Approval-gated publication workflow
-
Run the authorization and draft-create smoke test first; once checks pass and
published_commitmoves, callpackage_updatewithchanges: { locked: true }or use the lock icon on/@{username}/{kodyId}. -
After locking, pushes still land on Artifacts HEAD, but publish tools return
lockedwithapproval_url/account/packages/:packageId/approve-publish?commit=. The owner opens that URL and clicks Promote this commit; promoting a commit does not unlock the package. -
If an agent needs the lock removed, it sends the owner to
/@{username}/{kodyId}and does not passlocked: false.
- GLM 5.3 Flash (Z AI) is presented by Matthew Berman as a new open-weights mixture-of-experts model with 320B total parameters and 18B active parameters; its weights can be customized, fine-tuned, and hosted by users. Berman cites Terminal Bench 84.3 and DeepSuite 63.4, and says it approaches Claude Opus 4.8 on coding and agentic benchmarks. The model offers a 1M-token context, 131K maximum output, default maximum reasoning, and cached-input pricing of 1 cent per million tokens.
- Cost and routing trade-off: Berman reports about $0.09 per intelligence-index task and estimates the model is only 5–7% below the frontier while costing roughly 2–3% as much as the cited frontier model. He considers GPT 5.6 Luna the best cost/quality trade-off at roughly $0.05 per task, but says GLM 5.3 Flash has a higher intelligence score and offers open-weight control; GLM also averages about 47,000 output tokens per task versus roughly 20,000 for Luna.
- Replicable integration workflow: Create an API key through Z.AI, or use OpenRouter/another inference provider, then connect the key to OpenCode or another project supporting an OpenAI-compatible API endpoint. Berman notes that Z.AI is served from China and says he avoided sending sensitive information. His practical smoke test was to have the agent build a Rubik’s Cube simulation, then check scrambling/solving and controls for cube size, colors, speed, camera, lighting, and materials.
- Hands-on comparison caveat: Berman tested GLM against GPT 5.6 Soul with identical prompts, including: “Build a beautiful interactive 3D scene featuring seven miniature biome dioramas floating against a deep navy background.” Soul won that scene on detail and coherence, while Berman judged GLM better on several website-design examples, including Apple and DGX Spark; he found the Galaxy Z Fold outputs poor and the Tesla comparison inconclusive. The comparison is not fully controlled because Soul in Codex had internet access while OpenCode did not at the time. This is firsthand prototype/demo evidence from Berman’s API and generated-app tests, rather than a reported production deployment.
Cursor/OpenAI availability (secondhand report): OpenAI said it intends to wind down the contract supplying its models to Cursor, with a proposed shutoff date of November 12, 2026, because it cannot be confident SpaceX will use the technology within its terms of service. The report frames this as an ownership-triggered judgment rather than a claim that Cursor itself violated terms. Cursor’s CEO said OpenAI models represent about 5% of user traffic, but that figure came from an unaudited screenshot, so the expected impact remains unverified.
Model-neutral orchestration: Harrison Chase argued that labs will build strong harnesses for their own models while restricting access to competitors’ harnesses, making a harness owned by no model lab the only approach that works across every model. For teams supporting multiple providers, this favors keeping orchestration and agent state outside any single model vendor’s harness; the report notes that LangChain’s business is itself based on model-neutral orchestration.
Workflow redesign matters more than layering AI onto existing process (secondhand report from an AWS senior principal engineer working on Kiro): Across roughly 50 Amazon Stores teams observed for about a year, teams that simply added AI to existing workflows achieved under 3× prior deployment velocity, while teams that changed how they worked achieved 4.5× or better, occasionally exceeding 10×; the company, tools, models, and time period were held constant. Earlier inline completion/autocomplete produced only 10–20% gains. The reported practices were to document implicit team knowledge for the agent, accept a temporary productivity dip during restructuring, improve error messages, migrate from Python/JavaScript toward TypeScript or Rust for compiler feedback, and use locally mocked services so agents can validate and self-correct without cloud round trips. The figures are self-reported internal metrics, and deployment velocity is not equivalent to value shipped.
Code-review agents need team-specific rules and outcome feedback (secondhand report from Uber): Uber’s first-review wait grew from three hours in 2024 to nine hours this year across thousands of engineers and six monorepos; its in-house U Review produces about 25,000 comments per week, with 67% addressed, 75% of high-severity issues resolved, and operating cost 60% below its first naive version. Uber improved the reviewer by tracking developer reply sentiment and whether comments were addressed, routing reviews by risk, and letting each team provide its own style guide and anti-patterns; without explicit team-specific rules, the models reportedly generated confident errors at scale. These metrics were also self-reported.
Coding-model release signals: Z.ai released GLM-5.3 weights on Hugging Face and reportedly dropped MIT licensing: providers with more than $10 billion in trailing-twelve-month revenue must pass a Z.ai security review before hosting it, while self-hosting and small providers are unaffected. The base model is unchanged from GLM-5.2; the reported gains came from post-training, especially on complex coding and long-horizon tasks. Perplexity says GLM-5.3 is live in Perplexity Computer and beats GLM-5.2 on its WANDR benchmark, but the comparison uses Perplexity’s own benchmark and hosting. The report also flags the absence of a model card and published red-teaming despite sharper cyber capability. Tencent’s Hy4 Preview reportedly has 770 billion parameters and a one-million-token context window, with internal tests claiming it beats Z.ai and Moonshot; that ranking remains unverified outside Tencent.
- Linear MCP backlog loop (firsthand workflow, presented in a sponsor segment): After a long brainstorming conversation, the speaker has the agent turn the ideas into Linear tickets, then asks, “Hey, Agent, go to Linear and tell me what I need to do next,” using the ticket backlog to select the next task. Resource mentioned: https://linear.app/terminal
- Use AI for research support, not unverified substitution (Casey Muratori, firsthand): Casey reports that after spending about three hours getting research from an AI, he still had to read the original paper and would not make strong claims without checking it; he argues that open-ended reading reveals valuable material he did not know to look for. The discussion identifies practical context-preparation uses: finding original sources, OCRing malformed PDFs, converting difficult web pages into local HTML, and turning articles into offline Markdown. A durable pattern follows: delegate discovery and format normalization to an agent, but keep primary-source verification human-in-the-loop.
- Cursor built a Kody-hosted PWA that tracks relevant lines of code in the Kody repository and visualizes codebase growth. The supplied screenshot description reports 1,809 commits and 610,426 cumulative lines, with cumulative, added/removed, and net-per-commit views plus filters for source, tests, docs, and language.
-
Kody configured a webhook that updates the app whenever a new commit reaches
main; Kent C. Dodds attributes the ease of building this kind of app to access to other packages and integrations. Kent also shares reusable examples: LOC Explorer and Lineage.
- Qwen 3.8 Flash Next’s n-gram/“engram” mechanism: Salvatore Sanfilippo describes a learned static association table of roughly 51 billion parameters that hashes the last two or three input tokens through 16 hash functions and retrieves vector fragments. A learned matrix gates how much of that phrase-level signal is injected into the already contextualized final token, with “New York” and “storia dell’arte” used as examples.
- Inference implication for coding-agent model selection: The lookup is not an additional context token and does not enter the KV cache. Retrieval is overlapped with first-layer processing and applied at the second layer. Sanfilippo says the lookup parameters can reside in RAM in mixed CPU/GPU inference and are handled as lightweight lookups rather than intensive matrix multiplications, reducing compute pressure on the dense backbone.
OpenAI said it is ending its partnership with Cursor following Cursor’s acquisition by SpaceX; under the proposal, Cursor’s direct access to OpenAI models would end on November 12. OpenAI said developers relying on its models in Cursor would be affected and that it was prepared to provide extensive transition support.
ClaudeDevs reports that Claude Code weekly limits will be reduced by 17% relative to current levels, while promising changes intended to provide more effective usage and greater visibility and control over consumption.
- Kent C. Dodds reports shipping a new Kody Koala feature intended to make it safer to trust agents with sensitive actions. Gmail is the initial example, with a linked guide on locked Gmail drafts; he says the capability is broader than Gmail.
- Resource: Locked Gmail drafts.
- Claude Code’s current temporary 50% increase in standard weekly limits is scheduled to end on September 14; the permanent standard weekly limits will then be 25% above the prior baseline for Pro, Max, Team, and seat-based Enterprise plans.
- Theo’s proposed communication pattern is to state the promotion history, quantify the net change, acknowledge user impact, explain compute or availability constraints, and surface any offsetting benefit. His suggested removal of the separate Fable limit was explicitly described as wishful thinking rather than a confirmed product change.
- Claude Code usage limits: ClaudeDevs announced that standard weekly limits for Pro, Max, Team, and seat-based Enterprise plans will be permanently raised by 25% starting September 14; the current 50% increase remains in place until then. This is an official product update surfaced by ThePrimeagen, not a firsthand workflow report or benchmark.
- Theo reports that Linux became the most popular platform for T3 Code as of August 23, indicating strong adoption of the coding agent among Linux users.
- Omarchy 4.1 is slated to ship with T3 Code, and DHH says getting started takes “literally just a few seconds.” Theo says Omarchy’s inclusion is likely the biggest factor among several behind Linux’s lead and thanks the Omarchy team.
Theo identifies an agent-native analytics gap: products should let agents access product-usage data, implement against the codebase, and expose where users encounter friction. He says analytics companies tend to either ignore AI or embed AI features directly, and that although several are building agent harnesses, he knows of none with working Agent SDK traces.
- Alex Finn describes Omarchy as an AI-first, open-source operating system and says it has “skyrocketed” his productivity; his linked video covers how to install and use it.
- DHH positions Omarchy as a “Third Option” for people who would not spend the time to configure a system by hand, highlighting reduced setup friction as its practical value.
Theo reports that Claude Code can be used with sudo permissions when using “auto” mode rather than “bypass permissions.”
- Paid users of Codex and ChatGPT Work received a usage-limit reset, with expected capacity improving by roughly 10%–50% depending on usage patterns.
-
The update identifies several concrete agent-cost and control failure modes: image-heavy compaction could retain old images and trigger repeated compaction, costing about 10% more usage; background memory workers could loop against Stop hooks, with one case checking 15,000 times;
/goalcould continue past its stop condition or retry broken tools, consuming 15%–70% of a weekly allowance; custom automations could run too frequently; and smaller models such as Luna could select more capable helpers or invoke/fastsubagents without being asked. All were reported fixed. - Additional fixes addressed overlapping Computer History summaries that consumed up to one-fifth of weekly usage in some cases, extra rolling-task-summary requests adding about 1% to token usage, and MCP results being encoded twice or having tool instructions truncated and fetched again. The team also added architectural safeguards and was working on an in-app usage breakdown.
Theo (@theo) ranks Claude Code CLI above Codex CLI, while preferring the Codex desktop app over Claude Code’s desktop app; the post provides no workflow, implementation details, or reasoning beyond this CLI-versus-desktop split.
- OpenAI announced that it is ending its partnership with Cursor following Cursor’s acquisition by SpaceX; under the proposal, Cursor’s direct access to OpenAI models would end on November 12.
- Jediah Katz says he has been the primary engineer supporting and promoting OpenAI models in Cursor since GPT-5, and that the team will work to ensure users are not missing anything during the transition.
- T3 Code nightly — file attachments: Theo says users can attach any file, with each attachment exposed to the agent as a real file path. This supports remote workflows and includes PDFs, Markdown files, MP3s, and other formats.
- DHH amplified Theo’s claim that Linux became the most popular platform for T3 Code as of August 23, calling it “The Year of Linux on the Desktop.” The posts provide no adoption share, methodology, workflow, or coding-agent technique, so this is only a tentative platform-usage signal rather than a benchmark.
Gmail drafts without send — lock what Google cannot scope

Google’s Gmail API has a send-only scope and no drafts-only scope. Creating a draft requires gmail.compose (opens in new tab) (“Manage drafts and send emails”) or a wider write grant. The token can send. A locked Kody package is the grant that cannot.
This is the usual complaint: an assistant should prepare the reply to an invoice or a support thread and leave it in Drafts. The human opens Gmail, edits, and sends. OAuth cannot say that. The published export can — and the publish lock keeps a later agent from widening it.
What lock does
A package is the declared-authority unit: named exports, jobs, and other package-owned surfaces run the published tree. An integration is auth only. The Google token stays as wide as Google issued it.
Publish lock (locked_at on the saved package) keeps serving that published tree. Agents and the five-minute reconcile job cannot advance published_commit. package_update accepts changes: { locked: true }. Agents cannot unlock; send the owner to /@{username}/{kodyId}.
Lock does not revoke send on the token, hide createAuthenticatedFetch from execute, or stop a different unlocked package from calling send. It stops this package’s jobs and exports from silently becoming a sender.
A connected MCP server is different: lock the server to a package so execute and other packages cannot call kody.mcp["name"]. That grant lives on the server, not on locked_at. See Lock an MCP server to a package (opens in new tab).
Usage detail: Packages → Publish lock (opens in new tab).
The loop
- Name the grant. “Create a draft reply. Never send.” Write that in README
## Intentand in the export JSDoc Purpose. If the user later asks to send, that is a new grant — unlock on the website, change Intent, and publish with a send export only after they confirm. - Connect Google with the narrowest token that can draft. Load
integration_bootstrap,oauth, andprovider_google. Requesthttps://www.googleapis.com/auth/gmail.composeand addgmail.googleapis.comtoallowedHosts. Addhttps://www.googleapis.com/auth/gmail.readonlyonly when the agent must read the inbox to propose the reply. Do not requesthttps://mail.google.com/orgmail.modify. - Smoke-test draft create, not send. After authorize, call
users.drafts.createfromexecute(example below). Confirm a draft appears in Gmail. Do not callusers.messages.sendorusers.drafts.send. - Save a thin drafts-only package. Follow
package_authoringandpackage_lifecycle. Give it its ownkody.id(for examplegmail-drafts). Do not lock a full@kody/googlefork if that fork exports send — keep send off this package’s published surface. Search Purpose must say the export creates a draft and does not send. - Publish, then lock. After checks pass and
published_commitmoves, callpackage_updatewithchanges: { locked: true }(or the lock icon on/@{username}/{kodyId}). Say so in chat so the owner knows later publishes need their Promote this commit click.
Draft-create export
This is the write the package is allowed to perform. Encode an RFC 2822 message as raw and POST it to https://gmail.googleapis.com/gmail/v1/users/me/drafts. Never add /messages/send or /drafts/send.
import { createAuthenticatedFetch } from 'kody:runtime'
function toBase64Url(text: string): string {
const bytes = new TextEncoder().encode(text)
let binary = ''
for (const byte of bytes) {
binary += String.fromCharCode(byte)
}
return btoa(binary)
.replaceAll('+', '-')
.replaceAll('/', '_')
.replace(/=+$/g, '')
}
function rfc2822Raw(input: {
to: string
subject: string
body: string
}): string {
const message = [
\`To: ${input.to}\`,
\`Subject: ${input.subject}\`,
'MIME-Version: 1.0',
'Content-Type: text/plain; charset="UTF-8"',
'',
input.body,
].join('\r\n')
return toBase64Url(message)
}
/**
* Create a Gmail draft. Use when the human will review and send in Gmail.
* Does not send.
*
* @param input - Recipients, subject, and plain-text body
* @returns Gmail draft id
*
* @example
* import createDraft from 'kody:@scope/gmail-drafts/create-draft'
*
* const draft = await createDraft({
* to: 'billing@acme.example',
* subject: 'Re: Invoice 1842',
* body: 'Thanks — I will review and reply today.',
* })
*/
export default async function createDraft(input: {
to: string
subject: string
body: string
}): Promise<{ draftId: string }> {
const googleFetch = await createAuthenticatedFetch('google')
const response = await googleFetch(
'https://gmail.googleapis.com/gmail/v1/users/me/drafts',
{
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({
message: { raw: rfc2822Raw(input) },
}),
},
)
if (!response.ok) {
throw new Error(
\`Gmail draft create failed: ${response.status} ${await response.text()}\`,
)
}
const data = (await response.json()) as { id?: string }
if (!data.id) {
throw new Error('Gmail draft create returned no draft id.')
}
return { draftId: data.id }
}A job that drafts overnight follows the same rule: the scheduled wrapper calls this export only. It does not grow a send path “for convenience.”
Later publishes
Pushes still land on Artifacts HEAD. Publish tools return locked with approval_url /account/packages/:packageId/approve-publish?commit=<sha>. The owner opens that URL and clicks Promote this commit. Promoting one commit does not unlock the package.
If an agent needs the lock off, it sends the owner to /@{username}/{kodyId}. It does not pass locked: false.
Same pattern on other coarse tokens
Use this guide whenever a provider token can do more than the published surface should. Slack workspace tokens, GitHub PATs with repo, and Drive-wide scopes have the same shape: grant the token you must, publish only the call you mean, lock so the creature cannot quietly grow.
When to load this guide
Load locked_gmail_drafts when someone wants Gmail drafts the agent must not send, when they ask why Gmail has no drafts-only scope, or when any OAuth token is coarser than the intended package. For the Google console and Testing-status refresh-token trap, load provider_google. For inbox reading as a teaching transcript, load google_oauth. For package shape and the lock field, load package_authoring and the publish lock (opens in new tab) usage page.
Direct answer. Reproduce the guide as a separate, thin Kody package with the explicit grant “Create a draft reply. Never send,” request Gmail’s gmail.compose scope, optionally add gmail.readonly only for inbox reading, allow gmail.googleapis.com, publish the package, and then set changes: { locked: true }. Later published changes require the owner’s Promote this commit action; an agent must not unlock the package.
Permission model
-
Gmail has no drafts-only scope:
gmail.composeis described as “Manage drafts and send emails,” so the Google token itself can send. The safety boundary is the Kody package’s published surface and lock, not OAuth scope granularity. - A Kody package is the declared-authority unit: its named exports, jobs, and other package-owned surfaces run the published tree, while an integration is authentication only and the Google token remains as broad as Google issued it.
locked_atkeeps this package serving its published tree; agents and the five-minute reconcile job cannot advancepublished_commit, andpackage_updateacceptschanges: { locked: true }. Agents cannot unlock; they must direct the owner to/@{username}/{kodyId}.-
The package lock does not revoke the token’s send capability, hide
createAuthenticatedFetchfromexecute, or stop a different unlocked package from sending; it prevents this package’s jobs and exports from silently becoming a sender. -
If access is through a connected MCP server, that is a separate grant: lock the server to the package so
executeand other packages cannot callkody.mcp["name"].
Exact setup
-
Put the intent in README
## Intentand the export JSDoc Purpose. If sending is later requested, treat it as a new grant: unlock on the website, change the Intent, and publish a send export only after confirmation. -
Load
integration_bootstrap,oauth, andprovider_google; requesthttps://www.googleapis.com/auth/gmail.compose, addgmail.googleapis.comtoallowedHosts, and addhttps://www.googleapis.com/auth/gmail.readonlyonly when inbox reading is required. Do not requesthttps://mail.google.com/orgmail.modify. -
After authorization, smoke-test
users.drafts.createfromexecuteand confirm that a Gmail draft appears. Do not callusers.messages.sendorusers.drafts.send. -
Save a thin drafts-only package following
package_authoringandpackage_lifecycle, with its ownkody.idsuch asgmail-drafts. Do not lock a full@kody/googlefork if it exports send; keep send off this package’s published surface, and make the searchable Purpose state that the export creates a draft and does not send. -
The export should encode an RFC 2822 message as
rawandPOSTit tohttps://gmail.googleapis.com/gmail/v1/users/me/drafts; never add/messages/sendor/drafts/send. The raw message containsTo,Subject,MIME-Version: 1.0, UTF-8text/plaincontent type, a blank line, and the body, then is base64url-encoded with+changed to-,/changed to_, and trailing=removed.
const googleFetch = await createAuthenticatedFetch('google')
const response = await googleFetch(
'https://gmail.googleapis.com/gmail/v1/users/me/drafts',
{
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({
message: { raw: rfc2822Raw(input) },
}),
},
)-
The export’s documented contract is that a human reviews and sends in Gmail; it returns a Gmail draft ID and does not send. On failure, throw with the HTTP status and response text; parse the JSON response, require
data.id, and return{ draftId: data.id }. A scheduled job must call this export only and must not add a send path “for convenience.”
Approval-gated publication workflow
-
Run the authorization and draft-create smoke test first; once checks pass and
published_commitmoves, callpackage_updatewithchanges: { locked: true }or use the lock icon on/@{username}/{kodyId}. -
After locking, pushes still land on Artifacts HEAD, but publish tools return
lockedwithapproval_url/account/packages/:packageId/approve-publish?commit=. The owner opens that URL and clicks Promote this commit; promoting a commit does not unlock the package. -
If an agent needs the lock removed, it sends the owner to
/@{username}/{kodyId}and does not passlocked: false.