Host-facing facade for governed, declarative Agent evolution.
Morph translates a small reply-only API into the existing immutable ChangeSet, review, approval, and activation pipeline. It does not create a second governance engine and cannot widen the canonical Surface declared by the Agent.
{:ok, activation} =
instance
|> Spectre.Morph.change(by: "actor:admin", reason: "Serve refunds")
|> Spectre.Morph.mount_skill("refunds",
match: {:exact, "refund"},
reply: "Refund policy applies to: {{input.text}}",
scopes: [:support]
)
|> Spectre.Morph.evaluate(cases: protected_cases)
|> Spectre.Morph.approve(by: "actor:reviewer")
|> Spectre.Morph.activate()Every stage returns an inspectable Spectre.Morph.Change. Approval remains
an explicit host commit, activation remains generation-CAS fenced, and each
runtime Skill is reloaded from the exact Definition pinned to its Run.
Summary
Functions
Activates an approved Candidate through the Instance generation CAS.
Records the separate host approval commit.
Opens a draft against the Instance's exact active Definition.
Proposes disabling a runtime-origin Skill.
Composes and deterministically evaluates a draft Candidate.
Returns the deterministic human report produced by evaluation.
Adds one reply-only runtime Skill proposal to a draft.
Rebases a draft's typed operations onto the current active Definition.
Records an explicit host rejection of an evaluated Candidate.
Replaces one runtime-origin Skill while preserving anti-hijack obligations.
Restores a durable governed Candidate view by Ref.
Returns a compact, data-only status projection suitable for UI or logs.
Functions
@spec activate( Spectre.Morph.Change.t(), keyword() ) :: {:ok, Spectre.Instance.Activation.t()} | {:error, term()}
Activates an approved Candidate through the Instance generation CAS.
:now and :checker_versions may be supplied. Activation re-reads all
durable artifacts and re-applies constitutional verification at commit.
@spec approve( Spectre.Morph.Change.t(), keyword() ) :: Spectre.Morph.Change.t()
Records the separate host approval commit.
Options are :by, :mode, :policy, :expires_at, and :now. A Surface
requiring human approval defaults the mode to :human and requires an
actor; host policy remains subordinate to the independent risk policy.
@spec change( GenServer.server(), keyword() ) :: Spectre.Morph.Change.t()
Opens a draft against the Instance's exact active Definition.
Required options are :by and :reason; :evidence accepts a plain map
that is digest-bound to the ChangeSet. The canonical Surface is always read
from the Definition Store, never from transient caller data.
@spec disable_skill(Spectre.Morph.Change.t(), String.t()) :: Spectre.Morph.Change.t()
Proposes disabling a runtime-origin Skill.
Morph derives negative replay cases for every scope allowed by the canonical Surface. Disabling one Skill therefore cannot silently introduce routing for the removed inputs in a sibling scope.
@spec evaluate( Spectre.Morph.Change.t(), keyword() ) :: Spectre.Morph.Change.t()
Composes and deterministically evaluates a draft Candidate.
:cases supplies the protected corpus. Tests may supply an inseparable
:receipts plus :delta pair for exact external replay. Optional controls
are :now, :checker_versions, and a narrowing :prompt_token_ceiling.
This stage never approves or activates the Candidate.
@spec explain(Spectre.Morph.Change.t()) :: {:ok, map()} | {:error, term()}
Returns the deterministic human report produced by evaluation.
@spec mount_skill(Spectre.Morph.Change.t(), String.t(), keyword()) :: Spectre.Morph.Change.t()
Adds one reply-only runtime Skill proposal to a draft.
:match must be an exact non-empty string (or {:exact, string}), and
:reply may contain only the {{input.text}} placeholder. Optional keys are
:never, :version, :token_cap, and :scopes. With a multi-scope Surface,
:scopes is required and must be a non-empty subset of the ceiling.
@spec rebase( Spectre.Morph.Change.t(), keyword() ) :: Spectre.Morph.Change.t()
Rebases a draft's typed operations onto the current active Definition.
Optional :by, :reason, and :evidence replace the original values.
Every operation is revalidated against the new canonical Surface before any
operation is copied into the rebased draft.
@spec reject( Spectre.Morph.Change.t(), keyword() ) :: Spectre.Morph.Change.t()
Records an explicit host rejection of an evaluated Candidate.
Both :by and :reason are required; :now controls the deterministic
commit timestamp in tests or host-managed clocks.
@spec replace_skill(Spectre.Morph.Change.t(), String.t(), keyword()) :: Spectre.Morph.Change.t()
Replaces one runtime-origin Skill while preserving anti-hijack obligations.
The options have the same form as mount_skill/3. Compiled Skills are
immutable through this API and are rejected again from the durable
parent-to-candidate diff at governance commit time.
@spec resume( GenServer.server(), Spectre.Definition.Candidate.Ref.t() | String.t(), keyword() ) :: Spectre.Morph.Change.t()
Restores a durable governed Candidate view by Ref.
The Ref may be a CandidateRef or its canonical string form. Optional
:by, :reason, and :evidence establish the host context used by a later
approval or activation; no transient proposal data is trusted.
@spec status(Spectre.Morph.Change.t()) :: map()
Returns a compact, data-only status projection suitable for UI or logs.