Skip to content

Commit 98c062e

Browse files
PhysShellclaude
andcommitted
docs(roslyn): the trust boundary is part of the profile's soundness model
The previous commit refused a region opened inside a type that declares the protocol, and documented it as one more thing the extractor refuses. That undersells what it is. The declaring types are the profile's trusted definition surface — token construction, region entry, transition plumbing — and everything else is the analysed surface. A type is one or the other, never both, because consumer code inside a declaring type is not a violation the core missed: it is a program the core never saw. The README states that as the model, next to what the profile claims, and the refusal list points at it. The lowering's header says the same. No behaviour changes: comments and prose only. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1 parent 78c041a commit 98c062e

2 files changed

Lines changed: 25 additions & 8 deletions

File tree

‎frontend/roslyn/OwnSharp.Extractor/ProtocolLowering.cs‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@
3030
// update, a change-tracker metadata write, raw SQL, another process. Those belong to
3131
// concurrency tokens, constraints and transactions.
3232
//
33+
// THE TRUST BOUNDARY. The types that DECLARE a protocol (the tokens, the type holding a
34+
// region entry) are the trusted definition surface: token construction, region entry and
35+
// transition plumbing live there, and their bodies are not lowered. Everything else is
36+
// consumer code — the analysed surface. A type is one or the other, never both: consumer code
37+
// inside a declaring type would simply be absent from the analysed program, so a region
38+
// opened there is refused rather than guessed about.
39+
//
3340
// OUTSIDE a region nothing protocol-relevant is live, and a region lowers to a self-contained
3441
// unit (the entity is acquired and released around it). So whatever surrounds a region —
3542
// `try`/`catch`, `using`, a loop, a branch, `await` — is walked through and ignored.
@@ -118,10 +125,11 @@ public static Result Lower(Compilation compilation,
118125
continue;
119126
if (IsApiType(msym.ContainingType))
120127
{
121-
// The protocol's own types are TRUSTED: their bodies implement the
122-
// protocol and are not lowered. So a region OPENED in one of them — a
123-
// handler written next to the region entry it calls — would never be
124-
// analysed and would read as clean. Trusted is not the same as checked.
128+
// The trust boundary (see the header): a declaring type's bodies
129+
// implement the protocol and are not lowered. So a region OPENED in one
130+
// of them — a handler written next to the region entry it calls — would
131+
// not be a violation the core missed but a program it never saw, and
132+
// would read as clean. Trusted is not the same as checked.
125133
foreach (var opened in method.DescendantNodes().OfType<InvocationExpressionSyntax>()
126134
.Where(i => IsRegionEntry(MethodOf(model, i))))
127135
refusals.Add(At(file, opened,

‎frontend/roslyn/README.md‎

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,16 @@ SQL, another process. Those belong to concurrency tokens, constraints and
118118
transactions (two of them are pinned as stated limits under
119119
`protocol-samples/efcore/known-gaps`).
120120

121+
**The trust boundary.** The types that DECLARE a protocol — the tokens, and the
122+
type holding a region entry — are its trusted definition surface: they construct
123+
tokens, enter regions and implement transitions, and their bodies are not
124+
lowered. Everything else is consumer code, and consumer code is what the profile
125+
analyses. A type is one or the other, never both. A handler written inside a
126+
declaring type would not be a violation the core missed; it would be a program
127+
the core never saw, and it would read as clean. So a region opened inside a
128+
declaring type is refused, and the profile does not try to guess which method of
129+
such a type is plumbing and which is a business handler.
130+
121131
**Refusals.** A recognised protocol construct that cannot be lowered safely is
122132
not skipped: the extractor exits `2` and writes no facts, for the whole scan.
123133

@@ -135,10 +145,9 @@ not skipped: the extractor exits `2` and writes no facts, for the whole scan.
135145
`nameof`, `typeof` and reads are mentions, not operations.
136146
- *Source.* The protocol and its entity must be in the scan as source; one that
137147
arrives only as a compiled reference cannot be admitted.
138-
- *Trusted types.* The types that declare a protocol (the tokens, the class
139-
holding a region entry) implement it and are not analysed as user code. A
140-
region opened inside one of them is refused rather than skipped: write the
141-
code that uses a protocol outside the types that declare it.
148+
- *Trust boundary.* A region opened inside a type that declares the protocol
149+
(see above): write the code that uses a protocol outside the types that
150+
declare it.
142151
- *Binding.* The scan does not read `obj/`, so usings a project only gets
143152
**implicitly** are not there. A region whose entity does not bind is refused;
144153
write the usings out in the files that open regions (or qualify the names).

0 commit comments

Comments
 (0)