Skip to content

Add revision-checked slice-description semantic patches - #175

Merged
woksin merged 5 commits into
mainfrom
feat/semantic-patches
Aug 30, 2026
Merged

Add revision-checked slice-description semantic patches#175
woksin merged 5 commits into
mainfrom
feat/semantic-patches

Conversation

@woksin

@woksin woksin commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Add the first allowlisted semantic patch operation on top of the immutable workspace transaction boundary: update an existing single-line slice description by stable SemanticId with exact source ownership and drift checks.

Added

Changed

woksin added 5 commits August 30, 2026 15:54
Add SemanticSourceMapRole (Declaration=0, Description=1) as an
additive init property on SemanticSourceMapEntry, keeping its
positional constructor and binary shape unchanged. Extend the source
map's duplicate/order validation to key on role alongside identity and
span.

Give DescriptionParser an additive internal overload that reports the
exact SourceLocation and raw escaped length of a newly accepted
single-line quoted description body, leaving the public Parse
signature and every existing caller's behavior unchanged. A fenced
description yields no span.

Add DescriptionLocation/DescriptionRawLength as init-only properties
on SliceSyntax (not positional constructor fields, for the same
binary-compatibility reason as its existing File property) and
populate them in SliceParser.

Have SemanticModelBinder.BindSlice emit a second source-map entry with
Role=Description and a non-zero span for a slice's single-line quoted
description, using the existing OffsetAt line/column resolution. This
is the plumbing a semantic patch operation needs to locate and replace
a description's exact bytes without touching the rest of the
document.
Introduce UpdateSliceDescription : WorkspaceOperation, keyed by a
slice's stable SemanticId, carrying a required ExpectedCurrentDescription
and NewDescription. It joins the Operations array like any
whole-document operation - same revision gates, same
parse/merge/bind/identity pipeline, no second preview/apply method.

Add four additive WorkspaceConflictKind values (SemanticIdNotFound,
UnsupportedSemanticField, SemanticFieldValueDrift,
MultiOwnerSemanticEdit) after the existing five, which keep their
values.

Extend the internal WorkspaceTransactionOperations.Apply (and its sole
caller, WorkspaceTransaction.Propose) to receive the original
ScreenplayWorkspace and a semantic-claims set alongside the existing
targeted set. Apply resolves the requested SemanticId against the
workspace's identity catalog and its Description-role source-map
entry, distinguishing an unknown id, a known non-slice id, and a
slice with no single-line quoted description - all rejected typed as
UnsupportedSemanticField or SemanticIdNotFound rather than falling
back to raw text editing. A matching entry's raw body is unescaped
with StringLiteral.Unescape and compared ordinally against
ExpectedCurrentDescription (SemanticFieldValueDrift on mismatch),
NewDescription is escaped with StringLiteral.Escape and spliced into
the decoded text, then the result is re-encoded as strict UTF-8,
preserving a BOM iff the original document had one.

A document may be claimed by at most one operation in a transaction.
Existing() now also checks the semantic-claims set so a whole-document
operation colliding with an already-claimed semantic edit reports
MultiOwnerSemanticEdit instead of the generic InvalidOperation,
symmetrically regardless of which operation runs first.
Cover the binder's new Description role: separate zero-length
Declaration and non-zero Description entries for the same slice id,
exact decoded text, determinism across repeated binds, and no
Description entry for a missing or fenced description.

Cover UpdateSliceDescription end to end: the happy path changes only
the description's literal bytes and yields one Replaced write entry
with every other document instance/bytes untouched; stale workspace
and catalog revisions are rejected before the operation is inspected;
an expected-value mismatch yields SemanticFieldValueDrift with no
candidate; an unknown SemanticId yields SemanticIdNotFound; a
module/feature/command id and a missing or fenced slice description
all yield UnsupportedSemanticField; two semantic edits and a
semantic-plus-whole-document edit on the same document yield
MultiOwnerSemanticEdit regardless of operation order; quote,
backslash, newline, tab and astral Unicode round-trip through
escape/splice/decode; and repeating the same proposal against the
same source returns an equal result without mutating the original
workspace.

Add constructor/enum/source-map compatibility specs for
SemanticSourceMapEntry, SliceSyntax, WorkspaceConflictKind and
UpdateSliceDescription.
Describe the first semantic patch on top of the workspace transaction
layer: how it shares the Operations array, revision gates and
compilation pipeline with whole-document operations, its exact-byte
happy path, and the four typed conflicts (SemanticIdNotFound,
UnsupportedSemanticField, SemanticFieldValueDrift,
MultiOwnerSemanticEdit) a caller must handle instead of falling back
to raw text editing. Update the prior forward-reference to semantic
patches now that the first one exists.
Reject semantic patches when the workspace has no trustworthy compilation, runtime values are null, or more than one description source owner exists.
@woksin woksin added the minor New features, non-breaking additions label Aug 30, 2026
@woksin
woksin merged commit 653a5dd into main Aug 30, 2026
3 of 4 checks passed
@woksin
woksin deleted the feat/semantic-patches branch August 30, 2026 14:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

minor New features, non-breaking additions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant