Scripting

Scripts and installations

Create mutable scripts, publish versions, and install exact releases safely.

Published by solever7 solever7
scripts installations ask dependencies

Macchi uses different words for different lifecycles. Add creates a mutable script
owned by a user, server, or channel. Publish freezes one positive version.
Install binds that exact immutable publication to a context without copying its
source. Delete removes a mutable script; Uninstall removes an installation.
Required dependencies block destructive changes instead of being silently removed.

References And Versions

u123/welcome@0 is the current mutable draft. u123/welcome@2 is immutable version 2.
Server and channel owners use g and c. Installation always requires a positive exact
version; an unversioned or @0 reference is rejected. The separate public code used by
library discovery is not the canonical reference.

The Execution Snapshot

ctx.scripts is loaded once and stays stable for one execution. It contains at most 32
deterministically ordered items. all(), user(), server(), channel(), and
installations() return bounded lists. find(name) and findRef(reference) search
that snapshot.

Each item says whether it is executable, manageable, and source-readable. Those flags
are independent. A runnable public installation does not expose its source through the
private snapshot. A target also carries an opaque handle; Macchi rejects fabricated
handles and handles copied from another execution.

Ask Proposals

Ask calls accept one strict table and reject unknown fields. A call only creates a
transport-neutral, three-minute proposal:

macchi.ask:forAdd({
  name = "welcome",
  scope = "channel",
  description = "Welcomes people",
  capabilities = {},
  enable = true
})
macchi.ask:forInstall({
  script = "u123/welcome@2",
  scope = "server",
  enable = true
})

Existing mutable targets come from ctx.scripts:

local target = ctx.scripts:find("welcome")
macchi.ask:forUpdate({ script = target, description = "New description" })
macchi.ask:forCapabilities({ script = target })
macchi.ask:forEnable({ script = target })
macchi.ask:forDisable({ script = target })
macchi.ask:forPublish({ script = target })
macchi.ask:forDelete({ script = target })

Installations use forUninstall. Macchi owns Accept and Cancel; no Lua handler runs
after the prompt. On Accept, Macchi re-resolves current state, refreshes Discord
permission, recomputes dependencies, then calls the canonical mutation. If the host
restarts, the actor/context changes, or the plan changes, the proposal expires safely.
Ask never reserves permission.

Dependencies And Capabilities

Published manifests use exact immutable references. The plan distinguishes already
installed, new, and conflicting versions and is recomputed after Accept. Dependencies
receive separate installation rows and inherit neither authority, activation, nor
grants.

Capabilities remain requested, granted, and effective. Installation does not
bypass current Discord permissions, hierarchy, quotas, or authority. interactive
controls use the normal output policy and need no separate grant; Broad moderation and
storage groups still need an explicit grant. A grant never replaces current Discord
permissions, hierarchy, scope, quotas, or trusted target validation. Persistent storage
is shared by user, server, or channel scope, so storage.write may replace values used
by other scripts in that scope.

Current Limits

Ask proposals and checked-source controls remain process-local and host-bound. Durable
Lua component/modal routes can be claimed by a current capable host, but Ask is not
forwarded across hosts. Upgrade review is not public yet: the current exact-version
model detects conflicts, but does not replace an existing installation silently.