# models/invocation.model.md

> 119 lines of code and 0 definitions.

Tree: Coordination tree
Language: markdown
Layer: domain
Canonical: https://banes-lab.com/anatomy/coordination#file-coordination-models-invocation-model-md
Source text: https://banes-lab.com/assets/sources/source.9e8ec7725611cb725c8d88013c40de2de451e6183eefd3eef9479543a0475468.generated.txt

## Source

```markdown
<!-- MODEL SURFACE -->

# Shared invocation: a run declares what it WRITES and publishes what it READ, and a second caller joins rather than duplicating.

# Instantiate per project. Nothing here names a project, a party, a tool or a count.

# Raised from `templates/model.template.md`. The measured half lives in a finding surface and never here.

═══════════════════ LIFETIME (declared, read rather than inferred) ═══════════════════

**THE VALUES ARE DRAWN FROM THE CLOSED SETS THE PARAMETER SURFACE DECLARES AND ARE NOT RESTATED HERE.**

**The file default:** retention `current-truth` — a class statement is corrected in place. Mutability
`owner-rewritable` — any party may write it, announced before the edit lands, because this is an OUTCOME
surface authored jointly rather than a set of per-party claims. Removal authority `author`.

| section                                    | axis       | value    | why                                                                                               |
| ------------------------------------------ | ---------- | -------- | ------------------------------------------------------------------------------------------------- |
| this LIFETIME block and the CONTRACT block | mutability | `frozen` | written from the template and never edited in a live surface — a correction lands in the template |

**ONE WRITER PER RECORD HAS NO OPERAND HERE.** This surface carries ONE PRODUCT, authored jointly, with no
per-party unit for the invariant to range over — so it does not hold weakly, it has **no operand**, which is a
third state distinct from held and violated. Record structure is REFUSED rather than merely unnecessary: the
collision here is between MEANINGS, and the instrument that reaches it is the announcement plus each author
cutting its OWN duplicate.

═══════════════════ CONTRACT (permanent) ═══════════════════

**A CLAUSE STATES THE SHAPE AND THE PARAMETER SURFACE HOLDS THE MEMBERS.** A statement naming a project, a
party, a tool, a file or a count is instance content and belongs in a finding surface.

| element      | states                                                               |
| ------------ | -------------------------------------------------------------------- |
| SCHEMA       | a run's two declarations and what each decides                       |
| LIFETIME     | when each declaration is written and what ends it                    |
| FAILURE MODE | what goes wrong when it is not obeyed, and how that failure presents |
| GATE         | the check that observes it, or `none` as declared debt               |

═══════════════════ MODEL ═══════════════════

## A run makes TWO declarations, and they answer two different questions

**A run declares a WRITE SCOPE and publishes a READ POPULATION, and neither is derivable from the other.** The
write scope decides COLLISION: whether two runs may proceed at once. The read population decides VALIDITY:
whether a published result answers a later caller's question. **Collapsing them into one declaration makes a
mechanism answer one question with the other's operand**, which is correct exactly while every run reads what
it writes and wrong the moment one reads more than it touches.

| declaration         | decides                           | consumed by               |
| ------------------- | --------------------------------- | ------------------------- |
| the WRITE scope     | collision between concurrent runs | the conflict comparison   |
| the READ population | validity of a published result    | a caller testing coverage |

**The two are ORTHOGONAL BY CONSTRUCTION rather than by assertion**, and the construction is what makes the
claim checkable: a JOINER's write set is EMPTY, so it appears in no conflict comparison at all.

## Joining is a READ of a published result, never an attachment

**A second caller whose question a live declared scope COVERS joins by reading that run's published result and
its standing, and writes nothing.** It does not attach to the run, does not wait on a handle, and does not
acquire anything — so the conflict algebra ranges over STARTERS alone, and a joiner cannot deadlock, cannot be
orphaned by the run it joined, and needs no cleanup path.

**COVERAGE IS THE CALLER'S FIRST TEST AND THE ALGEBRA IS THE FALLBACK**, in that order. A caller asks whether a
live scope already covers its question; only where none does is it a starter, and only then does its declared
write set enter a comparison. **Reversing the order makes every caller a starter that then discovers it did not
need to be**, which is the duplication the whole construct exists to remove.

## Comparison is by DECLARATION throughout, so no exclusion clause survives

**Two scopes are compared as DECLARED, never as inferred from what a run turns out to touch.** A declaration is
an operand both parties can read before either acts; an observation of actual writes exists only afterwards,
which is too late for a comparison whose whole purpose is to decide whether to begin.

**The consequence is that an exclusion clause cannot be honored.** A scope stated as _this subtree EXCEPT that
part_ is not comparable against another declaration without evaluating the exception over a population, and the
population is exactly what nobody has yet built. So the family of scopes is closed under what runs actually
write, with no atom in every scope, and a run that would need an exclusion declares the narrower scope instead.

**AND CONTAINMENT IS RELATIVE RATHER THAN A PREFIX.** A scope of one subtree does not contain a sibling whose
name merely opens with the same text — a prefix test admits it and a relative test refuses it, and the
difference appears only on a member somebody names later.

## Containment is a property of the MECHANISM, never a claim about a run

**The question a mechanism answers is _CAN this run write outside its scope_ rather than _did it_, and the
first is settled at one function.** The first needs a witness nobody holds for repairs scattered across a tree; the second is a
property of the write path, which takes the declared scope and refuses a path outside it.

**A gate over that property ranges over the WRITERS A RUN REACHES rather than over a directory listing.** A
gate scoped to one registry reports a complete funnel while something writes beside it; one scoped to the
dispatch directories reports the same while a helper writes beneath either. The reachable set is the import
graph from the entry point, and the sanctioned set is DATA the check cites, seeded only with verified members.

## Liveness is ONE-SIDED, and the asymmetry is the whole of it

**Absence witnesses death; presence witnesses nothing.** An absent process is dead whatever a clock says. A
present one may be an unrelated occupant of a reused identity, so its presence supports no conclusion at all —
and a mechanism treating the two symmetrically is right in one direction and guessing in the other.

**So liveness is derived ONCE, asking the witness first and falling through to a window only where the witness
cannot decide.** Every consumer reads that one derivation rather than each computing its own, or two consumers
of one question impose different properties and the weaker passes silently.

**THE WINDOW IS SET GENEROUSLY, AND ITS DIRECTION IS DECLARED WHERE THE WINDOW IS.** Too long holds a dead
claim and costs one re-invocation. Too short declares a live run dead and costs a LOST WRITE, which is silent
and unrecoverable. The generosity is affordable precisely because of the witness: an absent process reads as
dead whatever the clock says, so a long window hides no failure the machine can observe, and it governs only
what the witness cannot decide.

**A claim recorded on another machine is never interrogated and falls to the window**, because the witness is
local by construction and asking it about a foreign identity answers a different question.

## A published operand is its AUTHOR'S ACCOUNT until something outside the author is compared against it

**REACH and WITNESS are two axes.** That a mechanism PUBLISHES a result establishes reach — a consumer can
receive it. It establishes nothing about whether the result is true, because the publisher is also the only
party that measured it.

**So a published operand is evidence about its author until a second, independent operand is joined against
it** — and the join must range over something the author does not control, or it is self-consistency wearing
verification's clothes.

## A channel name is a TOTAL, REVERSIBLE encoding of the scope it belongs to

**INJECTIVE is not sufficient and the insufficiency is silent.** An injective name separates two scopes'
channels correctly, so nothing collides and no comparison is ever wrong. **INVERTIBLE is what lets a retention
condition read the scope back out of the name** — and a digest satisfies the first while failing the second
with no observable difference: the files are correctly separated and nobody can decide which is stale.

**The encoding is TOTAL, which is what makes the guarantee structural rather than checked.** Its alphabet
excludes the separator the name is composed with, so no scope — including one whose text is itself a channel
name — can compose the canonical whole-scope name or collide with another channel. That is a property of the
function rather than a precondition somebody remembers.

**A CHANNEL HAS A DECLARED REMOVER RATHER THAN INHERITING AN ORPHAN SWEEP.** A channel is identified
POSITIVELY — a name that decodes to a scope, and a body declaring itself non-authoritative — and one whose
scope resolves to nothing is removed by a remover that declares what it removes. A whole-scope aggregate is
identified by neither and is never a member, whatever its name reads.

## Two simultaneous starters are ordered by DECLARE-THEN-READ, with no lock and no wait

**The entry is written BEFORE the set is read**, so neither of two simultaneous starters can see an empty other
set. The order is decided by the start stamp with the party identity breaking an exact tie, and a release fails
CLOSED toward keeping when it cannot name its own run.

**Every member of that family is the same shape: mutual exclusion with no lock, no wait and no new field**,
because both operands are already in the declaration and only the ORDER of writing and reading decides whether
they are visible to each other.

**And the decision is HONORED at the entry point rather than announced.** A yielding caller exits without
writing, and a non-yield exit that carries a passing run's signal is a run that measured nothing reporting as
one that did — so both non-proceeding branches exit distinguishably from success.

## Gate

- A run proceeding without a declared write scope fails: the comparison has no operand.
- A caller starting where a live declared scope covers its question fails the coverage test, not the algebra.
- A scope carrying an exclusion clause fails at declaration rather than at comparison.
- A liveness verdict derived anywhere but the one derivation fails, because a second derivation is a second
  truth that disagrees on its first divergence.
- A channel name that is injective and not invertible: `none` — the failure is silent by construction and no
  check here decides it; the encoding's totality is what holds it instead.
```
