Repository navigation
Release v4.28.0
Code kept in files (file Reducers/Balance.cs, file Validations/...) is now identified by its content when a host reads it from disk, as decision 0002 requires, instead of being reported unresolved. The MCP server does this for every model it opens; cratis render can do the same with one call.
Added
AttachmentFiles.Load(root, documents)reads the files named by a model's implementation attachments (reducer rules, validation rules and code validation, command handlers, policies, reactions, query performers, file constraints) from a model root and returns their contents with warning diagnostics for anything it refuses. PassContentstoSemanticDocumentSet.Create(documents, catalog, contents).ScreenplayWorkspace.WithAttachmentContents(contents, diagnostics)and a matchingScreenplayWorkspace.Createoverload carry host-supplied contents through every workspace compilation, proposal and transaction. The workspace itself never reads files, and its revision and serialized bytes do not depend on attachment contents.- PLAY0430–PLAY0434 warnings for an attachment that is refused or missing: a path that is absolute or leaves the model root, a link, a missing file, a file over 2 MiB (or a set over 8 MiB), and content that is not UTF-8 text. A refused attachment stays unresolved; it never fails a model that compiled before.
Changed
- The MCP server loads attachment contents from its trusted root, so
implementation-requirementsshows a content hash for each file attachment, and a changed attachment changes its hash. Unchanged attachments reuse the analyzed workspace, and proposals survive an attachment edit. SemanticDocumentSet.Createnormalizes attachment keys, so./X.cs,.\X.csandX.csname the same attachment and hash. Two supplied keys that normalize to the same path with different contents are treated as a conflict, not resolved by picking one.PlayFileCompilerand the standalone Tool compile syntax only and do not read attachments; the documentation now says so (#244).
Security
- Attachment reads are confined to the model root. Paths are normalized and rejected if absolute, drive- or UNC-qualified, escaping the root with
.., containing control characters, or naming a Windows device (CON,NUL,COM1, ...). Links and reparse points on the file or any directory of its path are refused, and the resolved path is checked against the root again before reading. - Only regular files are read. On Linux and macOS the file type is checked with
lstatbefore opening, so a FIFO or device cannot block the MCP server or CLI; where the type cannot be verified, the attachment is refused with a warning. Sizes are checked before reading. - Only a SHA-256 of an attachment's content leaves the loader; contents are never shown, logged or persisted, and diagnostics name only the authored path. Link checks run before opening and after reading, but not as one atomic no-follow open, so a concurrent local writer could swap a link during the read;
file-references.mddocuments this.