Date: 2026-07-13 (grounding decision, original to the design)
Accepted — the whole-resource write behaviour described here is superseded by
0039, which makes a commit write only the values that changed. The
rest (no cascade, the coarse IsNew/IsSynchronized/IsReadOnly flags, Rollback() re-fetching) still
holds; 0039 adds a per-resource HasUnsavedChanges() but no aggregate state.
Beyond store transactions (0028), the resource objects themselves need a way to persist or discard their in-memory changes, and to know whether they are new or in sync with the store.
Resource implements ITransactional:
Commit()persists this resource to its model (_model.UpdateResource(this)), when it is attached to a model and not read-only (Trinity/Resource.cs).Rollback()reloads the resource from the model (re-fetch by URI viaModel.GetResource), discarding in-memory changes and clearing theResourceCache.- Lightweight change-tracking flags
IsNew(not yet persisted) andIsSynchronized(matches store) are maintained byModelcreate/get/update paths;IsReadOnlyblocks commits.
- Simple per-resource save/reload semantics.
- Commit does not cascade: modifying a linked/related resource is not persisted by committing the parent — each resource must be committed itself. This is a common gotcha, compounded by lazy-loaded object graphs (0023).
- Tracking is coarse:
UpdateResourcerewrites the whole resource (no per-property dirty tracking), andRollbackincurs a full re-fetch.
Document the no-cascade behaviour prominently; consider an opt-in cascade and finer-grained dirty tracking.