Should a person open a picker every time an agent creates a small review document? Allowing any local path would solve the inconvenience by granting far too much. I added a generated-attachment route that accepts the current context, a basename and explicitly supplied bytes instead.
Do not mix create and choose inputs
The external schema separates files list, choose and create. Create requires name and dataBase64; the other actions reject those fields. Context explicitly contains profileId, workspaceId and tabId. Its strict object does not accept an added path field that would turn the contract into arbitrary local-file reading.
The handler checks current context and idle conditions before invoking the generator, passing a callback that rechecks context and work state during creation. Valid JSON shape and currently usable execution context both matter, and neither replaces the other. Passing schema validation is not presented as acquiring every operational permission to run against any project.
Validate names and encoding before creating anything
Names must be basenames and pass length, forbidden-character, hidden-name, trailing-dot/space and Windows reserved-name checks. Only the chosen document, image and data extensions are accepted, rather than executable filenames. An extension allowlist is not malware scanning or proof that the content really has the named format.
Base64 validation goes beyond whether Buffer can decode it. Character, length and padding checks are followed by re-encoding the decoded bytes and requiring exact equality. Decoded content must be nonempty and at most one MiB. This avoids quietly accepting malformed representations as different bytes. The small attachment route is not described as a general large-file upload transport.
Create only inside a new folder under the project scope
The generator checks the base, staging and scope paths for symbolic links, hashes profile and project into the scope name, creates a fresh UUID folder and writes with wx. Creating another same-named document therefore does not search for and overwrite a file in an earlier folder.
The base realpath is compared as well. These checks do not prove complete isolation against every hostile external filesystem race. Operational use also requires a trusted root and appropriate permissions. Showing boundary checks in code is a narrower claim than guaranteeing arbitrary attacker-controlled environments, and the explanation preserves that difference.
Finish both byte creation and handle registration
After writing bytes, the file is registered so later work receives a handle. Bootstrap remembers the newly added IDs and passes a rollback that forgets only those IDs if the following check fails. This connects physical creation with the registry state used by the next task.
On error, cleanup targets only the one file and empty UUID folder created by this attempt, without recursive project deletion. Rollback or cleanup failures are retained alongside the original error in AggregateError. This shares an ownership principle with my earlier temporary-file article, but the boundary here is an external generated request becoming a usable attachment handle.
A creation receipt is not a completed remote attachment
The external response includes the new ID, name, size and SHA256 with selectionOnly. It reports creation and selection, not upload to a service or placement in a published article. Keeping creation permission separate from remote sending also makes the later verification understandable.
Original tests cover exact supplied bytes, project separation and no overwrite, and refusal of invalid names, encoding, linked roots and missing context. I read those tests without calling the original creation API. The shared synthetic package is a smaller in-memory byte and handle comparison, not a filesystem generator. The account states what was actually executed as well as what the source implements.