Conduct method before object-level work. Fires when the work needs several moves in non-trivial order. Type: (MethodUnderdetermined, Hybrid, CONDUCT, WorkProspect × MoveGround) → ConductedMethod
Scanned 9/3/2026
Install to Claude Code
npx -y skills add jongwony/epistemic-protocols --skill conduct --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Conduct?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/jongwony-conduct)More formats (shields.io, HTML) on the badges page.
---
name: conduct
description: "Conduct method before object-level work. Fires when the work needs several moves in non-trivial order. Type: (MethodUnderdetermined, Hybrid, CONDUCT, WorkProspect × MoveGround) → ConductedMethod"
---
# Hyphegesis Protocol
Conduct how a session's epistemic work will be carried out — the order, independence, reconciliation, termination, and routing of its cognitive moves — when that method is underdetermined before object-level cognition begins. The morphism is **design THEN hand off**: Hyphegesis designs a conduct topology over the moves it identifies and emits a method plan with in-session checkpoints, then stops; the substrate executes the moves. Type: `(MethodUnderdetermined, Hybrid, CONDUCT, WorkProspect × MoveGround) → ConductedMethod`.
## Definition
**Hyphegesis** (ὑφήγησις: a leading-the-way, guiding from just ahead): A dialogical act of conducting a session's epistemic work — deciding how its multiple cognitive moves relate in order, independence, reconciliation, termination, and routing — when the method is underdetermined while the goal is clear. The protocol's lexical verb is `/conduct`. It activates only when the work needs two or more moves whose conduct is non-trivial (single-move work relays to that one protocol), designs the conduct topology draft-first — filling every axis·region with a reasoned value shown beside the alternatives it displaces, and proposing the region cut itself with what it read to cut that way and the standing affordance to replace it, then opening a value gate only where the user points — and registers an in-session checkpoint when a constitutive decision's evidence does not yet exist (synthesis output shape generally; cell membership in the decompose-recovery instance), surfaces substrate feasibility as a handoff annotation, compiles a decision-typed Recognition brief into every checkpoint, assembles a cross-cutting trace contract (its disclosure overlay over the five axes — residuals, degradations, coverage caps, never silent), and hands off a method plan that the substrate — not Hyphegesis — executes.
```
── FLOW ──
Hyphegesis(WP) → (Λ.work_pointer := the navigation block the accumulated context supplies, None otherwise) → GroundPointer[unreachable ∨ support-integrity failure: relay(handoff unreadable)(extension) → deactivate] → MethodBrief(WP) → guard[relay-test, anti-self-application] →
[single-move ∨ trivial-conduct: relay-route(extension) → deactivate] |
[multi-move ∧ non-trivial:
Qc(brief, warrant) → A_w → [Accept: continue | Amend(WP'): Λ.work_prospect := WP' → re-enter Phase 0 over WP', rebinding work_pointer against the corrected prospect] →
MoveId(WP × MG) → Sc(MoveSet) → A_s → [Confirm(MS'): |MS| ≥ 2 → MS | |MS| < 2 → the relay terminals PHASE TRANSITIONS enumerates, deactivate] →
DraftTopology(MS, WP) → CT_draft →
loop( DraftSurface(CT, constituted_axes, CT_draft) → DraftGate → Stop → DM →
[Sufficient: exit
| Open(sites): [CutSite(p) ∈ sites: ReviseCut(p) → CarryConstituted → ReDraft → re-present (the round ends here — no value gate opens over region names about to be replaced)
| otherwise: for each site in impact/leverage-first order: AxisGate(site) → Stop → VM → update(CT, constituted_axes) → (VM = Sufficient: exit, or re-present first when this round re-filled a slot the surface has not shown | VM carrying a partition ends the round: ReviseCut → CarryConstituted → ReDraft → re-present | else: next site) — and only when the sites run out with no such exit: ReDraft(every unconstituted slot, against the values just constituted) → re-present] -- no arm runs ReDraft twice; an arm that exits runs none, since the exit is defined as preceding it
] ) until Sufficient →
FinalizeTopology(CT, constituted_axes, CT_draft) → (CT, residuals, topology_degradations) → AssignMoves(MS, CT) → move_assignment → RegisterCheckpoints(WP, CT) → checkpoints →
SubstrateFeasibility(CT) → SH → AnnotateHandoff(CT) → CarryPointer → CompileCheckpointBrief(checkpoints, WP, CT, MS) → RecordDegradation(SH, CT) → degradations → AssembleTraceContract(residuals, degradations, derived_coverage_limits(CT), derived_termination_grounds(CT, move_assignment)) → TC → converge(conduct trace: move assignment + handoff annotations + checkpoint briefs + trace contract, one surfacing op per element in TOOL GROUNDING) → handoff(ConductedMethod) → ConductedMethod ]
── MORPHISM ──
WorkProspect × MoveGround
→ brief(method, conduction_warrant) -- infer the work prospect's method-brief; judge whether conduction is warranted
→ guard(relay_test, anti_self_application) -- single-move work relays to that one protocol; Hyphegesis does not conduct Hyphegesis
→ identify(moves) -- candidate cognitive moves read off the move ground, presented for Recognition (`Recognition over Recall`)
→ select(moves) -- user confirms the move set via Cognitive Partnership Move (Constitution)
→ draft(conduct_topology) -- fill every axis·region with a reasoned value shown beside the alternatives it displaces, and propose the region cut carrying what was read to cut that way and the affordance to replace it — the cut's half differs because partitions are not enumerable, not because it is exempt; so the whole method is legible before any of it is answered
→ design(conduct_topology) -- the user points at the slots the draft got wrong; each pointed-at slot opens its own gate, highest-leverage first among them, and a pointed-at cut is settled alone because it re-keys the rest. Every value the user constitutes is pinned; the draft re-fills around it. Edge-local over move-regions; FinalizeTopology replaces the current pass's residual/degradation products, and once the moves are placed by the arrow below, checkpoint registration replaces the checkpoint set from the current CT + WP. Deferred decisions whose evidence does not exist yet register there
→ assign(moves, topology) → move_assignment -- place every selected move into a region of the resolved topology and into its slot under that topology's order; it is a field the emitted plan carries in its own right
→ annotate(substrate_feasibility) -- per resolved topology, surface substrate realizability as a handoff annotation
→ carry(work_pointer) -- carry the navigation block the work arrived under onto the emitted artifact, whole and unchanged. The pointer travels; the record's contents do not, so the executing substrate and any later session reach the canonical record itself rather than a copy that could silently disagree with it
→ compile(checkpoint_briefs) -- for every registered deferred decision, compile the decision-typed Recognition presentation contract the substrate executes there (structure, not content)
→ contract(trace_disclosure) -- assemble the cross-cutting disclosure overlay: residuals + degradations + coverage caps + termination grounds (one per region whose resolved termination needs a stop parameter — until_goal_met(g), bounded_rounds(n), until_dry_ceiling(k), or an emergent value declaring needs_stop_ground — each read off the value that carries it); surfaced, never silent
→ handoff(conducted_method) -- emit the method plan + in-session checkpoints, then stop (substrate executes)
→ ConductedMethod
requires: method_underdetermined(WP) -- runtime checkpoint (Phase 0)
deficit: MethodUnderdetermined -- activation precondition (Layer 1/2)
preserves: WP -- work prospect read-only
invariant: Conduction over Substrate
── TYPES ──
WP = WorkProspect: the work or goal facing object-level cognition, with its method (conduct plan) not yet determined
MG = MoveGround: what this session affords as candidate moves — the accumulated session context, the documented deficit/resolution declaration of each protocol available to it, and the analysis passes and delegations the session itself affords
Move = CognitiveMove { step: protocol invocation | analysis pass | delegation }
MS = MoveSet: (WP × MG) → {Move₁ … Moveₙ} -- MoveId yields n ≥ 2 under the warrant; a Phase 1 selection may reduce it, and |MS| < 2 is what the Phase 1 relay terminals handle
A_s = SelectionJudgment ∈ {Confirm(MS')}
A_w = BriefJudgment ∈ {Accept, Amend(WP')} -- Amend carries the corrected prospect: this protocol is Hybrid, so the Phase 0 gate is where the AI-inferred WP is constituted
MethodBrief = AI-inferred summary of WP: { work_intent, expected_handoff, span } -- span = invocation → the next planned /compact or /clear
Warrant = ConductionWarrant ∈ {warranted, relay} -- warranted = moves ≥ 2 ∧ conduct non-trivial; relay = single-move ∨ trivial
MoveRegion = a contiguous sub-graph of moves sharing one conduct treatment; the partition over MS is PROPOSED with the draft (DraftTopology reads MS's non-uniformity and cuts accordingly, citing what it read) and REVISED by the user, who reaches that revision from either gate. Proposer and reviser are both surfaced: a proposed cut is a draft slot the user can open like any other, so proposing it constitutes nothing
axis ∈ {order, independence, reconciliation, termination, routing}
Emergent(a) = a conduct value for axis a that the presented Gen set did not name, constituted at that axis·region's gate — the user's affordance, since a value the presented set did not name cannot be named by whoever is doing the presenting. It carries the obligation classes it falls under — relaxes_isolation, needs_stop_ground, crosses_span — declared with the value, because every downstream obligation below dispatches on the CLASS, not on a named value's identity; an emergent value declaring none carries none
Gen(order) ∈ {sequential_chain, parallel_fan, dependency_dag} ∪ Emergent(order)
Gen(independence) ∈ {isolated, shared} ∪ Emergent(independence)
Gen(reconciliation) ∈ {aggregate, dialectic, adversarial_refute, synthesis} ∪ Emergent(reconciliation)
Gen(termination) ∈ {single_pass, bounded_rounds(n), until_dry_ceiling(k), until_goal_met(g)} ∪ Emergent(termination) -- g ∈ {protocol_contract(ref), stated_condition(ref), resolution_required(resolver)}. The stop parameter travels INSIDE the value for every member that takes one, so whoever fills the slot carries it and no separate producer is needed. What a gate adds is the user's constitution, not the parameter. until_goal_met is no exception, and that is what makes the set uniform: a ground settled at fill time but left outside the value would have to be re-found at Phase 3 from a CT that does not hold it
Gen(routing) ∈ {return_to_user, chain_to_next, handoff_to_protocol(target), deepen_on_finding, handoff_to_span} ∪ Emergent(routing) -- handoff_to_protocol carries the protocol it routes to INSIDE the value, so the handoff is dispatchable without a second lookup whoever filled the slot; handoff_to_span: the move/region output crosses the span wall to a future span that does not share this session's context
ResolvedValue⟨a⟩ = per-axis resolved value, axis-typed:
ResolvedValue⟨reconciliation⟩ = RVᵣ = Gen(reconciliation) ⊕ Compose(RVᵣ, RVᵣ, op) -- RVᵣ abbreviates this same type: a composite's operands are themselves resolved reconciliation values, so composites nest
ResolvedValue⟨order⟩ = Gen(order); ResolvedValue⟨independence⟩ = Gen(independence); ResolvedValue⟨termination⟩ = Gen(termination); ResolvedValue⟨routing⟩ = Gen(routing)
op ∈ {⨾ sequential, ∥ parallel} -- extensible at operator level
CT = ConductTopology = Map(axis → Map(MoveRegion → ResolvedValue⟨axis⟩))
default(a) = ⟨order: sequential_chain, independence: isolated, reconciliation: synthesis, termination: single_pass, routing: return_to_user⟩[a] -- the per-axis fallback, used for a slot the draft could not ground and by FinalizeTopology for any slot still unfilled. termination falls back to the one value needing no stop parameter, so Sufficient always yields an executable method; every other member arrives WITH its parameter, from the draft or from a gate alike, and the fallback never binds one with the parameter unset — which is the whole reason the fallback is single_pass
CT_draft = Map(axis → Map(MoveRegion → DraftSlot)) over the proposed cut -- the whole topology filled before anything is asked. TOTAL over the cut's slots: every axis·region carries a DraftSlot, so accepting the draft always yields an executable method and no slot reaches the user blank. And CURRENT: whatever changes a slot's disposition leaves it holding a WHOLE candidate, and nothing takes a candidate the user has not been shown. A constituted slot's entry is the exception that proves it — that entry may sit stale precisely because nothing reads it while the pair is constituted, so the step that un-constitutes it is the step that owes it a fill
DraftSlot = { value: ResolvedValue⟨axis⟩, ground: Option(String), differential: Set(alternative × implication) }
-- ground = Some(g): the reasoning that picked this value over the others, cited to what it read (the work prospect's own method brief, the move set, a value already constituted, a cut just revised). ground = None: nothing preferred any value, so the slot carries default(a) and says so — a materially different fact from a grounded fill, and the residual record keeps the two apart
alternatives(a) = the NAMED members of Gen(a) ∪ Emergent-affordance ∪ [a = reconciliation] Compose-affordance -- fixed by the axis alone, so it is read off a rather than kept beside each slot's value
-- one rule, applied twice: alternatives(a) ENUMERATES what is closed and carries an AFFORDANCE for each part that is open. Closed here is the named members of this axis's Gen set — every one of them, so the draft conceals no candidate it already analysed. Open on every axis is Emergent(axis), which Gen(axis) also contains and which the presenter by definition cannot name, so quantifying over Gen(axis) itself would demand the unnameable; the affordance to constitute an Emergent value travels instead. Open on reconciliation additionally is the composites, which nest, so naming them is as unmeetable as enumerating the partitions of MS — the affordance to COMPOSE travels there. Without that second one, the axis whose values reach furthest past its named set would be the axis whose draft can hide a whole kind of value, since a slot taken as drafted never opens the gate where the composites are surfaced
-- differential states, for the alternative(s) that would most change the downstream plan, what changes if the slot goes that way. Bounded on purpose: naming all values is what keeps the taxonomy whole, and spending the differential where the plan actually turns is what keeps the draft readable. The full per-value trade-off unfolds at the gate the user opens
Site = (axis × MoveRegion) ⊎ CutSite(partition: Option(Set(MoveRegion))) -- a slot of the draft the user can point at. CutSite is the proposed region cut itself, and it CARRIES its revision the way every other answer here carries its payload: Some(p) supplies the cut to use, None says only that the proposed one is wrong and hands the next proposal back to the draft, citing what was rejected. Both settle alone — the round ends either way, because the region names are being replaced either way. Without the payload the cut branch would have no producer for the partition ReviseCut needs, and the branch forecloses the gate that would otherwise elicit it
DM = DraftJudgment ∈ {Sufficient, Open(Set(Site))} -- the draft gate's answer. Sufficient = take the topology as drafted; Open(sites) = these slots are wrong, open them. Silence is none of the two: it carries Stop and accepts nothing
AxisGate = { axis, region, options, drafted_value, basis, differential: Set(option × implication) } -- opens only for a pointed-at site; options is the full Gen set (plus composites on reconciliation), drafted_value is what the draft had put there, and differential carries the per-value implications `Round composition` requires the gate to present. This is where the draft's bounded differential is repaid in full: the draft spends it on the alternative that most moves the plan, the opened gate carries every option's. The gate OPENS ON WHAT THE SURFACE SHOWED — so at a slot the user already constituted and has now re-opened, that is their own value and never the draft's pre-gate entry, which is the value they replaced; and where the surface's basis predates something they constituted earlier in the same round, the gate says so rather than passing it off as current
DraftTopology(MS, WP) = (proposed cut, CT_draft) -- read MS's non-uniformity for the cut and fill every slot over it. An AI reading presented for Recognition, never a selection: nothing here enters constituted_axes
ReDraft(CT_draft, constituted_axes) = CT_draft with every UNCONSTITUTED slot re-filled against what is now constituted, except that a value CarryConstituted just carried is the user's own and stays — what it displaces is a fact about the region now in force and is redrawn there — and every constituted slot's own entry left untouched -- untouched is not the same as holding what the user set: what the user set lives in CT under constituted_axes, and this entry stays at the pre-gate value the draft had put there, read by nothing while that pair is constituted. Re-grounding is why a decision made in one ROUND cannot leave a stale reason standing in the next. The round is the unit, not the gate — re-grounding between the gates of one round would move the ground out from under a round the user composed in one act, so a later gate carries that surface's basis and says so instead
ReviseCut(partition: Option(Set(MoveRegion))) = Some(p): replace the region keys of the four edge-local axes of the DRAFT with p — the draft's keys only, so CarryConstituted still reaches the constituted values under their old keys. None: hand the cut back to DraftTopology, which proposes a different one citing the rejected proposal as what it read. The None arm is reached from CutSite(None) ONLY, because pointing at the cut is what says the cut is wrong. Reorient(a, None) does not call this function at all — supplying no partition there asserts nothing about the cut, so that slot alone returns to the draft over the current keys and the round continues. Either way order's single {whole} key is untouched, so the constituted global sequence survives every re-cut. The Option is what lets a user reject a cut without having to author its replacement — the AI proposes, the user disposes, exactly as at every other slot
CarryConstituted(constituted_axes, partition) = for each (a, r) ∈ constituted_axes with a ≠ order whose region r the new cut replaces: DROP the pair from constituted_axes, and seed each replacement region overlapping r with the value Λ.topology holds at that pair as its DRAFT, ground = "carried from the value you set on r"
-- the value is read from Λ.topology, since constituted_axes holds pairs and no values. ReviseCut re-keys the DRAFT, so that value is still under its old key when this step runs
-- a replacement region may overlap SEVERAL old regions, and the values they carry may differ; a slot holds one. Which carried value it takes is NOT settled by a precedence rule here, for the reason TerminationGround gives for its own: the reading that picks it is over this session's context, and a rule written now would have to rank grounds this protocol cannot read into. What IS fixed is the disclosure — the ground names every carried value with the region it came from. The ground and not alternatives(a), which is typed over the Gen set alone and could not hold a carried Compose. So a merge can leave a choice of the user's un-taken, but never un-shown
-- the value survives as a candidate the user can see and change, never as a constitution. That distinction is the whole guard: a silent survival would let a name the new cut happens to reuse read as already-constituted and let FinalizeTopology take a value belonging to the previous cut. Carrying it in the draft layer instead is what stops the user being asked the same axis once per re-cut
Checkpoint = { region: MoveRegion, decision: DeferredDecision, brief: Option(CheckpointBrief) }
DeferredDecision ∈ {SynthesisOutputShape} ∪ Emergent(DeferredDecision) -- a non-axis decision whose deciding evidence exists only at the checkpoint
CheckpointSet = ordered Set(Checkpoint) -- ordered by topology order between regions, with registration order breaking ties
CheckpointBrief ∈ {SynthesisBrief} ∪ Emergent(CheckpointBrief) -- one realization named today; every realization presents pre-gate evidence refs, private-gap slots, and candidates with differential implications, each as Slot(T)
SynthesisBrief = { findings_ref: Map(Move → Slot(output_ref)), convergences: Slot(Set(finding)), divergences: Slot(Set(finding)), decision_axes: Slot(Set(decision_axis)), private_gap_slots: Set(GapSlot), fusion_candidates: Slot(Set(fusion_candidate)), output_shape_candidates: Slot(Set(OutputShape)) } -- the Recognition presentation contract for SynthesisOutputShape
Slot(T) = a typed placeholder compiled at design time and filled with T by the substrate at execution
GapSlot = { category: a limit category the assigned move's protocol contracts to report, content: Slot(filled ∨ declined) }
OutputShape = the first-class unit the synthesis output is organized around -- an open organizing unit, not an enum: the candidate space is never fixed in advance
checkpoint_set(WP, CT) = { Checkpoint(r, d, None) | r ∈ dom(CT[reconciliation]), d ∈ deferred_decisions(WP, CT, r) }
deferred_decisions(WP, CT, r) = the non-axis decisions this pass identifies for region r whose deciding evidence does not exist at design time and does exist at the checkpoint; SynthesisOutputShape ∈ it when CT[reconciliation][r] contains synthesis ∧ (CT[routing][r] ∈ {return_to_user, handoff_to_span} ∨ CT[routing][r] declares crosses_span) -- keyed on the crosses_span obligation class as well as the named value, so an emergent routing that crosses the span wall registers the same checkpoint the named one does
compile_checkpoint_brief(c, WP, CT, MS) = the CheckpointBrief realization c.decision calls for, compiled from current CT + MS; SynthesisOutputShape → SynthesisBrief
SH = SubstrateHandoff = { feasibility: Map(MoveRegion → FeasibilityAnnotation), annotations: Set(HandoffAnnotation) }
FeasibilityAnnotation = { realizable: Bool, basis: String } -- the per-region substrate-realizability verdict; basis cites the inventory evidence it rests on
HandoffAnnotation = SpanExternalization(region: MoveRegion, record_surface: Option(String)) -- carries the externalization obligation a handoff_to_span region's seam declares; record_surface names the durable surface SubstrateFeasibility proposed, and is None exactly when that region was found unrealizable — the obligation still travels, beside the substrate_infeasible degradation the same pass records
span_externalization(r, CT, SH) = SpanExternalization(r, SH.feasibility[r].realizable ? Some(SH.feasibility[r].basis) : None)
VM = ConductMove ∈ {Select(value), Compose(left: RVᵣ, right: RVᵣ, op), Reorient(axis, partition: Option(Set(MoveRegion))), Sufficient} -- the answer at an OPENED axis gate. Compose carries BOTH operands the composite type needs, together with the operator; this MOVE is what writes Compose(left, right, op) into CT when the user makes it. A composite is a ResolvedValue like any other, so it can equally stand as a draft value and reach CT through Sufficient; the slot's ground says which happened -- partition is the revised region cut the user's reframing supplies. The cut has one PROPOSER and one REVISER, both visible: DraftTopology proposes it (surfaced as CutSite, constituting nothing), and the user revises it. The user reaches that revision from either gate — pointing at the cut at the draft gate, or supplying a partition in this move at an opened one — and both land on ReviseCut and end the round, since the hazard is the same one either way. A partition arriving here ends the round exactly as a pointed-at CutSite does, because the hazard is the same one either way
Sufficient = a MOVE in the axis gate as well as an answer at the draft gate → converge elicitation (user Constitution declaration) -- it takes what the last presentation SHOWED, so where the round has since re-filled a slot, the move re-presents before it can take anything
ResidualAxis = { axis, region, ground: Option(String), reason } -- an axis·region the user did not constitute at a gate. ground = Some(g): the draft filled it on ground g and the user took the topology as drafted without opening this slot; ground = None: nothing grounded a preference, so it carries default(a). The two are different facts about the same slot and the trace states which one holds — a value reasoned-and-accepted is not a value nobody had a reason for. When the Sufficient that took the topology was moved at an opened AxisGate, that exit precedes the round's trailing ReDraft, so a ground carried here can predate a value the user constituted earlier in the same round; reason says so where it does. That is a QUALIFIER on the grounded disposition, not a fourth one: the slot was still reasoned and still taken as drafted, and what reason adds is that its reason is older than the round. The dispositions stay the three `Convergence evidence` fixes. The field is widened rather than split into constructors because no phase branches on the distinction; only the trace reads it
Degradation = { region: MoveRegion, kind ∈ {independence_relaxed, substrate_infeasible}, resolved_value, reason } -- a surfaced acknowledgment that a resolved value relaxes an epistemic guarantee or cannot be realized
FinalizeTopology(CT_partial, constituted_axes, CT_draft) = (CT, unconstituted_residuals(CT, constituted_axes, CT_draft), topology_degradations(CT)) where CT = { order ↦ { whole ↦ take(order, whole) } } ∪ { a ↦ { r ↦ take(a, r) | r ∈ regions } | a ∈ {independence, reconciliation, termination, routing} } and take(a, r) = CT_partial[a][r] if (a,r) ∈ constituted_axes, else CT_draft[a][r].value if the draft filled that slot, else default(a). The third arm is a safety net, not a reachable path: every cut revision runs ReDraft before the draft is presented again, and Sufficient can only follow a presentation, so a well-formed run reaches here with every slot drafted. Should it ever fire, the CT stays well-formed rather than partial while topology_drafted_whole refuses the convergence. regions = ⋃_{a∈dom(CT_draft)\{order}} dom(CT_draft[a]), or {whole} when that is ∅ — the CURRENT cut and nothing else. CT_draft is TOTAL over that cut, so its domains ARE the cut, and CT_partial's are not: after a re-cut Λ.topology still holds its edge-local entries under the SUPERSEDED keys, because reading the carried values from exactly there is what CarryConstituted does. Unioning those in would put a region the cut replaced back into the final CT, and by then its pairs have already left constituted_axes and the re-keyed draft has no slot for them — so it would arrive on default(a) across all four axes and hand AssignMoves a second region every move of the replaced one also belongs to. The order axis is outside the cross-product by construction, not by convention: Gen(order)'s values are whole-graph shapes and order_position is a slot in a single sequence, so order resolves at {whole} regardless of how fine the partition gets — otherwise a finer cut would leave AssignMoves, checkpoint ordering, and frontier binding with per-region orders and no cross-region one. The remaining four axes are edge-local over regions
unconstituted_residuals(CT, constituted_axes, CT_draft) = { ResidualAxis{axis: a, region: r, ground: CT_draft[a][r].ground when the draft filled that slot else None, reason: the corresponding fact — the draft reasoned this value and Sufficient took it as drafted, or nothing grounded a preference so it fell to default(a); and where that Sufficient was moved at an opened AxisGate, that the ground predates a value constituted earlier in the same round, since the axis-gate exit precedes the round's trailing ReDraft} | a ∈ dom(CT) ∧ r ∈ dom(CT[a]) ∧ (a, r) ∉ constituted_axes } -- every slot the user did not constitute produces exactly one record, and the record carries WHY it went unconstituted. Under draft-first the user saw all of them, so "unsurfaced" would be the wrong claim to write here
topology_degradations(CT) = { Degradation{region: r, kind: independence_relaxed, resolved_value: CT[independence][r], reason: current relaxing resolution} | r ∈ dom(CT[independence]), CT[independence][r] = shared ∨ CT[independence][r] declares relaxes_isolation } -- r is BOUND by the region domain; unbound it left FinalizeTopology, degradation recording and convergence consuming an undefined set
substrate_degradations(SH, CT) = { Degradation{region: r, kind: substrate_infeasible, resolved_value: CT-value, reason: SH.feasibility[r].basis} | r ∈ dom(SH.feasibility) ∧ SH.feasibility[r].realizable = False }
CoverageLimit = { region: MoveRegion, bound ∈ {top_n, no_retry, sampling, emergent}, dropped: prose-scope, reason } -- a coverage cap the resolved topology imposes (what the method does NOT cover); dropped = the uncovered intra-region extent (prose)
Reference = { cites: String } -- a locator naming WHERE the referenced content is recorded, resolvable by the executing substrate at runtime
ref(x) = Reference { cites: the locator naming x } -- a CITATION of x — a pointer the executing substrate later dereferences and verifies at runtime — never a copy of x's compiled form
TerminationGround = { region: MoveRegion, ground ∈ {protocol_contract(ref), stated_condition(ref), resolution_required(resolver), round_bound(n), dry_ceiling(k)} } -- recorded per region whose termination resolved to a value that needs a stop parameter, and READ OFF THAT VALUE in every case: round_bound(n) from bounded_rounds(n), dry_ceiling(k) from until_dry_ceiling(k), and from until_goal_met(g) the g it carries — the referenceable ground that makes "goal met" determinate, being a condition the accumulated context makes available at this region, one of the assigned protocols' own convergence contracts, or resolution_required naming the party that owes the definition (an assigned move's own protocol, /apportion for a delegation move, or the user at execution). single_pass needs none. Which one a region takes is NOT settled by a fixed precedence table: whoever FILLS the slot settles it there and carries it in the value — a single available candidate as relay, and where several compete or none is available, the DRAFT takes one (or resolution_required) and its ground names the competitors, so the user meets the choice on the draft surface and opens that slot to settle it. Where the fill takes resolution_required, whether that resolver can reach the region is the same reading Phase 3 marks unroutable by, and it is available HERE — it turns on who the resolver is and when the plan runs them, both of which the fill already knows — so the ground says it on the surface the user can open. Phase 3's mark is then that reading's final disclosure rather than its first notice, which is the whole difference: Phase 3 surfaces and dispatches in one turn. A fill-time reading is a reading taken THEN, against the plan as it stood — an earlier notice, never a guarantee that survives what the rest of the loop does. Order can change after it and a resolver's reach turns on order; a re-cut can move the condition a g cites. So every ground travels with what it was read against, and Phase 3's is the reading taken over the final plan. Riding inside the value is what makes that reachable: under draft-first the termination gate opens only where the user points, so a ground left outside would have to be re-found at Phase 3 from a CT that does not hold it, and the re-finding could land somewhere the draft's own disclosure said it would not. The branch still closes by fusing horizons with the user, not by a rule that would have to rank grounds this protocol cannot read into; what moved is where the fusing is offered, not whether it is
TC = TraceContract = { residuals: Set(ResidualAxis), degradations: Set(Degradation), coverage_limits: Set(CoverageLimit), termination_grounds: Set(TerminationGround) } -- the method's cross-cutting disclosure overlay over CT
derived_coverage_limits(CT) = every CoverageLimit required by CoverageLimit's source→bound functor over CT (single_pass → no_retry; bounded_rounds(_) or until_dry_ceiling(_) → top_n; an intra-region sampling → sampling; any other imposed cap → emergent)
derived_termination_grounds(CT, move_assignment) = one TerminationGround for each region in {r | (_, r) ∈ range(move_assignment)} whose resolved termination needs a stop parameter, read straight off that region's resolved value in every case — round_bound(n) from bounded_rounds(n), dry_ceiling(k) from until_dry_ceiling(k), the carried g from until_goal_met(g), and the stop reference constituted with an emergent value declaring needs_stop_ground. All of it is relay: the value already holds what this function reports, so there is nothing to fold by rule and no gate to reach for that Phase 2 has closed. Relay reports the reading the fill took, which is not a certification against the final placements — so what travels with each ground is what it was read against, and a reader weighs it rather than taking it as checked. That is also why these two operands are the whole signature — a function that had to re-find a ground would need the plan or its placements, and carrying the ground in the value is what removes the re-finding. A single_pass region contributes no ground
ConductedMethod = { topology: CT, move_assignment: Map(Move → ⟨order_position, region⟩), checkpoints: CheckpointSet, substrate_handoff: SH, trace_contract: TraceContract, work_pointer: Option(N) } -- the method PLAN; handed off (the substrate executes) -- order_position = the move's slot in the order topology (Gen(order) shape); the per-region axis values (independence/reconciliation/termination/routing) are read from CT[axis][region]. work_pointer is the navigation block the work arrived under — purpose/frame, canonical locator, dereference instruction, snapshot anchor, grounding instruction. The record's contents stay where that locator names, so the substrate and any later session dereference the canonical record rather than read a copy that could silently disagree with it
-- The work-record seam. A POINTER, not a structural import: this protocol carries the locator; it never restates what the record holds, re-derives it, or copies it onto its own output.
N = NavigationBlock { purpose_frame: String, canonical_locator: HandoffLocator, dereference_instruction: DereferenceInstruction, snapshot_anchor: Option(String), grounding_instruction: GroundingInstruction } -- the fixed cross-session shape; a pointer, never a copied record
HandoffLocator = { record: the durable identity of the record the work was parked in, session: the id of the session that parked it }
DereferenceInstruction = an instruction to read the parked record at the canonical locator's record identity, within the session that locator names
GroundingInstruction = the fixed instruction to run /inquire where available, or the recipient's equivalent grounding pass, and stop when a source is unreachable or a needed premise lacks support-integrity — and, when the dereferenced record carries reservations, to surface each as an open question together with the ground that settles it, worded so it invites an answer rather than suggesting one, since an answer suggested here would be a compile-time default standing in for the live one. A reservation is NOT a fourth stop condition: whether one blocks is read against the work actually at hand, which is this protocol's own topology question rather than something the incoming block decides
method_handed_off ≡ the assembled ConductedMethod was emitted to the substrate in the handoff output — the emission IS the text, so convergence is never true before the dispatch the MORPHISM's handoff arrow names
topology_drafted_whole ≡ every axis·region of the final CT reached the user before the gate that took it, by the route its own disposition affords: a slot the user CONSTITUTED reached them at the AxisGate they opened for it, which presented that axis's full set beside the drafted value; a slot still carrying a draft reached them in a DraftSurface presentation — its value, its ground, alternatives(a) named, and the differential where the plan turns. DraftSurface shows the CURRENT topology, not the draft record on its own: at a constituted slot it shows the constituted value marked as the user's, because ReDraft leaves that slot's draft entry at its pre-gate value and re-presenting THAT would show the user back the very value they rejected. AND the region cut it rests on reached the user in that same presentation, carrying what the draft read to cut that way and the standing affordance to replace it. The cut's half is shaped differently on purpose, not by oversight: what conceals nothing is naming an axis's named values and affording its open ones — Emergent on every axis, the composites on reconciliation — and the partitions of MS are open in that same way, so a demand to name them would be unsatisfiable rather than strict. Both halves fix one thing — nothing the user would want to change reached them looking settled. Both hold before the gate whose Sufficient took the topology, which is the DraftGate on the ordinary path and an opened AxisGate when Sufficient is moved there. Like method_handed_off, the presentation IS the text and no state flag stands in for it. This is what separates draft-first from removing the gate: a slot presented with one filled value and no alternatives was not drafted in this sense, and a slot never presented at all fails this conjunct outright. FinalizeTopology's default(a) arm exists so that such a run still yields a WELL-FORMED CT rather than a partial one — never so that it converges; the conjunct is what refuses it
conduct_trace_surfaced ≡ every element `Convergence evidence` requires was presented to the user in the turn's text before that dispatch, EACH CARRYING the disclosure `Trace contract` attaches to it: the per-axis·region topology trace by Phase 2 converge, and each of the remaining four by its own Phase 3 surfacing step. `Trace contract`'s conditional markings are inside this conjunct rather than beside it, and the unroutable ground is the case that turns on it — a trace contract can reach the user whole while the one row that owed a warning arrives reading exactly like a routable one, and "never silent" would then be discharged by a presentation that said nothing. The topology trace is produced once, at the pass that resolves it, and Phase 3 re-presents the placement it induced rather than the axis values themselves — so what this conjunct requires is that every element REACHED the user before the dispatch, not that all five issue from one phase. Like method_handed_off, the presentation IS the text and no state flag stands in for it. The two conjuncts therefore pin convergence to a window rather than a point: the trace has to precede the dispatch, and the dispatch has to have happened
── WP-BINDING ──
bind(WP) = explicit_arg ∪ colocated_expr ∪ prev_user_turn ∪ ai_identified_prospect
Priority: explicit_arg > colocated_expr > prev_user_turn > ai_identified_prospect
/conduct "text" → WP = "text"
/conduct (alone) → WP = the work prospect under discussion
"how should I approach..." → WP = the work named before the trigger
AI-detected trigger → WP = the multi-move prospect AI identified (Hybrid: user confirms at the Phase 0 guard gate)
work_pointer (bound alongside WP) = Some(N) when the accumulated context supplies a navigation block over the
record the work was parked in, PRIOR PROTOCOL OUTPUT INCLUDED — a sibling protocol's
emitted block is how one reaches this protocol in the same session, so this is
deliberately not bind(WP)'s source list above: a prospect is what someone states,
while a pointer is what the session already holds — a
navigation block, not a bare locator, because a later session dereferences from the
block's grounding and dereference instructions, not from the record identity alone;
None otherwise. One optional field, bound or not: the block is checked at Phase 0 by
ground_pointer and then carried unchanged, so what this protocol takes from the record
it names is that the pointer resolves — never its contents
── PHASE TRANSITIONS ──
Phase 0: WP → init_state(track: every pass-scoped Λ field to its empty value — sets to ∅, work_pointer and trace_contract to None; runs EXACTLY ONCE on activation, before any read) → retain_pointer(track: Λ.work_pointer := the navigation block the accumulated context supplies, None otherwise) → ground_pointer(observe: when Λ.work_pointer = Some(N), follow N.dereference_instruction at N.canonical_locator and run N.grounding_instruction) → [¬dereferenceable ∨ support-integrity failure: relay(handoff unreadable)(extension) → deactivate | grounded ∨ work_pointer = None: continue] → MethodBrief(WP) → guard[relay-test, anti-self-application] → warrant? → [warrant=relay: relay_route(extension) → deactivate | warrant=warranted: Qc(brief, conduction-warrant) → Stop → A_w → [A_w = Accept: continue | A_w = Amend(WP'): Λ.work_prospect := WP' → re-enter Phase 0, rebinding work_pointer against the corrected prospect]] [Tool]
Phase 1: (WP, MG) → MoveId(WP × MG) → Sc(MoveSet) → Stop → A_s → [Tool]
A_s = Confirm(MS') → MS := MS' →
[|MS| = 1: relay-route to the surviving move, deactivate
| |MS| = 0: relay(no move survives — nothing to conduct or route to), deactivate
| Phase 2]
Phase 2: MS → DraftTopology(track: read MS's non-uniformity for a proposed cut, fill every axis·region over it with everything a DraftSlot carries — a grounded value and the differential where the plan turns — shown beside alternatives(a)) → CT_draft →
loop( DraftSurface(extension: present the whole CURRENT topology — the proposed cut; each constituted slot as the value the user set, marked as theirs and not re-offered as a candidate; each unconstituted slot as its draft value with its ground, alternatives(a) named, the differentials) →
DraftGate(constitution: take it as drafted, or name the slots to open) → Stop → DM ∈ {Sufficient | Open(Set(Site))} →
[DM = Sufficient: exit
| DM = Open(sites) ∧ CutSite(p) ∈ sites: ReviseCut(p)(track) → CarryConstituted(track) → ReDraft(track) → re-present -- settled ALONE: every other pointed-at site names a region about to be replaced, so opening one here would ask over a name that is already gone. p = None re-proposes rather than stalling, so rejecting a cut never requires the user to author its replacement
| DM = Open(sites) ∧ no CutSite ∈ sites: for each site ∈ sites in impact/leverage-first order — most-constrained first: AxisGate(full Gen set + drafted value + basis + per-value differential implications; [reconciliation axis ONLY: + ⨾/∥ composites + affordance]) — the round's gates ALL run before its trailing ReDraft, so a gate after the first carries the basis this round's surface had and discloses that it predates what an earlier gate constituted → Stop → VM ∈ {Select | Compose(reconciliation only) | Reorient | Sufficient} → update(CT, constituted_axes) → [VM carries a partition: ReviseCut(track) → CarryConstituted(track) → ReDraft(track) → re-present, abandoning the rest of this round for the same reason | VM = Sufficient: exit the loop — this exit is BEFORE the trailing ReDraft, so each slot it takes carries the ground it was last drafted with, which may predate a value constituted earlier in this same round. It is not re-presented for that: a user closing at a gate is not sent back to look again over a reason that shifted, and what the round owes instead is the record — the residual for such a slot says its ground predates that round's own constitutions (ResidualAxis). A slot whose VALUE changed since that presentation is the different case: Sufficient takes only what was SHOWN, so the loop re-presents and re-opens the DraftGate instead of exiting | else: next site] → ReDraft(track: re-fill every unconstituted slot against the values just constituted) → re-present
] ) until Sufficient →
FinalizeTopology(track: replace CT + residuals + topology-derived degradations) → AssignMoves(track: replace move_assignment) → RegisterCheckpoints(track: replace checkpoints from checkpoint_set(WP, CT)) → converge(topology trace) -- the DraftGate always yields the turn, on this pass and on every re-presentation; silence carries Stop and accepts nothing [Tool]
Phase 3: CT → SubstrateFeasibility(extension) → SH → AnnotateHandoff(track) → CarryPointer(track) → CompileCheckpointBrief(track) → RecordDegradation(track) → AssembleTraceContract(track) → TC → converge(conduct trace: move assignment + handoff annotations + checkpoint briefs + trace contract, one surfacing op per element in TOOL GROUNDING) → handoff(ConductedMethod) → deactivate -- trace BEFORE dispatch (`Convergence evidence`): handoff is a delegate dispatch that starts the substrate, so evidence shown after it would arrive after execution began. converge NAMES the evidence presentation here, not the terminal predicate: conducted(WP) requires method_handed_off as well, so it holds at this phase's terminal — after the dispatch — never at the trace step, even though this step is what discharges its conduct_trace_surfaced conjunct. Phase 2's converge(topology trace) is the same verb for a mid-protocol relay and likewise asserts no terminal [Tool]
── LOOP ──
After Phase 0 (Method Brief + Warrant):
warrant = relay → relay-route: the single resolving protocol, or — when conduct is trivial rather than single-move — the brief's own evident method; emit it as the routing, deactivate (conduction not needed)
warrant = warranted → Phase 1 → Phase 2 → Phase 3
During Phase 2 (Conduct Design — topology elicitation):
Entry surface: DraftTopology fills the WHOLE topology first — a proposed region cut, and over it every axis·region carrying a value, the ground that picked it, the other values by name with a standing affordance for the ones no list reaches, and the differential for the alternative(s) that would most change the plan. Present that draft as relay text, then open the DraftGate and yield. The draft is a surfaced candidate throughout, not an Extension-selected method: nothing in it enters constituted_axes, and silence carries Stop and accepts none of it. Sufficient is the explicit user act that takes the topology as drafted.
Each cycle presents the METHOD whole — a slot the user has settled shows their value marked as theirs, every other slot shows its draft — and asks only which slots are wrong. Impact/leverage survives as ORDER, not as gating: the draft is laid out most-constrained-first (the axis·region whose values most divide the downstream conduct-plans leads), and when the user opens several slots, those gates fire in that same order. What the user no longer does is answer one axis while the rest of the method does not yet exist. A decision defers past design time only when its deciding evidence does not yet exist; such a decision is never drafted as a Gen-typed axis value, and registers through the generic Checkpoint record after topology finalization.
DM = Sufficient → exit elicitation → FinalizeTopology takes every unconstituted axis·region from the draft (or from default(a) where the draft never reached it) and REPLACES Λ.residuals with exactly one ResidualAxis per unconstituted final-CT value, each carrying the ground the draft gave it or None where there was none
DM = Open(sites), CutSite ∈ sites → ReviseCut, then CarryConstituted, then ReDraft, then re-present. Settled ALONE, and this is the clause the whole draft-first shape turns on: re-cutting replaces the region keys of the four edge-local axes, so any other slot opened in the same round would be answered over a region name that is already gone. That is the one defect a whole-draft surface does not fix by itself
DM = Open(sites), CutSite ∉ sites → open each pointed-at site as its own AxisGate, most-constrained first, then ReDraft the unconstituted slots against what was just constituted and re-present. Re-drafting is what keeps a later ROUND's slot from being judged against a reason an earlier answer already retired. Inside the round it does not run between gates: a gate after the first carries the basis this round's surface had and discloses that, which is what the user answers against rather than a ground shifted under them mid-round
Each opened AxisGate integrates one ConductMove and updates MODE STATE:
VM = Select(value) → record axis·region → Gen(value) in CT; constituted_axes ∪= {(axis, region)} -- value is a named Gen member or an Emergent(axis) one the user proposes at the gate: the presented set aids Recognition and never bounds the space, so an emergent value records exactly like a named one
VM = Compose(left, right, op) → [reconciliation axis ONLY] record reconciliation → Compose(left, right, op) in CT; constituted_axes ∪= {(reconciliation, region)} -- all three come from the well-formed composite the gate surfaced and the user adopted; the arm binds the operands rather than re-deriving them
VM = Reorient(axis, partition) → remove the (axis, region) pair from constituted_axes and CT[axis][region], and RE-FILL that slot in this same move — the entry standing there is the pre-gate value the user rejected when they constituted it, and a later Sufficient in this same round exits before the trailing ReDraft, so FinalizeTopology would take the rejected value; the step that un-constitutes owes the slot its current fill — returning it to the draft over its own current keys — {whole} when axis = order, whatever the partition, since order resolves at {whole} by construction; the replacement regions for an edge-local axis under a new partition; the same region otherwise. When partition ≠ None this ends the round exactly as a pointed-at CutSite does: ReviseCut replaces the region keys of the four edge-local axes, CarryConstituted DROPS every remaining edge-local pair from constituted_axes and re-seeds each replacement region with the value it dropped, as a DRAFT carrying "carried from the value you set on the previous region" as its ground. The drop is what keeps a name the new cut happens to reuse from reading as already-constituted and letting FinalizeTopology take a value belonging to the previous cut; the re-seed is what keeps the user from answering the same axis once per re-cut. Order's single {whole} key and its (order, whole) pair are untouched, so the constituted global sequence survives every re-partition
VM = Sufficient → exit elicitation, taking the rest of the draft as it stands — unless a Reorient(_, None) this round left a slot re-filled since the last presentation, in which case re-present and re-open the DraftGate first, because Sufficient takes only what was shown
BOUND: the loop is bounded by user agency — the user's Sufficient move terminates it. What the finite axis set now guarantees is stronger than a terminal: the draft is COMPLETE from the first presentation, so an executable method exists at every point of the loop rather than only at its end, and a run that opens only fresh slots exhausts them. A run that keeps re-opening the same slot is dialogue, and the user ends it.
Checkpoint registration (track — deterministic, never gated): RegisterCheckpoints REPLACES Λ.checkpoints with checkpoint_set(WP, CT) after every FinalizeTopology pass.
converge(topology trace) → Phase 3.
After Phase 3 (Handoff):
Hyphegesis conducts to the LAST checkpoint in CheckpointSet, then downstream-delegates — execution and anything past the last in-session checkpoint belong to the substrate or to the routed protocol. The span ends at the next planned /compact or /clear, which the user types; Hyphegesis does not detect or emit that wall.
A checkpoint may re-open Constitution mid-execution.
At a checkpoint, the substrate executes the compiled CheckpointBrief. At a synthesis checkpoint the two candidate sets carry a normative order: when both are live the output-shape decision resolves first and the fusion candidates are expressed in the selected unit. Hyphegesis compiles this contract; the substrate performs it.
Continue until convergence: warrant=relay deactivation, the conduct trace surfaced and the ConductedMethod then handed off (both events, in that order — handoff alone does not converge).
Convergence evidence: At handoff, present the per-move trace — for each Move, show (Move → its ⟨order_position, region⟩ in CT) — AND the per-axis topology trace — for each resolved axis·region, show either (axis·region → ConductMove → value) for a slot the user constituted at a gate, or (axis·region → value → the ground the draft gave it) for a slot taken as drafted, or (axis·region → default(a) → no ground preferred any value) for a slot nothing grounded. The three are different facts and the trace must not flatten them into one: a value reasoned and accepted is not a value nobody had a reason for, and neither is a value the user chose — AND the SubstrateHandoff annotations and the exact current-pass CheckpointSet (with every checkpoint's decision-typed compiled CheckpointBrief) — AND the trace contract: the cross-cutting disclosure overlay (every final-pass residual, every degradation, every coverage cap the topology imposes, and every stop-parameter-bearing region's termination ground, a resolution_required ground shown with its owed resolver and marked unroutable where the reading finds that resolver unable to reach the region before its stop is wanted, the basis for that reading shown with it), never silent. Convergence is demonstrated, not asserted: any figure this trace states about its own contents is read off the rows it has just shown, never computed beside them, since a second computation can disagree with the rows it sits under and the reader holding both cannot tell which one the method means (`Convergence evidence`).
── CONVERGENCE ──
conducted(WP) = method_handed_off
∧ topology_drafted_whole -- the whole method reached the user before the gate that accepted it: every axis·region with alternatives(a), and the cut with what was read to make it and the affordance to replace it. Without this conjunct the draft could shrink to a single filled answer and the run would still converge, which is the failure mode of removing a gate rather than folding it
∧ conduct_trace_surfaced -- every element `Convergence evidence` requires reached the user BEFORE the dispatch: the per-axis·region topology trace at Phase 2 converge, and move assignment, handoff annotations, checkpoint briefs and trace contract each by their own Phase 3 surfacing step. handoff is a delegate dispatch that STARTS the substrate, so a run that dispatched with an element unsurfaced never gets a correcting turn — this conjunct is what keeps method_handed_off from standing alone as the terminal
∧ dom(move_assignment) = MS
∧ (∀m ∈ MS: let ⟨pos, r⟩ = move_assignment(m) in
r ∈ dom(CT[independence]) ∧ m ∈ r ∧ pos is m's slot under CT[order][whole]) -- the assignment is INDUCED by the resolved topology: m must BELONG to the region it is assigned to, since MoveRegion is a sub-graph of moves and the four edge-local axis values are read at that region
∧ [ (c.region, c.decision) | c ∈ checkpoints in CheckpointSet's declared order ]
= [ (c.region, c.decision) | c ∈ checkpoint_set(WP, CT) in that same order ]
∧ (∀c∈checkpoints:
c.brief = Some(compile_checkpoint_brief(c, WP, CT, MS)))
∧ substrate_handoff ≠ None
∧ dom(substrate_handoff.feasibility) = {r | (_, r) ∈ range(move_assignment)} -- every resolved region carries a verdict; an uncovered region would yield neither annotation nor degradation and still converge
∧ residuals = unconstituted_residuals(CT, constituted_axes, CT_draft)
∧ degradations = topology_degradations(CT)
∪ substrate_degradations(substrate_handoff, CT)
∧ trace_contract ≠ None
∧ trace_contract.residuals = residuals
∧ trace_contract.degradations = degradations
∧ trace_contract.coverage_limits = derived_coverage_limits(CT)
∧ trace_contract.termination_grounds = derived_termination_grounds(CT, move_assignment)
∧ work_pointer = Λ.work_pointer -- the POINTER travels onto the artifact; the record's contents do not. What the substrate and any later session reach is the canonical record the locator names, never a copy this protocol re-authored — which is the whole reason the seam is a pointer
∧ (∀r ∈ dom(CT[routing]): (CT[routing][r] = handoff_to_span ∨ CT[routing][r] declares crosses_span) →
span_externalization(r, CT, substrate_handoff) ∈ substrate_handoff.annotations)
-- The ConductedMethod value this invocation constructs and, on convergence, hands off is well-formed exactly when conducted(WP) holds.
── TOOL GROUNDING ──
-- Realization: Constitution → TextPresent+Stop; Extension → TextPresent+Proceed
Phase 0 init_state (track) → Internal state update (seed every pass-scoped Λ field once, on activation: constituted_axes, checkpoints, residuals, degradations and move_assignment to ∅; work_pointer, topology, topology_draft and trace_contract to None. Every later empty-set read consults THIS write, never an implicit default)
Phase 0 retain_pointer (track) → Internal state update (write Λ.work_pointer: Some(N) when the accumulated context supplies a navigation block over the record the work was parked in, None otherwise. The block is retained rather than restated: ground_pointer dereferences it to check that it resolves, and no step binds what it names to a field of this protocol. The write is total, so an Amend re-entry never leaves a prior block standing over a prospect it no longer names)
Phase 0 ground_pointer (observe) → record read, artifact read (when Λ.work_pointer = Some(N): follow N.dereference_instruction at N.canonical_locator — the record that locator names, within the session it names — and run N.grounding_instruction. What this establishes is that the pointer RESOLVES and its load-bearing premises hold; nothing read here is written to Λ or onto the handoff artifact, which is what keeps the seam a pointer rather than an import. An unreachable locator, a locator missing either half, or a premise the grounding pass cannot support relays handoff-unreadable and deactivates — no method is designed against a record that could not be reached. A reservation the record carries is surfaced as the open question GroundingInstruction requires, and whether it blocks is read against the topology question at hand. work_pointer = None skips the step: there is no pointer to ground)
Phase 0 MethodBrief (sense) → Internal analysis (infer the work prospect's method-brief + span from the session)
Phase 0 guard (sense) → Internal analysis (relay-test: single-move ∨ trivial-conduct → relay; anti-self-application; no Λ mutation)
Phase 0 relay_route (extension) → TextPresent+Proceed (the relay-test's two causes, both read off the Method Brief because this branch precedes MoveId and no MoveSet exists yet: a single-move resolution routes to that one protocol as the recommendation; a trivial-conduct prospect presents the brief's evident method — self-evident enough that no topology is designed — naming the protocols it runs through rather than an identified move set. Either way, deactivate)
Phase 0 Qc (constitution) → present (conditional: warrant=warranted only — the guard decides warrant before this gate opens; work prospect confirmation + conduction-warrant; relay-test result as pre-gate text; the response is parsed as A_w — Accept proceeds, Amend(WP') writes Λ.work_prospect and re-enters the brief and its guard over the corrected prospect)
Phase 1 MoveId (observe) → artifact read, artifact search (read MG — the session context together with each available protocol's own deficit/resolution declaration — to identify candidate moves)
Phase 1 Sc (constitution) → present (MoveSet confirmation; multiSelect: true)
Phase 1 single-survivor relay (extension) → TextPresent+Proceed (|MS| = 1 sub-case of A_s = Confirm: route by the survivor's own step kind — a protocol invocation routes to that protocol as the recommendation; an analysis pass or a delegation is presented as the single move to perform. Deactivate either way)
Phase 1 no-survivor relay (extension) → TextPresent+Proceed (|MS| = 0 sub-case of A_s = Confirm: no move — and no protocol — survives to route to; present that finding directly and deactivate)
Phase 2 DraftTopology (track) → internal Λ update (read MS for the non-uniformity that motivates a region cut, then fill every axis·region over that cut with everything a DraftSlot carries — the value, the ground that picked it over the rest of alternatives(a), and the differential for the alternative(s) that would most change the plan. Write Λ.topology_draft. An AI reading, not a selection — nothing here touches Λ.constituted_axes)
Phase 2 DraftSurface (extension) → TextPresent+Proceed (present the WHOLE CURRENT topology as pre-gate relay context — the proposed cut with what was read to cut that way and the affordance to replace it, then every slot: an unconstituted one with its draft value, ground, alternatives(a) named, and its differential where the plan turns; a constituted one with the value the user set, marked as theirs and NOT re-offered as a candidate. Read those from Λ.topology, never from Λ.topology_draft, whose entry there is the pre-gate value ReDraft leaves standing — presenting that would hand the user back what they rejected and leave the value actually in force unpresented. Then proceed only to DraftGate; it selects no topology value. Naming every alternative is what keeps the draft from concealing a candidate it already analysed; spending the differential where the plan actually turns is what keeps it readable)
Phase 2 DraftGate (constitution) → present (always opens on Phase 2 entry for warranted work and again on every re-presentation; the question is which slots the draft got wrong, and the answers are {Sufficient | Open(Set(Site))}; Stop holds on silence and accepts nothing)
Phase 2 AxisGate (constitution) → present (conditional: opens for a pointed-at site only, one axis·region per gate, most-constrained first among the sites opened this round: the full Gen set + the drafted value + basis + per-value differential implications; reconciliation axis ONLY additionally surfaces ⨾/∥ composites + a one-line affordance; open on what the last surface showed — at a re-opened slot that is the user's own value from Λ.topology, and where the basis predates what an earlier gate this round constituted, say so; moves {Select | Compose(reconciliation) | Reorient | Sufficient}, where Sufficient exits only if nothing has been re-filled since the last presentation and otherwise re-presents first; Stop holds on silence)
Phase 2 ReviseCut (track) → internal Λ update (replace the region keys of the four edge-local axes OF Λ.topology_draft with the partition its argument carries — the draft's keys only; Λ.topology keeps its constituted entries under the old keys until CarryConstituted has read them — CutSite(Some(p)) or Reorient(_, Some(p)) — or, on CutSite(None), hand the cut back to DraftTopology to propose a different one citing what was rejected; order's {whole} key is untouched. Reorient(_, None) never arrives here at all: it supplies no partition, so it revises no cut — that slot alone returns to the draft over the current keys, RE-FILLED by the Reorient move itself, and the round continues, as LOOP and the phase prose both say. The two callers share the Option so neither path needs a producer the flow does not have, but their None does not mean the same thing — one rejects the cut, the other declines to supply one — and only the first re-proposes)
Phase 2 CarryConstituted (track) → internal Λ update (for every constituted edge-local pair whose region the new cut replaces: DROP it from Λ.constituted_axes, and seed each overlapping replacement region's draft slot with the value read from Λ.topology at that pair's old key — Λ.constituted_axes holds pairs and no values, and ReviseCut re-keyed the draft rather than the topology, so that is where the value still is. Ground = carried from the value the user set on the previous region. When a merge lands several differing carried values on one slot, take one by reading this session's context — no precedence rule is written here — and name all of them in the ground with their source regions. The drop is the guard — a reused region name must not read as already-constituted — and the re-seed is the payoff: the user answers an axis once, not once per re-cut)
Phase 2 ReDraft (track) → internal Λ update (re-fill every UNCONSTITUTED slot of Λ.topology_draft against what is now constituted and against the current cut; leave every constituted slot's entry untouched at the pre-gate value the draft had put there — what the user set lives in Λ.topology under Λ.constituted_axes, never in this entry, and nothing reads this entry while that pair is constituted. a value CarryConstituted just carried is the user's own and stays — replacing it with a fresh fill is the drift cut-drift guards — while what it displaces is redrawn for the region now in force. Runs at most once per round, the cut-revising arm included — never twice, and not at all on a round that exits before it)
Phase 2 FinalizeTopology (track) → internal Λ replacement (over the CURRENT cut, whose regions are read off Λ.topology_draft's domains and never off Λ.topology's — a re-cut leaves the latter keyed on regions the cut replaced — take every axis·region from Λ.constituted_axes, else from Λ.topology_draft, else from default(a); replace Λ.topology with the complete CT, Λ.residuals with exactly unconstituted_residuals(CT, constituted_axes, topology_draft), and Λ.degradations with topology_degradations(CT))
Phase 2 AssignMoves (track) → internal Λ replacement (PLACE every selected move from the current CT's order and region shape and REPLACE Λ.move_assignment with that exact map. This produces dom(move_assignment) = MS)
Phase 2 RegisterCheckpoints (track) → internal Λ replacement (write Λ.checkpoints := checkpoint_set(WP, CT) on every finalized topology pass: one checkpoint per deferred decision the pass identifies for a region)
Phase 2 converge (extension) → TextPresent+Proceed (topology trace: per resolved axis·region, either ConductMove → value for a slot constituted at a gate, or value → the draft's ground for a slot taken as drafted, or default(a) → no ground for a slot nothing grounded; every registered checkpoint appears brief-less here — briefs compile at Phase 3)
Phase 3 SubstrateFeasibility (extension) → TextPresent+Proceed (per resolved MoveRegion, compute and SURFACE a FeasibilityAnnotation{realizable, basis} as pre-gate relay text; for a region whose routing is handoff_to_span OR declares crosses_span, realizable/basis is exactly the proposed durable record surface or its absence — the externalization annotation reads this verdict back, so keying it on the named value alone would leave an emergent crossing with a record_surface computed on some other basis; an extension op surfaces only — it does NOT mutate Λ)
Phase 3 AnnotateHandoff (track) → internal Λ update (the FIRST write to Λ.substrate_handoff: MATERIALIZE Λ.substrate_handoff := Some(SH), folding SubstrateFeasibility's same-turn per-region verdicts into SH.feasibility, then attaching span_externalization(r, CT, SH) into SH.annotations for every region whose CT[routing][r] is handoff_to_span or an emergent routing value declaring crosses_span. The set is ∅ when that condition holds for no region)
Phase 3 CarryPointer (track) → internal Λ update (Λ.work_pointer is carried onto the handoff artifact whole and unchanged. The record's CONTENTS are not copied: they stay in the record the locator names, so the substrate and any later session dereference the canonical record instead of a copy that could silently disagree with it. When the context supplied no navigation block, work_pointer stays None)
Phase 3 CompileCheckpointBrief (track) → internal Λ update (for every c in the current registry, write c.brief := Some(compile_checkpoint_brief(c, WP, CT, MS)). SynthesisOutputShape receives SynthesisBrief's findings/convergence/divergence/private-gap/fusion/output-shape slots — a presentation contract of structure only, never a copy of execution content)
Phase 3 RecordDegradation (track) → internal Λ update (write the current substrate_degradations(substrate_handoff, CT) beside the topology_degradations(CT) FinalizeTopology produced, yielding their exact union. The union is not separately externalized: AssembleTraceContract folds it into Λ.trace_contract, which the trace surfaces and the handoff artifact carries)
Phase 3 AssembleTraceContract (track) → internal Λ update (ASSEMBLE the cross-cutting disclosure overlay: populate Λ.trace_contract from Λ.residuals + Λ.degradations + derived_coverage_limits(CT) + derived_termination_grounds(CT, move_assignment); an INVARIANT aggregation, never gated)
Phase 3 surface move assignment (extension) → TextPresent+Proceed (surface Λ.move_assignment as the final pass left it: every selected move with the region it was placed in and its slot under the resolved order. The topology trace Phase 2 converge presented carries the axis VALUES; this carries the placement those values induced, which is a different reading and the one `Convergence evidence` requires before dispatch; relay only — it does NOT mutate Λ)
Phase 3 surface handoff annotations (extension) → TextPresent+Proceed (surface Λ.substrate_handoff.annotations whole: span_externalization(r, CT, SH) for every region whose output must cross a span wall. The set is ∅ when its condition holds for no region, and the emptiness is surfaced rather than omitted; relay only — it does NOT mutate Λ)
Phase 3 surface trace contract (extension) → TextPresent+Proceed (surface the trace contract in the convergence trace: every residual, degradation, coverage cap, and termination ground — each ground shown with WHAT IT WAS READ AGAINST, since a ground filled earlier in the loop was read against the plan as it then stood and this trace is where a reader weighs it against the final one. A resolution_required ground names its owed resolver, and is MARKED UNROUTABLE when the resolver it names cannot reach the region before that region's stop is wanted. This is a reading over the plan at hand, surfaced with the basis it rests on, and NOT a test read off the routing value: handoff_to_span sends a region's OUTPUT across the span wall, while the stop a resolver defines is wanted while that region's own moves are still running — so a crossing region whose resolver is an assigned protocol or the user at execution stays reachable, and a structural test would certify that routable ground as unroutable. The marking is taken at the surface, never a field of TerminationGround and never an argument of derived_termination_grounds. It is this reading's FINAL disclosure and not its first notice — the same reading was available when the slot was filled and its draft ground carried it there, on a surface the user could open, which is what this phase cannot offer since it surfaces and dispatches in one turn; relay only — it does NOT mutate Λ)
Phase 3 surface checkpoint briefs (extension) → TextPresent+Proceed (surface each compiled CheckpointBrief in the convergence trace; follows degradation recording, so a brief demoted to advisory is surfaced with that demotion visible; relay only — it does NOT mutate Λ)
Phase 3 handoff (dispatch) → delegate (hand the ConductedMethod plan to the substrate; the substrate executes — execution is out of scope; this dispatch is the plan's own handoff witness)
Λ (track) → Internal state update (the framing shifts are what LEAVES this protocol: they reach the handoff through Λ.trace_contract, which AssembleTraceContract populates and the dispatched ConductedMethod carries; per-axis bookkeeping stays in session. The work prospect itself does NOT ride in ConductedMethod — that type carries topology, assignments, checkpoints, the substrate handoff, the trace contract and work_pointer, and no WP or MethodBrief field — so where the context supplied a navigation block, work_pointer is what reaches the work, and where it supplied none, nothing carries it. No separate durable entry is written here — the one durable record in play is the parked record that pointer names, and re-authoring its contents into a second entry is what CarryPointer already refuses)
Seam transition to declared next protocol (extension) → TextPresent+Proceed (fires at deactivation/handoff: a user-declared chain naming the next protocol, or a composition edge this SKILL.md declares, settles the next move; proceed directly to it, citing that settling source; every Constitution gate inside this protocol and inside the next protocol fires unchanged. A routing=handoff_to_span region names no next protocol: its seam declares an externalization obligation the executing substrate discharges by writing the output to a substrate-owned record, and the future span receives a navigation block over that record in the fixed shape `Declared continuation and span seam` declares)
-- Substrate realization: at the Phase 3 seam, read the session's actually-loaded inventory — its agents, skills, MCP servers, and the tools/system-prompt each exposes — and propose realizable substrates from that live inventory rather than a fixed list; the inventory is the authority. Topology→substrate feasibility is a non-epistemic substrate handoff: the protocol surfaces feasibility, the substrate enforces realizability. A region whose routing is handoff_to_span or an emergent value declaring crosses_span requires a durable record surface its output can be externalized to across the span wall, proposed as the bridge substrate at this seam. Surface feasibility per resolved topology value as a delegated handoff annotation (extension: surface only); when the read inventory cannot realize the resolved topology — including no realizable durable record surface for a handoff_to_span region — record a substrate_infeasible degradation (track: the Λ.degradations mutation). The (constitution)/(extension)/(track) markers above remain the authoritative axis.
── MODE STATE ──
Λ = { phase: Phase, work_prospect: Option(WP), move_set: Option(MS), topology: Option(CT), topology_draft: Option(CT_draft), constituted_axes: Set(axis × MoveRegion), checkpoints: CheckpointSet, substrate_handoff: Option(SH), residuals: Set(ResidualAxis), degradations: Set(Degradation), move_assignment: Map(Move → ⟨order_position, region⟩), work_pointer: Option(N), trace_contract: Option(TraceContract), active: Bool, cause_tag: String }
-- residuals, the Phase-2 independence degradations, move_assignment and checkpoints are
-- PRODUCTS OF ONE TOPOLOGY MATERIALIZATION PASS, never cross-pass accumulators. constituted_axes is edited at
-- single (axis, region) granularity by Select/Compose/Reorient, and wholesale by
-- CarryConstituted when a re-cut replaces the region names its pairs are keyed on.
-- topology_draft is TOTAL over the current cut's slots — every axis·region carries one, which is what
-- topology_drafted_whole and the Sufficient-always-executable property both rest on. What is restricted is
-- not its domain but which entries are LIVE: ReDraft re-fills only the unconstituted ones and leaves a
-- constituted slot's entry untouched at the pre-gate value the draft had put there. That entry is NOT the
-- user's choice — the choice lives in Λ.topology under Λ.constituted_axes — so a reader that consults the
-- draft at a constituted slot reads a stale value, and no reader does: FinalizeTopology and
-- unconstituted_residuals both test constituted_axes first, DraftSurface and a re-opened AxisGate both read
-- such a slot from Λ.topology, and `Convergence evidence` forbids counting dispositions off
-- the draft beside them rather than off the rows the trace has shown. That holds only while the pair stays
-- constituted, which is why CT_draft's currency clause puts the fill on whatever un-constitutes the slot.
-- It carries no authority — FinalizeTopology reads it after constituted_axes and before default(a).
-- trace_contract stays None until Phase 3 assembles it.
-- work_pointer is bound alongside work_prospect at Phase 0 (see WP-BINDING), checked there by ground_pointer, and carried unchanged; its contents are never bound to any field here.
-- substrate_handoff is written ONCE, by Phase 3 AnnotateHandoff; it stays None on any path that
-- deactivates before Phase 3.
Phase ∈ {0, 1, 2, 3}
── COMPOSITION ──
*: product — (D₁ × D₂) → (R₁ × R₂). Dimension resolution emergent via session context.
```
## Mode Activation
`/conduct` is directly invocable. AI-guided activation requires at least two cognitive moves and a genuine fork in their order, independence, reconciliation, termination, or routing; scale and budget alone do not warrant conduction. Method-level planning questions and dependency-bearing staged work are typical triggers. Conduct the method before beginning its object-level moves, while retaining loaded safety boundaries, capability restrictions, and explicit user instructions.
When `/ground` self-grounding returns a Split partition reading, read `references/decompose-recovery.md` before conducting the fan; its frozen `MoveSet` and empty-cell behavior are branch-normative. A Trim reading remains a single `/induce` move and relays there.
## Protocol
### User-facing realization
Present the Method Brief and warrant before its Constitution gate. Set the brief's span from this invocation through the next planned `/compact` or `/clear`; an execution stop instruction bounds the current run without shortening that designed horizon. Present the identified move set as structured candidates for confirmation; prior-session recall indices may seed those candidates but never settle the judgment.
Render the whole current topology before its gate. Show the proposed region cut with the non-uniformity that grounds it and an affordance to replace it. For every axis·region, show the active value, its basis, every named alternative, an emergent-value affordance, the composition affordance on reconciliation, and the differential for the alternative that most changes the downstream plan. Mark user-constituted values as theirs. Present unconstituted values as draft candidates, then ask which slots are wrong; silence carries `Stop`.
Lay the surface and any opened gates most-constrained-first. A cut revision settles alone because it replaces the edge-local region keys; carry prior user values onto overlapping replacement regions as cited draft values. Read `references/round-composition.md` before composing when terminology or wording must remain stable, material belongs to another round or trace, or phase order determines its placement.
At the handoff seam, scan the actually loaded substrate inventory and surface per-region realizability before dispatch. Record infeasibility instead of silently binding an unrealizable substrate. Cross-span routing declares only the durable-record externalization obligation; author-side portability auditing and far-side compile-back remain outside this protocol.
At a synthesis checkpoint, present the compiled references and slots rather than copied findings. A substrate infeasibility affecting the in-session checkpoint makes its brief advisory; a downstream-only infeasibility demotes routing or externalization while leaving the checkpoint binding.
## Rules
- **Conduction warrant**: Require a genuinely underdetermined, non-trivial conduct over at least two moves. Relay single-move and self-evident methods; conduct-plan moves are object-level, so Hyphegesis never conducts itself.
- **Recognition over Recall**: Present genuinely viable options with differential futures and yield at every Constitution interaction. Collapse shared-trajectory candidates before presentation, while preserving the mandatory `Sc` and `DraftGate` yields through which the user constitutes the move set and whole topology.
- **Round composition**: Use everyday language, place each judgment beside its evidence and next-move implication, and keep analytical context before the gate. Read `references/round-composition.md` when terminology or wording must persist, content belongs to another round or trace, or phase order governs placement.
- **Convergence evidence**: Before dispatch, demonstrate the final move assignment, each axis·region's constituted/drafted/fallback disposition, substrate annotations, compiled checkpoints, and trace contract. Derive any tally from the rows actually shown; `order` has one `{whole}` row while the other axes are edge-local.
- **Trace contract**: Surface the final pass's residual dispositions, current degradations, coverage caps, and carried termination grounds as one cross-cutting overlay, never as a sixth gated axis. Mark `resolution_required` as unroutable only from the final plan's resolver-reachability evidence; cross-span output routing alone does not make its in-region resolver unreachable.
- **Decompose recovery**: Read `references/decompose-recovery.md` before the `/ground` Split → cell-assignment checkpoint → per-cell `/induce` instance. The split remains object-level and owns no orchestration.
- **Declared continuation and span seam**: Relay directly to a next protocol named by the user or a declared composition edge, citing that source; all internal Constitution gates still fire. Cross-span output travels as a navigation block over the substrate-owned canonical record, including dereference and grounding instructions, never as copied contents.
- **`/apportion` seam**: Treat an incoming plan as a checked navigation pointer, not an import: dereference it, run `/inquire` or equivalent grounding, and carry the block unchanged. A fixed-topology autonomous region handed outward is not re-conducted.
- **Form feedback**: Derive each round's density from the current request and carry an explicit form instruction until countermanded. Change the form directly; preserve content, wording, order, cadence, and turn boundaries fixed elsewhere, stating what changed and any overlapping constraint that remains.
- **Whole-draft safeguard**: Never show a drafted value alone. Pair it with the ground that selected it, every named alternative, affordances for open values, and the most plan-changing differential; pair the proposed cut with its cited ground and replacement affordance.
## Adversarial Guards
- **object-control-conflation**: Decompose transforms abstractions; the conduct topology owns its ordering, focus, span, state, and recursion.
- **cross-span-absorption**: `handoff_to_span` declares routing and externalization only; portability auditing and future-span cognition stay with the receiving span.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!