Repository navigation
feat(automations): follow the dev environment switch; a4 dev keeps the client's production deployment - #486
Merged
Merged
Conversation
…e client's production deployment Automations take their cluster from the client's environment switch (`client.environment`), with the descriptor's old `environment: 'dev'` kept as a fallback for clients generated by older versions. In dev mode they learn the environment's deployment from the client before binding the store or matching deliveries, and simulate against the environment by default. `checkCluster` compares `ARETE_CLUSTER` with the switch and says when the two disagree. The `a4 dev` runner refuses a production client, waits for the edge to name the deployment `a4 dev up` made, and connects view sources through the installed stack SDK in dev mode. `a4 dev up` and `a4 dev sdk` stop writing the dev deployment into the installed protocol client. The descriptor keeps the production deployment arete.lock pins, or none before the first deploy (`deployment: null` in TypeScript); for the published release's own spec nothing is generated. The `local_build` marker and the `a4 install --check` refusal stay. A TypeScript client with no deployment fails in production with "not deployed to production yet". The edge names the environment's deployment in `X-Arete-Dev-Deployment` on protocol routes; the protocol client reads it (`resolveDeployment()`) and signs metadata wallet proofs with it, since the API checks a proof against the instance's own deployment. `.arete/dev/session.json` no longer carries a stack session token.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
[Medium impact] The changes since the previous review appear safe to merge, with both numbered findings addressed. SummaryAutomations now follow the client's environment switch while generated clients keep their production deployment. The latest changes address both numbered findings:
Earlier thread context:
|
…a redeploy; repack skills a4 dev keeps the deployment arete.lock pins only for a published release: an older a4 wrote dev deployments into never-published entries, and one from before the current deployment would otherwise pass as production's. Automations refuse new work once the client calls another deployment than the one their store was bound to (a redeploy into the dev environment). a4 dev up no longer mints a stack session, so the integration tests check that it doesn't. The skill archives are repacked.
…fore the publish A client generated from a local build after `a4 protocol deploy` marks its deployment as production in sdk-provenance.json. `a4 dev` keeps a never-published entry's deployment only with that mark, so an unmarked id an older a4 wrote for the dev environment is still dropped.
# Conflicts: # cli/src/commands/dev/edge.rs # cli/src/commands/dev/proxy.rs
# Conflicts: # docs/public/.well-known/agent-skills/arete-protocols.tar.gz # docs/public/.well-known/agent-skills/index.json
…y; regenerate a missing published client
This branch was successfully deployed
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.
@usearete/automationsfollows the dev environment switch.a4 dev upstops writing the dev deployment into the installed protocol client. These two have to ship in the same release: once the client no longer names the dev deployment, automations must read the switch, or dev runs count as mainnet.Stacked on #483 (the TS/React switch), which is stacked on #475 (the edge). This branch also merges the latest
feat/dev-edgecommits (the protocol instance, intent and receipt routes), which #483 doesn't have yet. That's why the edge's last three commits show in this diff until #483 picks them up.What changes
Automations
clientCluster(client)returnsdevwhenclient.environment === 'dev'. The olddeployment.environment === 'dev'check stays as a fallback for clients oldera4versions generated (exported aslegacyDevClient, marked for removal in the next major).client.resolveDeployment()before it binds the store, matches webhook deliveries, labels stream events or checks consents, so all of these use the environment's deployment. Clients from SDKs without the method behave as before.checkClustercomparesARETE_CLUSTERwith the switch-derived cluster. The messages no longer say to restore the published client, because the file is the same. A mismatch now says the variable and the switch disagree. A legacy dev-generated client still gets the olda4 install --lockedmessage.createAutomationswithoutsimulator: production throws ("pass asimulator"), so the requirement stays the same, now checked at construction. Dev mode simulates against the environment.rpcSimulator()with no URL: in dev mode it uses the edge. In production it throws. In direct mode it throwsdevenv-surface-unavailablewith a fix.a4 devrunner: it refuses a client whoseenvironmentisn'tdev.a4 dev upnow starts it withARETE_ENVIRONMENT=devandARETE_DEV_URL=<edge>, and removes anyARETE_DEV_ENV. It waits up to 15s for the edge to name the deploymenta4 dev upjust made, which covers the edge's resolve cache after a redeploy. View sources connect withArete.connect(stack, { environment: { kind: 'dev' } })through the edge. A stack the environment lacks is refused (devenv-stack-not-loaded) instead of falling back to the published stack's data.Protocol client (
a4 dev up/a4 dev sdk)sync_installed_clientstill regenerates types from the local build, and thelocal_buildmarker and thea4 install --checkrefusal stay. The descriptor now keeps the production deploymentarete.lockpins (from a publish or ana4 protocol deploy), or none before the first deploy. A dev deployment id an oldera4wrote into the lock is dropped, not kept as production's.deployment: null, andProtocolDefinition.deploymentis nowProtocolDeploymentDescriptor | null. Rust and Python emit an empty deployment id, which is how feat(rust-sdk): honour the dev environment switch; ARETE_ENVIRONMENT in a4 #482/feat(python-sdk): honour the dev environment switch #484 already read "not published yet". Theenvironment: 'dev'marker is no longer generated. READMEs say "not deployed to production yet" instead of naming a deployment.createProtocolClientwith no deployment in production fails withPROTOCOL_NOT_DEPLOYED: " is not deployed to production yet …". feat(sdk): TypeScript and React SDKs honour the dev environment switch #483 acceptednullonly in dev mode, but with a generic message.a4 dev upalready binds each deployment to the environment (environmenton deployment create), and resolve returns the newest active one. No change was needed.Metadata proofs (the #483 gap)
The API verifies a participant-writer proof against the instance's deployment, i.e. the environment's. The wallet's signature covers the deployment id, so the edge can't rewrite it. The fix is in the SDK, which signs with the environment's deployment:
/api/protocol-deployments/…answer it forwards, the edge addsX-Arete-Dev-Deployment: <environment deployment>, exposed to loopback pages through CORS.resolveDeployment(). In production it returns the generated id with no request. In edge mode it does aGETof the deployment route if no call has named it yet. In direct mode it uses resolve. After that,client.deploymentIdis the environment's.proofMessagein dev mode throws "await client.resolveDeployment()before building one" until the deployment is known, instead of signing a proof that can't verify. The contract (§3.1) documents the header and this rule.session.json
a4 dev upno longer mints a stack session or writesstackSession. Nothing read it: the old runner minted its own, andDevClient/a4 dev status/a4 stream --devmint with the key. Older files still parse. The doc comment onDevSession,docs/cli/local-development, the streams skill and thedev_statusMCP description are updated.Not done / deviations
a4 stream --devstill streams with stack sessions it mints, not through the edge. The edge's/stacks/<alias>route resolves installed identities (manifest hash + live alias).a4 stream --devstreams the environment's own stacks (the protocol's stack, custom stacks). Those have no installed identity, and the environment's stack listing doesn't expose one. Routing it through the edge needs an identity on the listing, or an edge route by environment stack. That's follow-up work. Its behaviour is unchanged here; it never read the session file's token./transactions/v1/simulate. The policy'sSimulatoris JSON-RPC (getMultipleAccounts,simulateTransaction,getTransaction,isBlockhashValid,getSignatureStatuses; schedules also read the clock). Several of these have no REST counterpart on the transactions transport. The edge's JSON-RPC is the same environment (its fork), so "simulates against the environment" holds. Direct mode has no JSON-RPC target in the resolve answer, sorpcSimulator()refuses there with a fix rather than deriving a URL.environment: { kind: 'dev', url }option (rather than variables or the session file), the default simulator can't see that URL. PassrpcSimulator(undefined, { environment }).a4 dev upanda4 dev runset the variables, so the runner isn't affected.@usearete/automationsnow importsresolveEnvironmentSwitch/DevEnvironmentErrorfrom@usearete/sdk. Its@usearete/sdkpeer range needs the release that ships feat(sdk): TypeScript and React SDKs honour the dev environment switch #483.@usearete/automations/dev) is still open. When both land, its helpers' gate (clientCluster(client) === 'dev') should move to the switch (client.environment === 'dev').clientClusteralready reads the switch, so the existing gate works as is.Conditions
dev. It accepts the environment's webhook deliveries, binds the store to the environment's deployment and completes steps (runtime.test.ts). The runner builds a realcreateProtocolClientin dev mode fromARETE_ENVIRONMENT=devand asks the edge for the deployment (dev.test.ts).a4 dev upstarts the runner with the switch set (Rust testruns_the_runner_in_dev_mode_through_the_edge).mainnet, and the mainnet policy rules are unchanged (runtime.test.ts, existing cluster refusal test).checkClustermessages are covered inhost.test.ts.simulateTransactiongoes to the edge's JSON-RPC. Production still requires one (runtime.test.ts,policy.test.ts).an_unchanged_spec_leaves_the_published_client_as_it_is). A spec change keeps the production deployment (a_published_protocol_keeps_its_pins_and_its_production_deployment), and an unpublished protocol getsdeployment: null(goldens updated). The same definition calls the production deployment with the switch unset and the edge in dev mode (coredev-environment.test.ts).What ran where
@usearete/sdk(core) typecheck + 836 tests;@usearete/automationstypecheck, lint and 418 tests (Postgres suites skipped locally);@usearete/protocoltypecheck + 319 tests;@usearete/react188 tests (its typecheck needs the adapter packages built, which CI does).a4 dev upor a real environment.Merge order
#475 → #483 → this PR. Release automations and the CLI together, along with #482/#484 if Rust/Python dev mode should match. #472 can land before or after; see above.