Approving, reviewing and publishing
Admins and developers decide what gets made and what reaches the game.
Approve request batches
The web page has a sidebar with one view per job, each showing how many items wait there. Under Your work: Inbox, Approve, Open requests, My claims, Questions, Review and Publish. Under Project: Library, AI disclosure and Settings. You only see the views your role can use, and a count that needs a decision from you is filled in green.
The page opens on Inbox: where every asset is, from an agent's draft to the repository, and a card for each kind of work waiting on you — the oldest batch to approve, the deliveries to review, questions nobody has answered, and what is ready to publish. Beside them sit the open pull request and how the published assets were made.
Library shows every asset as a picture, 50 at a time, newest first unless you pick Oldest first. Related assets share an id prefix: type hero. to see every hero, or pick a group under the filters, so hero.hero_3. shows one hero's expressions together. Narrow it by status, kind or tag too. Choose a tile to see its brief and files. Admins and developers can change its tags there with Edit tags: the picker suggests the keys and values other assets already use, so a set stays consistent, and a tag is key=value with one value per key. Ids that share a prefix for each character or set, like hero.<name>.<expression> or ui.attribute.<name>, make the library most useful. From the CLI, agh inbox prints the same counts with the command for each:
agh inbox
1 batches to approve agh batch list --status submitted
4 open requests agh list --claimable
0 requests you claimed agh list --status claimed
2 deliveries to review agh list --status delivered
3 accepted, ready to publish agh publish
1 waiting to merge agh publish --status
Requests arrive in batches, and fulfillers see nothing until a batch is approved. On the web page they are under Approve; from the CLI:
agh batch list --status submitted
agh batch show <batch-id>
agh batch approve <batch-id>
agh batch reject <batch-id> --note "Merge the three hare requests into one"
You don't have to take a batch whole. On the web page each request shows its brief, spec, tags and notes, with Edit to fix them and Drop to delete one. Untick the requests that need more work and press Approve: the ticked ones enter the queue, and the rest go back to the author's draft with your note. From the CLI:
agh mark card.frost_hare.art --spec size=768x1024 # fix a request before approving
agh remove card.ash_crow.art # drop one
agh batch approve <batch-id> --only card.ember_wolf.art,card.frost_hare.art --note "Split the crow into two poses"
Cancel an open request
An approved request that nobody has claimed yet can be taken back. On the web page, open Open requests, choose Cancel request… on the request, add a note if you like, and confirm. From the CLI:
agh cancel card.ash_crow.art --note "Cut from the game"
A cancelled request leaves the queue at once: nobody can claim it, and guest links stop showing it. Its brief and conversation stay in Library, marked cancelled, where Ask for it again (or agh revise) reopens it. A request for a new version of a published file goes back to published instead, with that file unchanged. If someone holds a live claim, ask them to release it first (or release it yourself) and then cancel.
Coding agents can cancel their own requests too, with agh cancel or the MCP cancel_request tool, until someone claims them. One that is still waiting for approval leaves its batch on Approve; if the agent cancels every request in a batch, the batch no longer waits for you.
Review deliveries
Review shows each delivered file beside its brief and the file it would replace, with image, audio and text previews.
3D models get a stage of their own. A .glb, .gltf or .fbx file opens in a viewer you can rotate (drag), zoom (scroll or pinch) and pan (right-drag), with its triangle and material counts. An FBX whose textures are separate files shows grey, with a note saying so: its shapes are right but its colours aren't. The first time anyone views a model, the page saves a still of it, so the Library shows the model without loading it again. The file a delivery replaces shows its still until you select it. Roblox files (.rbxm, .rbxmx and .mesh) can't be drawn in a browser. When the artist attached a picture, it shows labelled Artist's render: it is their picture of the model, not drawn from the file, so open the file in Roblox Studio before you accept anything that matters. Without one, Ask for a render starts a question in the asset's conversation.
agh list --status delivered
agh get <asset-id> --which pending # download the delivery
agh review <asset-id> --accept
agh review <asset-id> --reject --note "Too dark; keep the embers visible"
A rejection sends the request back to the queue with your note, so the next fulfiller sees it. Say whether the file missed the brief, or you now want something different: --changes-brief with the new --brief, --spec or --notes (Reject: change brief… on the web page) updates the brief and keeps the old one in its history. Fulfillers can ask questions on an asset; answer them under Questions, then change the brief once you agree. agh guide conversations covers both. The rejected file is kept: under the delivery, earlier attempts shows each one with its note, and agh get <asset-id> --which rejected --attempt 1 downloads one.
On the web page you can also:
- Correct how a file was made before accepting it, under Record as: for example
ai-assistedandFlux, retouched by Janewhen someone touched up the image. From the CLI:agh review <asset-id> --accept --provenance ai-assisted --made-by "Flux, retouched by Jane". - Tick several deliveries and press Accept selected.
- Reject and drop request when the asset isn't needed any more. It removes the request and its delivery, the same as
agh remove. - Change your mind before publishing: Back to review on Publish, or
agh review <asset-id> --undo, puts an accepted asset back in review and makes the file it replaced current again.
Spec checks
Specs are hints for the fulfiller, so agh never refuses a delivery that differs from them. For images, it measures the delivered file instead: its size and whether it has an alpha channel are shown under the preview, and any difference from the request's size spec, or from a spec asking for transparency (background: transparent, or one mentioning RGBA or alpha), is listed as a warning in red. agh show <asset-id> prints the same details (pending.image and pending.specWarnings with --format json). Whether a 1149×1369 image passes for a 1150×1370 request is your call: accept it, or reject it with a note asking for the exact size.
Audio deliveries are measured when the spec asks for a sample_rate, bit_depth, channels, loudness (integrated LUFS, within 1 LU unless the spec gives a tolerance such as -16 ±2) or peak (true peak in dBTP). Loudness follows ITU-R BS.1770, the measure most platforms and broadcasters use, and is measured for WAV, FLAC, MP3 and Ogg Opus files up to 10 minutes long. Differences show as the same warnings.
Videos (MP4, MOV, WebM) are read from their header when they're delivered, however big the file: length, size, frame rate and codecs. They're checked against max_seconds, size (such as 1920x1080), aspect (such as 16:9), fps and audio (required or none), and differences show as the same warnings (pending.videoHeader with --format json).
Review a video
A delivered video gets its own review layout. The player has a timeline, speed, sound and full screen, and keys while it has focus: Space plays, ← and → step 5 seconds, comma and period step one frame. Spec checks beside it lists each fact from the file's header, with mismatches marked. Made with shows how it was made.
Notes go in the asset's conversation, the same one every request has, with questions, answers and attached files. The message box carries an at 0:42 chip that stamps the player's current time into your message (✕ sends it without a time). Stamped messages start with their time: click it to jump the player there. They show as marks on the timeline too. Agents set the time with timecode (seconds) on post_asset_message.
Request changes asks for a written reason and sends the video back, the same as Reject for other assets; the reason goes into the conversation. Compare with v1 plays this delivery beside the accepted version, or the last attempt, in step from one set of controls, with a line saying what changed. Brief shows the request. On a phone the player goes edge to edge, spec mismatches come first, and Accept and Request changes stay at the bottom of the screen.
Scale to the spec's size
When a PNG, JPEG or WebP delivery is bigger than its size spec, agh can scale it down for you instead of sending it back. When the image's shape differs from the spec's, you choose which area to keep; by default it's the largest area of the spec's shape, from the centre.
On Review, Scale to 768×1024… sits under the size warning. It opens the image with a frame of the spec's shape over it, as large as fits and centred: drag the frame to choose what's kept, drag a corner to keep less (never below the spec's size), or nudge it with the arrow keys. The preview beside it shows the result. After Apply, the delivery says who scaled it, with links to the original and to undo. From the CLI, say which area to keep in the image's pixels:
agh scale <asset-id> # to the spec's size, cropped from the centre
agh scale <asset-id> --crop 0,96,1024,1365 # keep this area (x,y,width,height)
agh scale <asset-id> --undo # put back the image from before
The scaled image replaces the delivery, which still waits for review, with the same provenance. The delivered original moves to earlier attempts with a note saying who scaled it, and pending.scaledFrom records the original's size and the area kept. agh only scales down: an image smaller than the spec would blur, so reject it or ask for a bigger file. Undo works while the delivery waits for review.
How an image or sound was made
agh also reads what a delivered image's or audio file's embedded metadata says about how it was made, and lists it under the preview as Metadata:
- Content Credentials (C2PA): the tool that signed the file, such as ChatGPT or Adobe Firefly, and the digital source type it records.
- The IPTC digital source type in XMP, such as
trainedAlgorithmicMedia(made by generative AI),compositeWithTrainedAlgorithmicMedia(partly) ordigitalCapture(a camera). - EXIF and XMP software and camera tags, such as
Software: Adobe Photoshop 25.0orMake: Canon. - Generation settings that Stable Diffusion tools such as AUTOMATIC1111, ComfyUI and InvokeAI write into PNG text or the EXIF user comment.
- For audio: Content Credentials in an MP3's ID3 tag (a GEOB frame) or a WAV's
C2PAchunk; ID3 tags such as encoder, artist, comment and links; WAV INFO tags such as software and comment, and the broadcast-wave description and originator; and FLAC and Ogg comments such as encoder and description. Suno, for example, attaches Content Credentials to its downloads, and ElevenLabs says it uses them too.
Clues that name an AI generator are marked AI. When a delivery is declared human but its metadata says AI was involved, a red box says so above the clues: ask whoever delivered it, or correct it under Record as before accepting. agh show <asset-id> prints the same (pending.origin and pending.provenanceWarning with --format json).
Metadata is a clue, not proof. Most exports, screenshots and uploads strip it, so an image without any says nothing about how it was made, and anyone can edit it. The same goes for audio: re-exporting from an audio editor usually drops it. Some AI services also hide a watermark in the pixels or the sound itself (SynthID, used by Google, OpenAI and ElevenLabs, and Meta's AudioSeal). It survives editing, but only the service's own detector can read it. On Studio and Enterprise, agh can check new images and audio for OpenAI's watermark with your OpenAI account, and shows the result as the first line of Metadata; see Watermark checks. For other services' watermarks, Google and ElevenLabs each run a free detector page.
Image variants
Under a delivered image, Make variants… makes smaller copies, such as a 900-pixel WebP, that are saved as accepted assets when you accept the image. When a new version of an image with variants comes in, the box to remake them on accept is ticked by default. See Image variants. Studio and Enterprise plans.
Publish
Connect GitHub once (admins): on the web page, open Settings › Publishing, choose Set up on GitHub, then Connect GitHub. GitHub asks you to install the Asset Goes Here app and choose the repositories it may use, then sends you back to agh. agh never sees a GitHub password or token of yours. It publishes with short-lived tokens that GitHub issues to the app for one repository at a time. If you connected exactly one repository and the project had no target yet, agh publishes to that repository's default branch. Otherwise, pick a repository and branch under Publishing, or from the CLI:
agh project publish-to chust4phun/godot-ccg [--branch main] [--auto-merge]
To add repositories later, choose Connect GitHub again. A repository you haven't connected uses the server's own token, if its operator set one.
Then send accepted assets to GitHub as one pull request from the agh/assets branch. Publish lists everything accepted, all ticked; untick any that should wait, then choose Publish selected. From the CLI:
agh publish # every accepted asset
agh publish --only card.ember_wolf.art,card.frost_hare.art
Each publish adds a commit to the open pull request, together with an updated .agh/provenance.yaml. The assets it sent are proposed until that pull request merges, and only then published. agh checks the pull request whenever you open Publish, run agh publish --status, or publish again:
- Merged: its assets become
published. - Closed without merging: its assets go back to
accepted, ready to publish again or to send back to review. - Still open: they stay under Waiting to merge, with a link to the pull request.
A proposed asset can't be revised, undone or delivered to while its pull request is open; merge or close the pull request first. With --auto-merge, GitHub merges the pull request once required checks pass, and one with nothing to wait for merges at once, so its assets are published straight away.
Ask for a new version
agh revise <asset-id> --note "..." reopens a delivered, accepted or published asset with your note, optionally changing its brief or spec. On the web page, choose the asset in Library and use Ask for a new version, or use the Revise button beside it at the bottom of Publish; both work for published and accepted assets. A published file stays in place until its replacement is accepted and its pull request merges. agh guide revise covers every case.
Correct provenance, or swap in human work
AI-made assets can ship; the disclosure just has to say so. When the record is wrong, or you decide to replace a file with human work, these keep it accurate:
agh list --provenance ai
agh mark <asset-id> --provenance ai-assisted --made-by "AI draft, repainted by Jane"
agh fill <asset-id> ./final.png --provenance human --made-by "Jane Artist"
AI disclosure
Steam asks whether generative AI made content that ships with the game: art, sound, story, localization, the store page and marketing. AI disclosure on the web page, agh report on the CLI, and the get_ai_disclosure MCP tool show what agh recorded for the files in the repository (published assets), grouped by those categories:
- how many files are AI-generated, AI-assisted, human-made or not recorded;
- the AI tools named in their
made_by; - every AI and AI-assisted asset id, for your own audit;
- records to fix first: unknown provenance, AI files with no tool named, and files declared human whose metadata says AI made them.
An asset counts under its kind and where players see it: store and marketing material by used_in, game images as art, audio as sound and music, text and strings as story and writing, and translations of them as localization, counted per language. To file one elsewhere, tag it, such as --tag disclosure=story-and-writing. The categories are art, sound-and-music, story-and-writing, localization, store-page, marketing and other.
Steam's categories blur some differences: art holds both images and 3D models, and the store page and marketing hold any kind of file. So the report also counts the same files by asset type: images, 3D models, audio, writing (text and strings in the game's own language), translations and other files. On the web page, Group by switches the cards between Steam category and asset type, and a category that mixes types lists each one under By type. The public page always uses Steam's categories.
Above the categories, a filled chart shows how many published files were AI-generated, AI-assisted, human-made or not recorded on each day, for every file, one category or one asset type. agh began recording asset types later than categories, so a type's chart starts on the day your server first recorded them. When you replace AI placeholders with hand-made work, it reads as a burn-down. agh saves the day's counts whenever the published files change (a pull request merges, a provenance is corrected, an asset is removed) and when someone opens the report, so the history starts when this feature reached your server; it is not rebuilt from earlier commits.
The report states facts. Write the explanation Steam asks for yourself; Start from the numbers on the web page gives you a neutral first draft to edit.
Publish it for anyone to see
An admin can publish the report at a public page, such as https://app.assetgoeshere.com/disclosure/my-game, that anyone can open without signing in. It shows the explanation, and each category's counts and AI tools. Asset ids and paths stay private.
agh report --publish --explanation-file ai-disclosure.txt
agh report --unpublish
The public page is a snapshot of the report when you published it. Publish again after changes to update it. Visitors may see the earlier version for up to five minutes, because the page is cached so heavy traffic never reaches the inventory. The same data is at /disclosure/<project>/report.json.
On Studio and Enterprise, the page carries your studio's logo, accent colour and dark or light look from Organization > Branding & address, and once your studio address is approved it also opens there, such as https://yourstudio.assetgoeshere.com/disclosure/my-game.
For agents: this page as Markdown is at /docs/review.md, and the CLI prints it with agh guide review.