Proplasma Protocol
SkillDev toolsDivergent-discard instantiation. Fires when direction candidates cannot be recognized from descriptions. Type: (DirectionUnrecognizable, Hybrid, PREVIEW, DirectionProspect) → DirectionalContrast
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Proplasma Protocol skill
What this skill tells your AI
The instructions your AI receives, as published by jongwony/epistemic-protocols in proplasma/skills/preview/SKILL.md and read by ahel’s review.
Expose direction unknowns through divergent-discard instantiation before commitment. Type: (DirectionUnrecognizable, Hybrid, PREVIEW, DirectionProspect) → DirectionalContrast.
Definition
Proplasma (πρόπλασμα): the preliminary clay model a sculptor shapes before committing to marble. A dialogical act for the moment right before a direction commitment when the candidate directions cannot be recognized from their descriptions: the AI derives the axes on which the candidates genuinely diverge, relays the drafted axes, placeholder policy, probe target set, and realization tier with the basis that chose each, instantiates two to four cheap placeholder probes that commit different values on those axes, presents them probe-first with a per-axis contrast, and the user constitutes the direction decision on recognized futures — or sends the draft back, the first send-back costing no re-fan budget. Probes are discard-committed instruments — never evidence, never promoted.
── FLOW ──
Proplasma(X) → detect(X, route) →
[¬pre_commit(X) ∨ |direction_candidates(X)| < 2] requires_fail_relay → exit (not activated)
[futures recognizable from text] no_deficit_relay → exit (not activated)
[route ∈ {①, ②, ③}] route_away_relay(matched row) → exit (not activated)
[a type guard fails (¬fake_data_sufficient ∨ ¬placeholder_fidelity) ∧ no routing row matches] unfit_relay → exit (not activated)
derive_axes(X) → Axs → draft_policy → spec_relay(Axs, policy, Tgt, tier, each with its basis) → draft_spec →
[either party, at the spec relay or at any gate: sharpened description makes the futures recognizable ∨ activation premise collapses]
dissolution: [Λ.probes ≠ ∅ (refan re-entry) → cleanup_verify first] → dissolution_relay → exit (DissolutionExit)
instantiate(∥ probes over Tgt, temp-isolated, artifact_ref registered) →
contrast(P, Axs) → (CM, EU, CC) → present(probe-first: probes → contrast map → unknowns) →
Qdir → D →
[D = Select(direction)] harvest → cleanup_verify → assemble → DirectionalContrast
[D = Synthesize(composition)] Qmicro → Gs →
[Gs = Confirm] harvest(synthesized direction) → cleanup_verify → assemble → DirectionalContrast
[Gs = Materialize] spec_relay_if_spec_revision → refan(composition) → contrast → present → Qdir
[draft sent back at Qdir ∧ ¬spec_settled] spec_relay_if_spec_revision → refan(gap; budget untouched) → contrast → present → Qdir
[contrast_insufficient ∧ refan_budget > 0] spec_relay_if_spec_revision → refan(gap) → contrast → present → Qdir
[contrast_insufficient ∧ refan_budget = 0 ∧ refan_kind = Materialization ∧ ¬insufficiency_relayed] insufficiency_after_materialization_relay → Qdir (re-present over the accumulated probes)
[contrast_insufficient ∧ refan_budget = 0 ∧ refan_kind = Materialization ∧ insufficiency_relayed] insufficiency_standdown_relay → cleanup_verify → exit (EarlyExit via insufficiency_standdown)
[contrast_insufficient ∧ refan_budget = 0 ∧ refan_kind = Gap ∧ ¬spec_settled ∧ ¬insufficiency_relayed] insufficiency_before_settlement_relay → Qdir (re-present over the accumulated probes; the draft has not reached the user yet)
[contrast_insufficient ∧ refan_budget = 0 ∧ refan_kind = Gap ∧ (spec_settled ∨ insufficiency_relayed)] misdiagnosis_exit → cleanup_verify → route_away(MisdiagnosisRoute)
-- spec_relay_if_spec_revision: a refan whose implication carries a SpecRevision — a change to any drafted element of the spec —
-- re-enters the spec relay scoped to the revision BEFORE generation
-- spec_settled: False after the relayed draft; True at the first D answer or at the first send-back of the draft — a send-back
-- while ¬spec_settled is the draft's own correction and re-fans without spending the shared budget; an insufficiency the AI
-- detects at contrast is not that correction and rides the budget as any gap refan
── MORPHISM ──
DirectionProspect
→ detect -- deficit predicate + 4-step routing (type guards: fake_data_sufficient, placeholder_fidelity)
→ derive_axes -- divergence axis candidates (where the candidate directions must commit different values)
→ set_placeholder_policy -- visible synthesis + non-evidence stamp + skeleton-faithful/data-fake split (draft)
→ relay_spec -- Extension spec relay: axes + policy + probe target set + realization tier drafted with the basis for each, relayed BEFORE any generation, and open to send-back at the direction gate
→ instantiate_probes -- transform (∥ over the drafted target set, temp-isolated, artifact_ref registered)
→ contrast -- per-axis juxtaposition → ContrastMap + ExposedUnknowns + CommonCommitments
→ present -- probe-first relay (probes one by one → contrast map → new unknowns)
→ constitute -- direction gate: options point at probe-exposed futures (Select | Synthesize)
→ harvest -- direction + deciding contrast rows + routed unknowns recorded BEFORE discard (Λ.harvest)
→ cleanup_verify -- per-probe discard verification → discard_trace
→ assemble -- terminal record built from the harvest + the completed discard trace
→ DirectionalContrast
-- primary-path codomain: the advertised result type is the primary path's. DissolutionExit — the convergent
-- stand-down — emits the enriched axes with its cited basis INSTEAD of this record: the deficit dissolved,
-- so no resolution object is owed (see CONVERGENCE)
requires: pre_commit(direction) ∧ |direction_candidates(X)| ≥ 2 -- runtime checkpoint (Phase 0)
deficit: DirectionUnrecognizable -- activation precondition (Layer 1/2)
preserves: commit_target_identity(X) -- the pending commitment itself is unchanged; probes never mutate it
invariant: Contrast over Simulation -- direction judgment rests on recognized materialized futures, not mental simulation
── TYPES ──
X = DirectionProspect: a direction decision immediately before commitment (input; carries direction_candidates, |candidates| ≥ 2;
source-agnostic: design direction, architecture fork, UX shape, plan branch — any pre-commit direction choice)
-- Input type: morphism processes X uniformly; enumeration scopes the definition, not behavioral dispatch
DirectionAxis = a declared divergence axis — a direction unknown on which the probes must commit different values
Axs = Set(DirectionAxis) drafted at the spec relay (AI derives each and relays it with the basis that chose it; the user sends any back at the direction gate — no axis commits a probe value before it was relayed with its basis)
Tgt = List(direction) — the probe target set drafted at the spec relay: which directions get probes on this fan
-- contrast fan (initial, or gap refan): Tgt ⊆ X.direction_candidates with |Tgt| ∈ 2..4. When |candidates| > 4,
-- the draft names WHICH candidates are probed and why, and an unprobed candidate stays reachable at the direction
-- gate (the cap is a presentation bound, not a silent truncation)
-- materialization refan: Tgt = [composition] — the user's own synthesis, materialized so they can see it;
-- |Tgt| ≥ 1 here: the composition is contrasted against the ACCUMULATED probes, which already carry the
-- differentiated axis values
DetectGuards (type guards, both required for activation):
fake_data_sufficient : the direction contrast holds with placeholder concreta alone — no real evidence required
placeholder_fidelity : placeholder concretization carries the differential futures on the divergence axes without distortion
PlaceholderPolicy = { visible_synthesis: artifacts are overtly placeholder (never mistakable for real data),
non_evidence_stamp: probes are evidence for no claim (pierces harvest and session remnants),
skeleton_data_split: structure/skeleton is faithful to each direction; data values are fake
-- operating rule for placeholder_fidelity: divergence must live in the skeleton, fake data must not blur it }
RealizationTier ∈ {Vignette, Mockup}
-- Vignette: text-vignette probes — concrete placeholder-filled scenario narration in session text; no file artifacts
-- Mockup: real artifacts (files) in temp isolation, optionally instantiated by parallel agents
Probe = cleanup-bound instrument { direction: String, axes_realized: Map(DirectionAxis, Value),
concretum: Concretum, artifact_ref: ArtifactRef }
Concretum = Narration(text) -- Vignette tier: the instantiated narration itself, typed ON the probe — present
-- re-presents this carrier (instantiate→present identity), never regenerates it at presentation
| AtArtifact -- Mockup tier: the concretum lives at artifact_ref; present walks the artifact through
ArtifactRef = None -- Vignette tier: session-text only, no file to destroy
| Path(temp-isolated path) -- Mockup tier: locatable file/dir under temp isolation; registered at creation
cleanup(p) = the destruction step read off p.artifact_ref (no-op for None; file/dir removal for Path)
ContrastMap = per-axis juxtaposition: for each axis ∈ Axs, the futures each probe exposes on that axis
ExposedUnknown = a direction unknown newly exposed by the contrast (or recorded at an interrogation), tagged with its
DownstreamRoute at recording — the harvest inherits the tag, it does not attach it
DownstreamRoute = PreCommit -- a pre-commit check the USER carries once the settled direction MATERIALIZES INTO A
-- COMMITTED ACTION — not at the direction decision. /inquire at that moment surfaces only what
-- the action rests on (unstated assumptions, missing facts); an unconsidered trade-off,
-- alternative, or step is the user's to raise, and this tag is what reminds them the check is theirs
| Inquire -- a factual unknown needing real evidence now (placeholders can never ground it)
GroundTag = optional annotation ON THE CONSTITUTED DIRECTION (not an ExposedUnknown route): when the surviving
-- direction maps onto a familiar domain, it is tagged at harvest for /ground
-- structural-mapping validation; the tag rides Harvest.direction into
-- DirectionalContrast.direction
CommonCommitment = a design decision forced uniformly across ALL probes during instantiation (not on a divergence axis);
must be reported at present so the user does not mistake a shared premise for a divergence axis
SpecRevision = a change to any element of the drafted spec — its divergence axes, placeholder policy, probe target set, or
realization tier, in whichever direction the correction runs — carried by a refan, whether the user sent the draft back at the
direction gate or contrast insufficiency exposed it; the spec relay re-presents scoped to it before that refan generates
anything. Which element moves and what it becomes are read from the send-back or the insufficiency, never enumerated here
-- on a MATERIALIZATION re-entry a revision reaches the axes, policy, or tier only: Tgt = [composition] is fixed
-- by the refan kind
directions(P) = {p.direction : p ∈ P} -- the directions a probe set has materialized
D = Direction gate answer ∈ {Select(direction), Synthesize(composition)}
-- Select: settle one probe-exposed direction — CONSTRAINED constructor: direction ∈ directions(Λ.probes);
-- a response naming an UNPROBED candidate is never parsed as Select — it enters the unprobed-candidate
-- free-response pathway (probed first within budget, or stand-down)
-- Synthesize: user composes/recombines the presented probes → opens micro-gate Gs
-- interrogation is NOT a D constructor: it settles no direction, and surfaces as a free-response pathway (`Direction-gate response discipline`)
Gs = Synthesis micro-gate answer ∈ {Confirm} ∪ {Materialize | refan_budget > 0}
-- Confirm: settle the synthesized direction as-is, now
-- Materialize: re-fan the synthesis into new probes (consumes the shared re-fan budget)
UserDecision = the constituted direction: Select's direction, or the synthesis settled via Confirm (either way user-constituted)
Disposition ∈ {FileDestroyed, NoFileArtifact, DiscardFailed(reason)}
-- FileDestroyed: Path artifact removed and verified absent (satisfying condition for Mockup tier)
-- NoFileArtifact: Vignette tier — nothing to destroy; discard = non-promotion, remnant text stays under the non-evidence stamp
-- DiscardFailed: destruction attempted (with one retry) and still present; declared, never silent
ProbeRef = minimal identity carrier { index: ℕ (ordinal in Λ.probes — uniqueness key), direction: String, artifact_ref: ArtifactRef }
-- what was destroyed and where it lived; axis values and probe content stay
-- session-local (`Harvest before discard`)
DiscardTrace = List<(ProbeRef, Disposition)> -- one entry per instantiated probe (re-fanned probes included)
RefanKind ∈ {Gap, Materialization} -- what the single shared budget was spent on; decides the still-insufficient branch
Harvest = { direction: UserDecision (⊕ optional GroundTag), deciding_rows: ContrastMap, unknowns: Set(ExposedUnknown) }
-- recorded BEFORE discard; carries no discard_trace — cleanup produces it
DirectionalContrast = single record { -- terminal; single-record codomain (no bare plural)
contrast_map: ContrastMap, -- restricted to the DECIDING rows at harvest (`Harvest before discard`)
exposed_unknowns: Set(ExposedUnknown), -- each tagged with its DownstreamRoute
direction: UserDecision (⊕ optional GroundTag),
discard_trace: DiscardTrace }
-- ASSEMBLED after cleanup_verify: assemble(Harvest, DiscardTrace) → DirectionalContrast
EarlyExit = user WITHDRAWAL at any gate — an explicit exit declared as a free response, a typed withdrawal the protocol
acts on (side effects require explicit answer types) — or a withdrawal by consequence (unprobed_standdown /
insufficiency_standdown, per the result equation): partial transformation trace
over completed steps + cleanup_verify enforced + residual declared (direction NOT constituted)
DissolutionExit = deficit dissolved at the spec relay or at a gate: deriving the axes, or seeing them relayed with their
basis, sharpened the description until the candidate futures became recognizable without probes, or the
activation premise itself collapsed (the fork proves false). Declared by either party. Payload: the sharpened axes as the cited
basis, any recorded unknowns with their DownstreamRoutes, and — on a refan re-entry — the per-probe
dispositions plus the pending re-fan target set (the user-authored composition on a materialization
re-entry, the revised candidate set on a gap re-fan) relayed as live candidates for the regular gate.
A success stand-down: no unresolved residual remains
RoutingRow = ① a structural mapping onto a familiar domain would carry the futures → MappingUncertain (hint: /ground)
| ② real evidence is required before the directions can be judged → ContextInsufficient (hint: /inquire)
| ③ the candidate field is thin — one or none — → CandidateFieldUnderexpanded (hint: /ideate); the frame itself is
absent → FrameworkAbsent (hint: /frame); the coordinates live implicit in externalized substrate → AbstractAporia
(hint: /elicit)
-- the rows Phase 0 and MisdiagnosisRoute dispatch on, first match wins: read after the requires checkpoint and before the type
-- guards, and what no row takes — candidates ≥ 2, evidence-free, placeholder-carriable — is this protocol's own case. Each row
-- names the sibling deficit as the binding and its command as the hint
MisdiagnosisRoute = Row(① | ② | ③) -- a sibling deficit matches (RoutingRow): hand off to the cited protocol
| NoRow -- NO row matches (the candidates may simply not genuinely diverge): declare the
-- misdiagnosis with no downstream protocol and return the decision to a regular
-- gate, residual declared. The exit is defined even when nothing downstream fits
MisdiagnosisExit = refan_budget = 0 ∧ refan_kind = Gap ∧ contrast still insufficient AT CONTRAST (Phase 3), the draft having been settled
or the direction gate already re-presented once over it — a withdrawal at that re-presented gate is EarlyExit, never this:
deficit misdiagnosis report
+ cleanup_verify enforced + route_away(MisdiagnosisRoute); no DirectionalContrast is emitted
contrast_insufficient = the presented contrast does not make the candidate futures recognizable on the axes in force
-- declared by the user (free response at the direction gate — not a D constructor; any drafted element sent back —
-- an axis, the policy, the tier, the target set — is this declaration carrying its SpecRevision) or detected at contrast (an axis with no
-- differentiated values across probes); either way surfaced, never silently self-repaired
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 161
- Forks
- 15
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
preview-jongwony- Source
- github.com/jongwony/epistemic-protocols