Conversation
There was a problem hiding this comment.
Pull request overview
This PR removes Donna’s ability to mutate “world artifacts” (update/copy/move/remove) and strips the related mutability modeling (readonly) from workspace config and world abstractions, aligning implementation with updated CLI/docs.
Changes:
- Removed artifact mutation APIs (workspace/context helpers, world methods, CLI subcommands/options, and related errors).
- Removed
readonlyfrom world/config models and implementations. - Updated documentation/specs and unreleased notes to reflect “read/validate only” artifact behavior.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| donna/workspaces/worlds/python.py | Removes readonly field and readonly-related constructor wiring. |
| donna/workspaces/worlds/filesystem.py | Removes artifact mutation methods and readonly gating; keeps session state/journal writing. |
| donna/workspaces/worlds/base.py | Removes readonly field and update/remove abstract methods from the World interface. |
| donna/workspaces/errors.py | Removes WorldReadonly error type. |
| donna/workspaces/config.py | Removes readonly from WorldConfig and default world configs. |
| donna/workspaces/artifacts.py | Removes artifact mutation functions and associated error classes; keeps fetch/extension helpers. |
| donna/context/artifacts.py | Removes context-level update/copy/move/remove methods. |
| donna/cli/types.py | Removes --extension option parsing/types used by the removed CLI mutation command(s). |
| donna/cli/commands/artifacts.py | Removes update/copy/move/remove subcommands and updates CLI help text accordingly. |
| donna/artifacts/usage/worlds.md | Updates spec to clarify Donna only reads/validates artifacts; mutation is external. |
| donna/artifacts/usage/cli.md | Updates CLI docs to remove mutation commands and clarify artifact immutability. |
| changes/unreleased.md | Adds migration/breaking-change notes for removal of artifact mutation support. |
Comments suppressed due to low confidence (2)
donna/workspaces/worlds/filesystem.py:266
initialize(reset=True)can delete the entire configured world directory viashutil.rmtree(self.path). Withreadonlyremoved from the world/config model, there is no longer a config-level guardrail to prevent destructive deletes if a user misconfigures the session world path (e.g., pointing it to a non-workspace directory). Consider adding a safety check beforermtree(e.g., requireself.sessionand/or require the path to be under the workspace’s.donna/directory, and refuse/reset with a structured error otherwise).
def initialize(self, reset: bool = False) -> None:
if self.path.exists() and reset:
shutil.rmtree(self.path)
self.path.mkdir(parents=True, exist_ok=True)
donna/workspaces/worlds/filesystem.py:169
write_state/journal_reset/journal_addnow always perform filesystem writes whensession=True, but these methods don’t catchOSError/PermissionErrorfrommkdir,write_bytes, oropen. Sinceunwrap_to_erroronly convertsUnwrapError, these exceptions will propagate and crash the CLI if the session world path is not writable. Consider wrapping the I/O intry/except OSErrorand returning a domainWorkspaceError(or similar) so the failure is reported as a normalErrorsList.
def write_state(self, name: str, content: bytes) -> Result[None, ErrorsList]:
if not self.session:
return Err([world_errors.WorldStateStorageUnsupported(world_id=self.id)])
path = self.path / name
path.parent.mkdir(parents=True, exist_ok=True)
path.write_bytes(content)
return Ok(None)
def journal_reset(self) -> Result[None, ErrorsList]:
if not self.session:
return Err([world_errors.WorldStateStorageUnsupported(world_id=self.id)])
path = self._journal_path()
path.parent.mkdir(parents=True, exist_ok=True)
path.write_bytes(b"")
return Ok(None)
def journal_add(self, content: bytes) -> Result[None, ErrorsList]:
if not self.session:
return Err([world_errors.WorldStateStorageUnsupported(world_id=self.id)])
path = self._journal_path()
path.parent.mkdir(parents=True, exist_ok=True)
with path.open("ab") as stream:
stream.write(content.rstrip(b"\n"))
stream.write(b"\n")
return Ok(None)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -1,2 +1,16 @@ | |||
| ### Migration | |||
|
|
|||
| - Update your scripts and specs to use external tools or direct file edits to create, update, move, copy, or delete world artifacts instead using removed Donna commands. | |||
There was a problem hiding this comment.
The migration note has a grammatical issue that makes it harder to understand. Consider rephrasing to: “...delete world artifacts instead of using the removed Donna commands.”
| - Update your scripts and specs to use external tools or direct file edits to create, update, move, copy, or delete world artifacts instead using removed Donna commands. | |
| - Update your scripts and specs to use external tools or direct file edits to create, update, move, copy, or delete world artifacts instead of using the removed Donna commands. |
No description provided.