Hypotyposis Protocol

SkillDev tools

Recognize and revise concrete sketches to discover a form when descriptions cannot settle intent. Type: (FitUnrecognized, Hybrid, SKETCH-RECOGNIZE-CYCLE, FormIntentSeed) → RecognizedForm

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Hypotyposis Protocol skill

What this skill tells your AI

The instructions your AI receives, as published by jongwony/epistemic-protocols in hypotyposis/skills/sketch/SKILL.md and read by ahel’s review.

Discover what a form should be by encountering concrete sketches and marking what does not fit, until the user recognizes a specific version as the form for a stated purpose. Type: (FitUnrecognized, Hybrid, SKETCH-RECOGNIZE-CYCLE, FormIntentSeed) → RecognizedForm.

Definition

Hypotyposis (ὑποτύπωσις): an outline or sketch — a first drawing of a position rather than its finished statement. A dialogical act for the moment when a form has to be made and the intent behind it cannot yet be settled from descriptions: the user can say what is wrong with a thing in front of them long before they can say what the thing should be, because good fit has no positive description of its own while each misfit is immediate and can be pointed at (Alexander, 1964). So the protocol runs the other way round from a specification: the AI drafts each round's focus, the perception it needs, and its variants, relays the draft with the basis that chose each, and produces the sketches; the user marks a specific version — what does not fit and what to keep — as first-class utterances, settling or sending back the round's readings in the same answer; the AI revises the retained version under those marks; and the loop ends when the user recognizes one version as the form for a stated purpose and names where it lives.

── FLOW ──
Hypotyposis(I) → detect(I, ctx) →
  [¬fit_unrecognized(I, ctx)] no_activation_relay → exit (NoActivationRelay)
  bind(I) → Λ.history (each prior item as Settled | Candidate, provenance kept) → Λ.round := 1 →
  spec_relay(draft(RoundSpec, provisional(Λ))) → Λ.spec := draft → produce(spec, Λ) → Sk →
  present(Sk) → Qfit(Sk, spec.focus) → Stop → M →
    [M = Marks(ms, acts)]   act(acts) → record(ms) → interpret(ms) → record(Proposed) → Λ.round += 1 → spec_relay
    [M = Fit(w, acts)]      act(acts) → w.context_revision := Λ.context_revision → Λ.fit_witnesses ∪= {w} → Λ.round += 1 → spec_relay   -- one focus adequate; the loop continues
    [free response: spec revision] revise(draft, rev) → spec_relay (scoped to the revision; no new round counted)
    [M = Finish(rec, acts)] act(acts) → rec.context_revision := Λ.context_revision → Λ.recognition := Some(rec) → Qplace → Stop → P → harvest → account →
                        [retention verified] RecognizedForm
                        [retention failed]   declare → Qplace (re-presented with the failure; the same location is admissible)
    [M = Withdraw]    account → EarlyExit
  [either party, at the spec relay or at any gate: recognition needs no further encounter ∨ activation premise collapsed]
    dissolution_relay → account → DissolutionExit
  [either party, at the spec relay or at any gate: a sibling deficit is demonstrated ∨ a realization the round requires is unavailable]
    boundary_relay → account → BoundaryExit

── MORPHISM ──
FormIntentSeed
  → detect          -- deficit predicate over the utterance and accumulated context (silent analysis)
  → bind            -- prior material enters the history as Settled or Candidate, provenance kept
  → relay_round     -- Extension: focus, realization, and targets drafted with the basis that chose each, relayed beside the provisional coordinates; nothing is settled here
  → produce         -- transform: one sketch per brief — a brief naming a parent revises that retained version, a parentless brief generates from the material it names or from prior material — and declares what producing it determined that no coordinate covered
  → present         -- relay: each sketch from its typed concretum, what this round can and cannot expose, and whether an artifact was observed
  → recognize       -- Constitution: marks on a specific version — Marks | Fit | Finish | Withdraw; the same answer promotes, supersedes, or holds the coordinates in view
  → record          -- track: every mark, and every interpretation read from it, enters the append-only history; interpretations stay provisional
  → place           -- Constitution: where the recognized concretum lives beyond the session, and which versions the run passed over are kept as revert points; no default for either
  → harvest         -- active commitments, recognition witness, trace, and residual recorded before release
  → account         -- per-sketch retain-or-release disposition, verified
  → RecognizedForm
requires: form_purpose_in_scope(I)             -- runtime checkpoint (Phase 0): the work is about to make a form
deficit:  FitUnrecognized                       -- activation precondition (Layer 1/2)
preserves: utterance(I)                          -- I.utterance is read-only; the history accumulates beside it
invariant: Concretum Retention                   -- a brief that revises does so on a retained parent; a sketch under judgment is never regenerated from coordinates alone
invariant: Commitment Provenance Preservation    -- a prior constitutive act stays recorded; a later user act may supersede its operative determination; AI inference alone never supersedes a user commitment
invariant: Recognition over Description          -- fit is the user's recognition of a specific version for a stated purpose

── TYPES ──
I  = FormIntentSeed { utterance: String, prior: List(ReferencedMaterial) }
       -- Input type: morphism processes I uniformly; prior is source-neutral — a settled direction, a resolved intent,
       --   a candidate field, an existing artifact, a prior session's record — each named by the user or already in context
ReferencedMaterial = { source: String, content: String }          -- what it is and where it came from; no sibling type is a runtime dependency
Binding = Settled(Coordinate) | Candidate(ReferencedMaterial)      -- how a prior item enters the history at bind: a commitment the user already made, or material to draw on
fit_unrecognized(I, ctx) = a form-making purpose is in scope
                         ∧ decision-relevant intent remains underdetermined
                         ∧ encountering and revising a concrete proposal is what would constitute that intent
                         ∧ the resolution sought is a recognized form with its commitments and residuals
Axis      = String                                                 -- emergent label: "information unit", "reading order", "density", "tone"
Focus     = Axis | Question(String)                                -- what this round filters attention toward; an unexpected misfit on any other axis stays admissible
Value     = String                                                 -- a determination on an axis, in the user's words or read off the sketch
Realization = capability description                               -- what this round's judgment needs in order to be possible: the perception it rests on
       --   (narration, spatial layout, interaction, sound, …) and, where the focus opens an axis carrying a standard
       --   outside both parties' preference, the referent it is checked against. Open, named per round — and a referent
       --   the round requires that this session cannot supply is the boundary arm's condition rather than something to
       --   proceed without
VariantBrief = { parent: Optional(SketchRef), source: Optional(ReferencedMaterial), commits: Map(Axis, Value) }
       -- one sketch to produce. Some(parent): revise that retained version. None: generate from active_coords and
       --   from the material `source` names, or from the bound prior material where it names none — every brief of round 1's
       --   first pass, and a fresh start the user names at Qfit for a later round; a SpecRevision re-entry that keeps a version
       --   names it as parent, so the re-drafted round revises the retained version rather than regenerating it
       -- a round that changes where the material comes from is a parentless brief naming the new source, not a
       --   different kind of round: what the loop does is unchanged, and what moved is only what "generate" draws on
RoundSpec = { focus: Focus, realization: Realization, targets: NonEmptyList(VariantBrief) }
       -- k = |targets| is drafted here; a count the user settled at a recognition gate holds until they revise it
Supersession = { of: Coordinate, by: Optional(Coordinate) }        -- the user's act on a coordinate in view: by = Some(c') replaces it with a determination the user states (c' enters Settled, basis Utterance), by = None retires it with nothing in its place
CoordinateActs = { settlements: Set(Coordinate), supersessions: Set(Supersession) }
       -- the user's acts on the coordinates in view, riding the recognition answer: which provisional coordinates become
       --   Settled and which coordinates — Provisional or Settled — they supersede; either set possibly empty
SpecRevision = a change to this round's focus, realization, or targets, named by the user as a free response at the recognition
       gate; the spec relay re-presents scoped to it and no new round is counted
SketchRef = { id: ℕ, round: ℕ }                                    -- identity of one version; the harvest and every mark point at one of these
Concretum = Text(value) | Artifact(versioned_ref)                  -- Text: narration carried in session text; Artifact: a file under temp isolation, versioned at creation
Sketch = { ref: SketchRef, parents: List(SketchRef), concretum: Concretum, rendered_from: snapshot(active_coords), focus: Focus }
       -- what it was rendered under that no Settled or Provisional coordinate covered — its brief's commits and what producing it determined — reaches the history as Proposed coordinates basis Production(ref),
       --   so a sketch's own determinations are read back by its reference rather than stored a second time
Anchor = Element(locator) | Region(bounds) | Whole | Span(text)    -- where on a sketch a mark points; Whole admits "something is missing here" with nothing to point at
       -- premise: a mark points at a place. A property recurring across the sketch sits at none, and arrives as Whole
       --   with the property itself in the mark's utterance and, where it names one, its axis — carried whole, not classified
Mark = Misfit { sketch: SketchRef, anchor: Anchor, utterance: String, axis: Optional(Axis) }
     | Keep   { sketch: SketchRef, anchor: Anchor, utterance: String }
       -- a user utterance anchored on a version; Keep is the positive half of mixed feedback and is retained, never dropped
Status = Provisional | Settled
Coordinate = { axis: Axis, value: Value, basis: Mark | Binding | Utterance | Production(SketchRef), status: Status, round: ℕ }
       -- interpret() yields Provisional only; Settled requires the user's act at Qfit or a convention already on record
       -- Production(ref): a determination rendered into that sketch that no Settled or Provisional coordinate covered — drafted in its brief or made while producing.
       --   Provisional like any reading, and settled or superseded only by the user's act at the next recognition gate —
       --   production introduces determinations, it never settles them
Event = Bound(Binding) | Marked(Mark) | Proposed(Coordinate) | Promoted(Coordinate) | Superseded(Coordinate, by: Optional(Coordinate)) | Witnessed(FitWitness)
       -- Superseded is appended by supersede at Qfit and nowhere else: the user's act is its only producer, so an AI interpretation the user rejects leaves provisional(Λ) and a determination the user replaces leaves active_coords
       -- Proposed is appended by interpret and by produce: a coordinate the AI puts forward, whichever step reached it.
       --   Its basis says which, and its lifecycle is one — presented at the spec relay and again beside the sketch at Qfit, promoted or superseded there, residual otherwise
active_coords(Λ) = fold(Λ.history)                                  -- the operative determinations now: per axis, the latest Settled coordinate with no Superseded(it, _) after it — Superseded(c, Some(c')) makes c' operative in c's place, Superseded(c, None) retires c with nothing in its place; Provisional ones shown beside
provisional(Λ)   = { c : Proposed(c) ∈ Λ.history ∧ ¬∃ Promoted(c) ∈ Λ.history ∧ ¬∃ Superseded(c, _) ∈ Λ.history }
                                                                    -- what the AI read from a mark or decided while producing, awaiting the user's act at Qfit; derived from the history, never stored apart
FitWitness  = { sketch: SketchRef, context_revision: ℕ, scope: Focus, utterance: String }
       -- adequacy on one focus for one version; bound to the context revision the answer carrying it left, acts included; stale once its sketch is superseded or the context revision moves — shown as stale, never reused silently
Recognition = { target: SketchRef, context_revision: ℕ, purpose_scope: String, residual: Set(Axis) }
       -- target must be a presented, retained version; Finish is recognition of the assembled form, not of one focus
M  = Recognition gate answer ∈ {Marks(Set(Mark), CoordinateActs), Fit(FitWitness, CoordinateActs), Finish(Recognition, CoordinateActs), Withdraw}
       -- the acts ride Marks, Fit, and Finish: the answer that judges the version also settles or sends back the readings shown
       --   beside it, and an answer naming none carries empty sets; a settlement stated in the Finish answer reaches commitments
       --   through the same act, and what is still Provisional after it is declared in the result's provisional set; Withdraw
       --   carries none — nothing it settled would be read
       -- Marks(∅, ∅) is read as Stop, never as Fit; Marks(∅, acts) with acts non-empty moves the coordinates and re-enters the
       --   next round as any Marks does; silence yields the turn again; a response carrying both marks and a finish is parsed
       --   as Marks — recognition names an unmarked version
       -- premise: one answer settles this version. An answer also naming what a later round should take up departs from
       --   that premise rather than breaking it — it is parsed by its constructor, and the rest is recorded as itself
Location = a reference the user judges to outlive the session      -- the capability the placement gate asks the user to bind; the protocol supplies no default
       -- the durability is their judgment, not a checked fact: account verifies that the reference resolves to that
       --   version's concretum AT THE MOMENT IT IS CHECKED, which is the narrower of the two claims
P  = Placement gate answer ∈ {Place(Location, kept: Map(SketchRef, Location))}
       -- where the recognized version lives, and which versions that were not recognized are kept as revert points and
       --   where; kept may be empty. On a re-presentation after RetainFailed, either may be the same or another; a
       --   free-response withdrawal here is EarlyExit with the recognition in the partial trace
Fixture = { ref: Location, target: SketchRef, scope: String, residual: Set(Axis), kept: Map(SketchRef, Location) }
       -- status: recognition witness. It carries no implementation commitment and is not an executable specification
       -- kept: what a later reversal would otherwise have to rebuild. A version the loop passed over is what the
       --   decision could return to, and returning to it costs rebuilding unless it survives as itself
Disposition ∈ {Retained(Location), Released, ReleaseFailed(reason), RetainFailed(reason)}
       -- Retained is written only once verification holds: the reference resolves to the recognized version's exact concretum. RetainFailed sends control back to Qplace; ReleaseFailed is declared with a handoff
TraceEntry = (Mark → Optional(Coordinate) → Optional(SketchRef) → Recognized | Superseded | Residual)
       -- what each mark became: its interpretation, the revision it drove, and how it ended
ExitCause ∈ {NotActivated, Recognized, Withdrawn, BoundaryReached, Dissolved}
RecognizedForm = single record { commitments: Set(Coordinate) (Settled only), witness: Fixture, recognition: Recognition,
                                 trace: List(TraceEntry), residual: Set(Axis ⊎ ReferencedMaterial), provisional: Set(Coordinate) }
       -- assembled after account: the retained concretum is reachable through witness.ref, and what the user named for a
       --   round that never came is declared rather than dropped
NoActivationRelay = the non-activation basis stated: the failed predicate with its evidence; a sibling deficit visible in the same scan is named as a finding and left to the session
EarlyExit = withdrawal at any gate: partial trace over completed rounds + account enforced + residual declared (no RecognizedForm returned; any prior recognition remains in the partial trace)
BoundaryExit = the unresolved obligation named — a sibling deficit demonstrated, or a realization the round requires that this session cannot supply — with account enforced; which protocol takes it is the session's, never this record's
DissolutionExit = the deficit dissolved during a circulation: the sharpened description made the form recognizable without a further encounter, or the activation premise collapsed; declared by either party with its basis, the surviving determinations relayed, account enforced
Phase     ∈ {0, 1, 2, 3, 4, 5, 6}

── A-BINDING ──
bind(I) = explicit_arg ∪ recent_form_intent ∪ surfaced_fit_gap
Priority: explicit_arg > recent_form_intent > surfaced_fit_gap

/sketch "what to make"          → I = FormIntentSeed with utterance; prior = material the utterance names or that is already in context
/sketch (alone)                 → I = the most recent form-making intent in session
"I'd know it when I see it"     → I = the utterance under discussion (AI-detected path: the spec relay cites the evidence of FitUnrecognized as the run's basis; a decline of the run is a withdrawal at the first Qfit)

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
161
Forks
15
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
sketch-jongwony
Source
github.com/jongwony/epistemic-protocols