# Publish a module Reference for [Publish a module](../start/publish.md): session records, what is uploaded, pins. ## Give it a session record A module that acts for a signed-in user names a session: `records/.json`, a `com.fedfork.exec.oauth.clientMetadata` record. Its scope is all the module may do. Copy one: `records/statusphere.json` ```json "clientMetadata": { "client_id": "https://statusphere.example.com/oauth-client-metadata.json", "client_name": "Statusphere", "client_uri": "https://statusphere.example.com", "redirect_uris": [ "https://statusphere.example.com/oauth/callback" ], "grant_types": [ "authorization_code", "refresh_token" ], "response_types": [ "code" ], "scope": "atproto repo:xyz.statusphere.status", ``` `scopeGroups` let a page ask for parts of it at a time. `hello` makes only public reads, so it has none. ## What is published The flow: [Publish a module](../start/publish.md). `atlibs publish` builds the repo's cargo workspace in a `rust:` container ([CONTAINER_ENGINE](../reference/env.md)) on a copy of exactly the files it publishes (`Cargo.toml`, `Cargo.lock`, `.cargo`, every member), uploads each source file once (by sha256), a manifest (its `build.command` is what `atlibs verify` replays), the blob and the module record, and keeps a copy under `records/wasm/`. The record is written twice: at `` (the latest) and at `.` (this version, which later publishes leave in place): ```bash run jq -c '{language, build: .build.command, origin: (.origin | keys)}' records/wasm/statusphere.manifest.json jq -c '{session: .session | keys, source: .source | keys}' records/wasm/statusphere.json ``` ```output {"language":"rust","build":"…","origin":["commit","repository"]} {"session":["cid","uri"],"source":["cid","uri"]} ``` Sharing a checkout with other work? Publish from `git worktree add ../pub HEAD`. A module is republished when its wasm, its record fields or its session record changed; a record whose live CID differs from the last publish is `drift`. Published before atlibs 0.5.0? Copy each module and composition to its version record (getRecord only, no build, the same pin): ```bash run=account atlibs publish versions hello compose --dry-run --as you.bsky.social atlibs publish versions hello compose --as you.bsky.social ``` ## Pins A lockfile pins each module: sha256 of the wasm's sha256 and the record's grant fields. `add` with `@` (32+ hex digits) or `@` refuses anything else. A pin loads its version (`.<32 hex>`), so it survives a republish: ```bash run=network atlibs add bobvmbuilder.bsky.social/echo PIN=$(jq -r .modules.echo.pin atlibs.lock.json) atlibs add "bobvmbuilder.bsky.social/echo@$PIN" > /dev/null && echo pinned atlibs add "bobvmbuilder.bsky.social/echo@$(printf '0%.0s' {1..32})" 2>&1 | grep -c pin ``` ```output pinned 1 ``` ## Verify a published module `atlibs verify` fetches the module, its manifest and every source file, checks each hash, rebuilds in a container and compares the result with the manifest and the blob. ```bash run=container atlibs verify bobvmbuilder.bsky.social/echo ``` ## Remove one ```bash run=account atlibs publish delete com.fedfork.exec.wasm.module/hello --as you.bsky.social ``` Previous: [Test a module](test.md) | Next: [Compositions](../compositions.md)