Skill Lab
Build and improve Runx skills through one authoring surface. Keep judgment in
bounded agent acts and mechanics in native tools:
inspect target files, catalog ownership, and native/shared tools
→ decide ownership, execution lanes, effects, budgets, and proof
→ bind that architecture to the inspected package digest in native code
→ compose existing capabilities before authoring code
→ author only bounded writes, explicit deletions, and output intent
→ bind those bytes to the admitted architecture in native code
→ validate paths, secret posture, and the complete candidate
→ inspect and safely replay the exact staged package
→ commit that validated bundle through one native transaction
Use the generic host skill-creator for platform-wide authoring guidance when
it is available. Do not reproduce Runx package operations from that guidance;
invoke the appropriate skill-lab runner so the work is bounded and receipted.
Runners
design: read-only catalog-fit and architecture planning. It returns a
native digest-bound plan and never authors package bytes. A later build
re-inspects and replans against its exact target before any write.
build (default): create or update a package after its exact staged bundle
passes native parsing, inspection, and safe harness replay.
improve: turn one receipt or harness failure into a bounded package update,
then validate and commit the exact staged bytes.
harness: add fixture files to an existing package and replay the safe native
harness against the exact candidate before committing it.
build, improve, and harness write local workspace files. They never
publish, install, push, or mutate an external provider. Native harness replay
runs with isolated Runx home, receipts, and no operator credentials. Invalid
staged packages stop before the target package is touched. Design, inspection,
validation, and the bounded transactional workspace write do not add a human
approval gate; the operator authorizes those reversible local writes by
invoking a runner whose native filesystem steps request
fs.write/fs.delete. Publication, installation, provider effects, and other
consequential boundaries remain outside this skill and keep their own approval
rules.
A validated local write is not a published skill. For a shared or public
package, the validated X.yaml identity and the exact target_dir and
package_digest in apply_result form the publication candidate. When the
operator's objective includes shipping or registry availability, continue that
exact candidate through the repository's canonical registry operator: publish
under the intended existing owner/name, then independently read back the same
version and digest. Do not call the work shipped while that sync is pending or
unverified. Publication remains a separate authenticated act so Skill Lab
never receives registry credentials or hides a remote mutation inside local
authoring.
Authoring rules
- Start from the operator's recurring job, not the requested package name,
bounty wording, provider, or implementation sketch. Establish what becomes
materially easier or newly possible for the operator, what judgment the
skill contributes, and what durable result it returns. A package that merely
restates ordinary agent behavior, renames one native call, or produces a
document with no usable next step is not a valuable skill even when every
contract and harness passes.
- Treat prior implementations, accepted bounty text, issue suggestions, and
named integrations as evidence about the intended capability, not binding
architecture. Preserve the real user outcome and compatibility obligations;
replace stale ownership, unnecessary providers, and accidental workflow
shapes when the current catalog has a cleaner canonical route.
- Treat
SKILL.md as the product manual for both the human operator and the
operating agent. A person opening it cold must understand what the capability
does, why and when to use it, what happens end to end, and where it stops.
Do not reduce that manual to terse model directives, field lists, or a task
contract.
- Preserve the useful context in an existing skill: its mental model, procedure,
examples, trade-offs, chain relationships, evidence rules, and recovery
posture. Rewrite statements that no longer match the implementation; never
delete the surrounding explanation merely because the executable profile now
enforces part of it.
- A complete public skill explains, in a structure natural to the capability:
the recurring job and outcome; when and when not to use it; the operating
model and sequence; upstream and downstream skill relationships; meaningful
input and output semantics; authority, approval, evidence, finality, and
recovery; and relevant edge cases and stop conditions. Include a concrete
example when it materially clarifies a non-obvious workflow. Do not force
ceremonial sections onto a simple facade or internal rail.
- Put task-specific agent clauses after the human-readable operating guide.
They sharpen individual agent acts; they do not replace the guide or carry
the product's voice by themselves.
- Explain meaningful upstream and downstream skill relationships naturally in
the operator guide. Do not maintain a second machine-readable dependency
registry in
SKILL.md: native execution-closure inspection owns the exact
edge set and operator preflight surfaces it. Prose explains why the chain
exists; the runtime proves what it actually calls.
- Design capability chains by responsibility, not by whichever integration is
easiest to name:
- The domain skill owns domain evidence, interpretation, policy, and the
truthful domain result.
- A canonical capability or authority skill owns a reusable decision such as
authorizing a send, spending funds, or preparing a release.
- A provider adapter owns the bounded external API effect and independent
readback.
Do not collapse these roles into one package, and do not make a provider
adapter a required part of a provider-neutral capability. Pin an adapter only
when the objective genuinely requires provider-specific behavior; otherwise
return a stable handoff that an operator can route to the selected adapter.
For example, a meeting skill may produce grounded task proposals and a
follow-up message; communication then goes through
send-as, while task
creation goes through the operator's selected task adapter. n8n, Zapier, or
any other automation provider is optional unless the requested capability is
explicitly about that provider.
- Search the catalog by operator outcome and authority owner, not only by words
present in the request. Consider every material result independently: a
workflow may need different next lanes for a message, task proposal, payment,
publication, or unresolved ambiguity. Reuse the canonical capability at each
boundary and explain why it owns that decision. Do not hide an unhandled
outcome behind a generic "handoff" claim.
- Preserve the context that makes the next operator or skill intelligent.
Handoffs carry the bounded evidence, decision rationale, unresolved
ambiguity, stable content or proposal, intended audience or target, and
effect status needed by the next lane. Do not squash these into a digest,
terse status, or provider payload. Digests bind context; they do not replace
it. Conversely, do not forward unrelated source material or secrets.
- Make finality explicit at every boundary. Distinguish observed evidence,
model interpretation, draft, proposal, authorized action, attempted effect,
provider-confirmed effect, and independently read-back effect. A downstream
route is not proof it ran; a sealed plan is not approval; an adapter request
is not delivery. The public result and operator guide must say what actually
happened and what still has to happen.
- A skill declares domain procedure and policy. Runx owns generic input,
packet, evidence, approval, request, credential, effect, and receipt mechanics.
- Place the capability in its real owner before choosing an implementation.
Reusable skills, end-user and domain-operator commands and UX, local host
loops, local queues, and default local-state orchestration belong in Runx OSS
or the owning product repository.
runx/cloud is not precedent for those
concerns: it may provide the hosted control plane, custody provider
credentials, resolve authoritative grants, and execute a fixed bounded
provider operation. Using Hosted Connect does not move the surrounding skill,
procedure, operator decision, or state into Cloud. If that operator surface is
missing, return work to OSS or the product owner; never extend a Cloud script
or hosted service as a substitute.
- For hosted provider work, compose native
provider.read or
provider.mutate; declare exact scopes and provider operations, and require
provider readback. A scoped provider grant is sufficient by default. When an
act genuinely needs a human decision, put one typed approval request in the
provider.mutate inputs with a concrete reason and action-specific type. The
native provider effect constructs the exact operator summary, binds the
request to the plan, and suspends for runx resume; never add an adjacent
graph approval for the same action. Use an explicit graph approval only for a
consequential decision no native capability owns. One action has one
approval owner. Payment effects must also provide the typed
amount: {units, unit} input so the exact amount is visible and plan-bound;
do not bury it only inside provider-specific payload JSON. Use
expected_result to bind the returned resource identity and result_fields
to admit only the fields the receipt needs. Secret-adjacent operations must
project their result. Pass retry identity through the native
idempotency_key input; do not copy it into the provider payload. Never add a
package token loader or request client.
- Never model human authority as a caller-supplied approval string, boolean, or
reference. A native approval gate must summarize the exact target and effect;
its host-attested packet is the only approval input a credentialed provider
tool may accept. If a provider API requires its own approval reference, derive
the claim- or resource-bound value inside that tool after verifying
approved: true, actor: human, the exact gate id, and the action-specific
gate type. An agent-authored answers value must fail before provider
execution.
run: approval is a human gate. Agent provenance is rejected by the runtime;
use agent-task for model judgment and keep its result distinct from human
authority.
- Treat the selected runner's typed execution requirements as the complete
permission request. Put opaque scope strings, exact non-secret environment
names, the named credential requirement, and runtime metadata on their
canonical runner or source fields—never under
runx, in prose, or in a
package loader. Runx resolves and records those declarations without
inventing a scope vocabulary; the native capability or provider that owns a
scope enforces it.
- Make every public runner contract recursively complete at the authoring
boundary.
X.yaml owns nested properties, closed objects, enums, bounds,
and complete parser-validated invocation examples; runx skill inspect,
MCP, agent tools, and generated exports must project that same declaration.
When an identical input declaration is used by multiple runners, define it
once with the manifest's exact input-definition reference rather than copy
it or invent merge overrides. JavaScript may enforce irreducible
relationships between otherwise valid fields, but must not repeat structural
validation already owned by the profile.
- Dogfood the result through the real agent-facing surface, not only the
package harness. A cold agent must be able to inspect the selected runner,
construct a valid call without reading source or fixtures, understand a
path-specific rejection, and continue from the resulting context. Exercise
every materially different runner; a default-only export cannot certify a
multi-runner skill. For an existing target, use
authoring_context.target_inspection as the canonical runner-contract and
execution-closure evidence. An invalid inspection is repair context, not
permission to guess: read the declared target files, correct the owning
contract, and validate the complete candidate.
- Design evidence admission around the operator's job, not the first provider
implementation. When analysis is useful over local admitted files or
artifacts as well as remote sources, support both through their canonical
evidence boundaries; do not require HTTPS, Hosted Connect, or another
provider merely to analyze evidence already available on the operator's
machine. Provider-specific acquisition remains a separate runner or upstream
skill when it adds real readback value.
- Make permission claims executable through the existing package harness.
Permission-bearing native and provider paths need a realistic admitted case
and, where the harness can exercise that owner, a refusal case with the
required scope or grant withheld. The harness must call the same catalog,
dispatcher, and capability/provider implementation as a real run; never add
a mock permission evaluator, scope vocabulary, or parallel verification
report. This proves enforcement owned by Runx capabilities and providers. It
cannot prove that trusted host code avoided undeclared filesystem, network,
or syscall access, so report that boundary as trusted rather than confined.
- Tool fixtures inherit the exact scopes declared by the canonically resolved
manifest and pass declared packets through the production packet verifier.
Use
expect.output.matches_packet only when the whole fixture output is one
self-described packet; named artifact packets are already verified from the
manifest and should not be asserted through a second fixture path.
- Search the inspected native-tool and skill catalogs before designing files.
Prefer an existing core tool or canonical skill over executable package code.
- Make every public runner input constructible from inspection. Use ordinary
schema for runner-owned nested values. When an input is exactly one
canonical Runx packet, declare type: json plus packet: <packet-id> and
let the runtime resolve the catalog-owned schema into inspection, validation,
exports, registry bundles, and harnesses. Never copy that packet schema into
the consumer. If the canonical schema is too weak to make the input usable,
improve the producing packet contract first; a packet reference is not a
substitute for a complete schema. Do not mint a packet id for a runner-local
nested value, graph intermediate, or one-run implementation detail. A packet
exists only for the complete value crossing a named reusable skill, runtime,
SDK, provider, receipt, or registry boundary, and it must have one active
producer and consumer or an explicit public native owner. Remove the generated
artifact when that ownership disappears. Every public runner still needs at
least one realistic, copy-valid example unless its inputs are empty.
- A named packet must expose its semantic fields or reference a canonical typed
contract. Bare
type: object, unconstrained {}, and opaque property bags do
not make a runner inspectable and must be repaired at the producing contract,
not documented around in prose. Open JSON is admissible only as an explicitly
named protocol extension or generic data payload inside an otherwise bounded
semantic envelope.
- Apply that rule recursively. Every nested
type: object declares meaningful
properties or an explicit additionalProperties policy. If the value is
intentionally arbitrary JSON, declare type: json; do not make an object
declaration imply structure that the contract does not provide.
- Put a producer's nested output shape in that output declaration's
schema.
Do not hand-maintain the same shape in a packet file, fixture, exporter, or
consumer: native parsing, agent context, runtime validation, packet
generation, registry packaging, and harness replay all consume the producer's
declaration.
- Express orchestration through
X.yaml; keep all static agent operating
knowledge and task contracts in SKILL.md. Never put model instructions in
manifests, fixtures, or duplicated prompt fragments.
- Declare every harness-only support file explicitly in
harness.files using a
normalized profile-relative path under fixtures/. Runx stages only those
declared files into the isolated harness workspace; it never guesses
dependencies from arbitrary input strings. Do not turn the declaration into
a second source tree or include unconsumed helpers.
- Put every typed output and packet contract on the step that actually produces
it. A graph runner is composition and its receipt proves that composition; it
must not declare a second runner-level
outputs or artifacts contract with
ambiguous ownership. Every graph runner declares graph.result_from as the
intentional public result boundary. Name the final provider readback or
package/finalize step, not every leaf: approvals, evidence gathering, and
intermediate writes remain available in operator context and receipts without
polluting the result. Multiple producers are valid only for mutually exclusive
branches or when their distinct contracts are intentionally returned together;
simultaneous producers may not emit the same key. When a graph needs one
public result, end it with an explicit package/finalize step and let that
producer own the packet schema.
- Add executable code only for irreducible deterministic domain computation.
Explain its domain boundary and why native tools plus a declarative graph
cannot express it. Do not add code merely to transform Runx contracts.
- For a genuinely separate CLI or protocol tool, keep one canonical
manifest.json. It owns source, inputs and defaults, artifact projection,
scopes and retry/idempotency. Effect and approval stay with the capability
that invokes the tool; never duplicate them in this manifest. Never persist
generated runtime, output, runx, hash, or toolkit fields beside that
contract.
runx tool build validates and reports derived hashes without rewriting the
package. The extension SDK may carry the already-materialized JSON request
and response across a process boundary; it must not become a second manifest
or input-contract owner. The declared entrypoint must execute on the
repository's supported runtime without probing for generated files or
importing uncompiled TypeScript. A bundled tool lives at
tools/<namespace>/<name>/manifest.json, its dotted manifest name must match
that path, and aggregate package admission must bind every static local
source dependency before the package can run or publish.
- Local CLI tools, process MCP servers, and process adapters are trusted host
code. Runx controls their exact invocation, delivered environment and
credentials, lifecycle, bounded output, and evidence; it does not turn
declared scopes into portable filesystem, network, or syscall confinement.
Use this lane only when the operation is genuinely irreducible to native
capabilities, provider adapters, declarative composition, or deterministic
JavaScript. Never author a sandbox declaration, wrapper, or fallback flag.
- When that computation is JavaScript, use the native
type: javascript
source. Prefer one cohesive module named for the skill with focused named
exports of the form (inputs, context) => JSON; split it only when the
computations have genuinely separate ownership. Runx owns input delivery,
output serialization, errors, wall limits, and isolation. Do not add fake
operation inputs, Node command declarations, per-runner wrapper files, or
stdout/environment plumbing. Pure JavaScript receives only its validated
in-memory module bundle, JSON input, and a frozen
context.environment object containing the exact names declared in the
runner's environment.required and environment.optional lists. A missing
required name stops before worker execution; an absent optional name is
omitted. Values never enter the manifest, agent context, inspection output,
or receipts. Environment declarations are for non-secret runtime
configuration; credentials stay on the native credential/provider boundary.
The worker process itself has an empty ambient environment and no workspace
path, filesystem, network, clock, randomness, subprocess, credential, or
provider surface. The default wall limit is two seconds; a runner may declare
timeout_seconds from 1 through 30 when irreducible computation genuinely
needs it. The worker is ECMAScript, not a browser: use the frozen
Runx.parseUrl(value) helper for absolute URLs and do not assume Web or Node
globals exist.
- Classify volume before authoring. Small typed control values belong in normal
runner inputs;
runx skill --inputs is only a bounded transport for one
complete control object. Large immutable local content belongs behind
artifact.admit/bounded pages. Durable history belongs behind
data.read_events cursors or a compact projection. A graph must not carry an
archive, growing event history, or completed-id array simply because one CLI
call can parse it.
- Use deterministic
pages only for irreducible record transforms over one
admitted JSON-array artifact. The runtime owns artifact admission, page
framing, snapshot digest, record boundaries, offsets, retries, and the page
loop; the module owns only
decoding and domain selection. Treat runx_page.artifact_ref as an opaque,
runtime-local read capability that belongs in receipt provenance; never place
it in a plan or idempotency digest. Bind deterministic domain output to
runx_page.whole_digest, which is stable for identical content. Keep
continuation state proportional to the bounded result. Do not add a package
file reader, manual byte cursor, hashing loop, high-volume profile, or raised
worker limit. If safe framing or bounded state is impossible, choose
needs_core or a genuinely separate protocol tool rather than
smuggling filesystem authority into JavaScript.
- Prove a volume path at two materially different scales through the production
owner. The result must be identical across page sizes, cursors must advance,
process count must stay stable where session reuse applies, and failures must
remain distinguishable from empty pages. A larger fixture alone is not
performance evidence.
- A missing generic primitive is not permission for package code. Return
needs_core with no writes and identify either a runtime/security invariant
or two independent existing consumers.
- Never add package-local raw
RUNX_INPUTS_* parsing, generic packet or
evidence hashing, packet wrapping, generic status construction, or provider
simulation when a shared Runx boundary can own it. Package code may retain a
canonical hash only when that hash is an intrinsic field of an established
domain or wire protocol, not as a substitute for receipt or effect integrity.
State that exception at the computation boundary.
- Keep packages concise: normally
SKILL.md, X.yaml, and focused fixtures;
add narrowly scoped references, assets, tools, or domain code only when consumed.
- Judge the whole capability, not proxy metrics. Native reuse, fewer files,
shorter code, green harnesses, and low resource ceilings are valuable only
when the result remains understandable, useful, truthful, and complete.
Keep JavaScript when it performs irreducible domain computation; remove it
when it reimplements runtime mechanics. Never trade away domain semantics or
operator context merely to reduce line count.
- Keep shared computation DRY. A helper used by multiple skills belongs in its
existing native owner or a justified shared primitive, never copied scripts.
- Count the whole replacement and delete displaced scripts, manifests, schemas,
fixtures, and tests in the same change. Do not leave dual paths.
- Do not add package READMEs, changelogs, installation guides, strategy files,
generated state, or credentials.
- Match the documented capability to the execution profile and truthful terminal
state.
- Review the documentation diff for semantic loss. A shorter
SKILL.md is an
improvement only when the removed material was false, duplicated, or
irrelevant and the remaining document still passes the cold-operator test.
- Treat the catalog's manual check as an anti-stub backstop, not a writing
target. The structural title/section/prose floor does not prove a guide is
substantive. Do not pad prose to satisfy a word floor or turn natural
operating guidance into a template checklist.
- Prefer extending an existing owner over adding a near-duplicate skill.
- Preserve registry identity as part of capability ownership. Inspect the live
registry before publishing a shared package; update the intended existing
owner/name rather than creating a first-party neighbor beside an older name.
Preserve an accepted contributor's namespace in the
registry_owner
field of SKILL.md frontmatter; absence means the Runx-owned runx
namespace.
A deliberate rename must migrate or retire the prior identity through the
registry operator. Never transfer a contributor's community-owned row into
the first-party namespace unless that ownership transfer is explicit.
- Treat registry portability as execution truth, not a publish-time smoke test.
A local cross-package skill edge must be present in the digest-bound registry
package bundle, and the publish harness must execute that exact materialized
package. Never copy sibling source beside a harness while omitting it from the
published artifact, rewrite the source graph for registry-only execution, or
certify a package that needs the original checkout to run.
- Include a realistic happy path and refusal, stop, or error path.
- Never treat supplied agent answers as provider-effect proof.
- For every public package, make the native readiness report the acceptance
boundary. One executable
standalone journey must select the actual default
runner and name at least two existing nearby public skills as confusors.
One executable composed journey must consume named prior evidence and state
the work or effects it must not repeat. A journey on a convenient phase runner
cannot prove the standalone default. A graph-level harness may use
exercises_runner only to identify the public runner it really invokes.
- Read
semantic_report.readiness from runx skill inspect; do not recreate its
classification in package code, prose, or a second test script. Public work is
not ready unless evaluated, coldSelection, standaloneDefault, and
composedReuse are true and native semantic diagnostics are empty.
- Keep provider evidence labels exact. Deterministic replay is
harness, not
live. A sealed provider-readback case supplied through caller agent answers
does not prove provider execution. Harnesses must not inherit local Runx
grants, tokens, credential delivery, or global configuration; every fake
binding must be explicit in the fixture, and live proof must come from a
separately identified provider run.
Before admitting an architecture, perform a cold-operator trial against the
actual proposed result:
- Can the operator tell what the skill concluded and which evidence supports
it?
- Can they distinguish missing or ambiguous information from a negative
result?
- Can they tell which effects happened, which are only proposed or
authorized, and which remain unattempted?
- Can they continue each material outcome through the correct canonical skill
and the declared provider-selection boundary without reconstructing lost
context?
- Does one clear owner hold each decision, approval, mutation, and readback?
- Would this still be the architecture chosen from scratch against the current
Runx catalog?
- Can a cold agent actually invoke every public runner from inspection alone,
using local or remote evidence appropriate to the job, without source-diving,
guessed JSON, or an unnecessary provider dependency?
If any answer is no, the package is not ready even if its schemas, tests, and
budgets pass. Fix the capability design or return no_skill/needs_core;
do not compensate with more fixtures, prose padding, or a bespoke wrapper.
Outputs
architecture_decision: the agent's closed ownership and execution design.
architecture_plan: that decision bound by native code to the exact
inspection digest. Design stops here.
change_draft: package bytes and intent authored against the admitted plan;
it contains no model-authored integrity values.
change_bundle: the native, digest-bound transaction candidate produced from
the plan and draft.
apply_result: unchanged, needs-core, or validated-and-applied, with exact
changed/deleted paths, package digest, focused proof, and line/file deltas.
For a shared/public package, this is the exact local half of the registry
publication handoff; registry publish and readback evidence remain separate.
Inputs
objective (required): capability or improvement to deliver.
package_name (optional, build): explicit identity for a newly requested
package; use it for SKILL.md and X.yaml even when the target directory has
a different basename.
repo_root (optional): workspace root; defaults to the caller workspace.
target_dir (required for build, improve, and harness): repo-relative package directory.
project_context (optional): product, repository, and operator constraints.
receipt_id, receipt_summary, harness_output, failure_packet (improve):
failure evidence, including the stable packet from diagnose-skill-run.
Agent task contracts
skill-lab-architecture
Call runx_final_result with exactly one root field,
{"architecture_decision": <decision>}. The inner decision uses
runx.skill.architecture_decision.v1. Choose build, extend_existing,
no_skill, or needs_core. Explain the operator value and the manual's
knowledge contract: purpose, required evidence, decision logic, stop conditions,
and recovery. Assign every required behavior to exactly one real execution lane
(manual, graph, agent_task, native_capability, domain_module,
cli_tool, or provider_adapter). A native lane names a selected capability;
a domain module supplies a specific justification. Record inspected, selected,
and genuinely missing native capabilities; use needs_core only for a runtime
or security invariant or a primitive with two independent existing consumers.
Before calling runx_final_result, call runx.skill.plan once with the exact
authoring_context.base_digest and candidate architecture_decision. Repair
any deterministic architecture error it returns, then submit the same validated
decision. For every native_capability behavior, reuse_ref must be exactly one
entry from native_reuse.selected_capabilities; split a behavior when it needs
more than one capability. This prevalidation is read-only and does not replace
the graph's native digest-binding step.
When package_name is supplied, treat it as the requested package identity;
do not silently rename the package from its target path.
Inspect an existing target in one bounded pass. Use the target file list and
repository root in authoring_context to read the relevant files together with
fs.read_bundle; do not crawl them one at a time or reread files already
present in context. Once the evidence is sufficient, return the declared
architecture decision instead of spending the remaining round budget on
optional discovery.
For every build or extend_existing decision, make the identity decision
explicit. Record the current and proposed name, choose keep, rename,
create, or internalize, state whether the package is public or internal,
and explain why that name is the operation a cold agent will reach for. A
rename or internalization is a clean cutover: identify every consumer and do
not plan aliases or duplicate discovery rows. Internal packages have no public
direct-use contract.
For every public package, declare both operator contexts before authoring:
direct_use names realistic natural-language trigger and non-trigger
requests, the default outcome, routine work the host should do normally, the
exact boundary where Runx adds value, the terminal result, one actionable
blocker behavior, and the context-preserving native escape path.
chain_use names accepted typed inputs, the reusable result, prior evidence
and effects that survive the boundary, and work that must not repeat.
The proof plan must contain distinct selection_trial,
standalone_operator_journey, and composed_operator_journey entries for a
public package. They are different claims: intuitive selection, useful direct
completion, and evidence-preserving composition. A generic harness or sealed
receipt may supplement them but cannot replace them. The selection trial names
at least two real public catalog confusors; the standalone journey runs the
actual default; and the composed journey names both reused prior evidence and
work that must not repeat. The final package inspection must report all four
native readiness facts true with no semantic diagnostics.
Declare effects, authority scopes, approval meaning, provider boundary, skill
routes, resource ceilings, preservation obligations, exact intended deletions,
and a proof plan. For every skill route, state the domain result being handed
off, the canonical capability or authority owner, whether a provider adapter is
required or operator-selected, the context that must survive the boundary, and
the truthful effect state before and after that route. Cover every material
outcome independently. Reject an unnecessary provider pin even when it appears
in prior work or the request's implementation sketch. Apply the cold-operator
trial to the proposed public result and chain before choosing a disposition.
Classify every potentially large value as control input,
immutable artifact, durable cursor/projection, or bounded domain result, and
name its production owner plus small/large proof. Reads, drafts, local
validation, reversible package writes, and routine grant-scoped provider
mutations do not gain ceremonial human approval. Add an exact resumable gate
only when the action genuinely requires a separate human decision. Assign each
such action exactly one approval owner; never pair
an explicit graph approval with an effect-owned approval for the same action.
Budgets are operational ceilings, not guesses to be widened after validation.
Do not write files, calculate a digest, invent provider proof, or solve an
ownership gap with package code.
For a shared/public package, also preserve its intended registry identity and
state whether registry availability is in scope. If it is, the plan ends local
authoring at the exact applied package and names the canonical registry
operator as the separate publish-and-readback boundary. Do not plan embedded
registry HTTP, credentials, auto-publish, or an adjacent owner/name.
For improve, diagnose only from supplied receipt or harness evidence and
distinguish contract, implementation, fixture, environment, and operator
failures. When evidence cannot justify a change, choose extend_existing and
let the author return no_change. For harness, plan fixture-only changes and
preserve all production behavior.
skill-lab-author
Receive the exact native architecture_plan and return one change_draft using
runx.skill.change_draft.v1. Never copy or calculate base_digest,
plan_digest, architecture, or any other integrity field; native bind owns
those values. Choose write, no_skill, no_change, or needs_core in a way
that agrees with the plan. A non-write draft has empty writes and deletes.
A write contains the smallest complete target-relative file set, the exact
planned deletions, a truthful summary and non-goals, and the outputs the package
will actually produce.
When source bytes are needed, read the planned target files together with
fs.read_bundle. Do not spend separate rounds reopening files already supplied
by authoring_context or the architecture plan; reserve the final round for the
complete change_draft.
When package_name is supplied, use it consistently in the SKILL.md
frontmatter and the X.yaml skill field. The directory is a placement
decision, not a second source of package identity.
Put static operating knowledge and task-specific agent rules in SKILL.md and
execution structure in X.yaml. Compose selected native capabilities and
declared skill routes first. Ensure the manual explains what each route is for,
what context crosses it, and what remains unperformed; do not substitute an
adapter name for that explanation. Add a domain module only when the architecture
admits it, and keep the module inside its stated computation boundary. Include
focused proof for a useful path and a stop, refusal, or regression path. In
harness mode, every write or delete must be under fixtures/*.yaml. Preserve
useful behavior and delete superseded implementation in the same draft. Never
add auxiliary docs, generated state, credentials, placeholder modules,
duplicated generic Runx mechanics, or an undeclared provider boundary.
Registry publication code, credentials, and live-state claims are likewise
outside the authored package; preserve only the canonical package identity
needed by the later registry operator.
1---2name: skill-lab3description: Canonical Runx skill-authoring implementation. Use for designing, creating, updating, improving, or adding harness coverage to a Runx skill package; it combines bounded agent judgment with native file writes, inspection, and safe harness validation. When a host skill-creator also triggers, use its general guidance but execute Runx work through this skill.4---56# Skill Lab78Build and improve Runx skills through one authoring surface. Keep judgment in9bounded agent acts and mechanics in native tools:1011```text12inspect target files, catalog ownership, and native/shared tools13→ decide ownership, execution lanes, effects, budgets, and proof14→ bind that architecture to the inspected package digest in native code15→ compose existing capabilities before authoring code16→ author only bounded writes, explicit deletions, and output intent17→ bind those bytes to the admitted architecture in native code18→ validate paths, secret posture, and the complete candidate19→ inspect and safely replay the exact staged package20→ commit that validated bundle through one native transaction21```2223Use the generic host `skill-creator` for platform-wide authoring guidance when24it is available. Do not reproduce Runx package operations from that guidance;25invoke the appropriate `skill-lab` runner so the work is bounded and receipted.2627## Runners2829- `design`: read-only catalog-fit and architecture planning. It returns a30 native digest-bound plan and never authors package bytes. A later build31 re-inspects and replans against its exact target before any write.32- `build` (default): create or update a package after its exact staged bundle33 passes native parsing, inspection, and safe harness replay.34- `improve`: turn one receipt or harness failure into a bounded package update,35 then validate and commit the exact staged bytes.36- `harness`: add fixture files to an existing package and replay the safe native37 harness against the exact candidate before committing it.3839`build`, `improve`, and `harness` write local workspace files. They never40publish, install, push, or mutate an external provider. Native harness replay41runs with isolated Runx home, receipts, and no operator credentials. Invalid42staged packages stop before the target package is touched. Design, inspection,43validation, and the bounded transactional workspace write do not add a human44approval gate; the operator authorizes those reversible local writes by45invoking a runner whose native filesystem steps request46`fs.write`/`fs.delete`. Publication, installation, provider effects, and other47consequential boundaries remain outside this skill and keep their own approval48rules.4950A validated local write is not a published skill. For a shared or public51package, the validated `X.yaml` identity and the exact `target_dir` and52`package_digest` in `apply_result` form the publication candidate. When the53operator's objective includes shipping or registry availability, continue that54exact candidate through the repository's canonical registry operator: publish55under the intended existing owner/name, then independently read back the same56version and digest. Do not call the work shipped while that sync is pending or57unverified. Publication remains a separate authenticated act so Skill Lab58never receives registry credentials or hides a remote mutation inside local59authoring.6061## Authoring rules6263- Start from the operator's recurring job, not the requested package name,64 bounty wording, provider, or implementation sketch. Establish what becomes65 materially easier or newly possible for the operator, what judgment the66 skill contributes, and what durable result it returns. A package that merely67 restates ordinary agent behavior, renames one native call, or produces a68 document with no usable next step is not a valuable skill even when every69 contract and harness passes.70- Treat prior implementations, accepted bounty text, issue suggestions, and71 named integrations as evidence about the intended capability, not binding72 architecture. Preserve the real user outcome and compatibility obligations;73 replace stale ownership, unnecessary providers, and accidental workflow74 shapes when the current catalog has a cleaner canonical route.75- Treat `SKILL.md` as the product manual for both the human operator and the76 operating agent. A person opening it cold must understand what the capability77 does, why and when to use it, what happens end to end, and where it stops.78 Do not reduce that manual to terse model directives, field lists, or a task79 contract.80- Preserve the useful context in an existing skill: its mental model, procedure,81 examples, trade-offs, chain relationships, evidence rules, and recovery82 posture. Rewrite statements that no longer match the implementation; never83 delete the surrounding explanation merely because the executable profile now84 enforces part of it.85- A complete public skill explains, in a structure natural to the capability:86 the recurring job and outcome; when and when not to use it; the operating87 model and sequence; upstream and downstream skill relationships; meaningful88 input and output semantics; authority, approval, evidence, finality, and89 recovery; and relevant edge cases and stop conditions. Include a concrete90 example when it materially clarifies a non-obvious workflow. Do not force91 ceremonial sections onto a simple facade or internal rail.92- Put task-specific agent clauses after the human-readable operating guide.93 They sharpen individual agent acts; they do not replace the guide or carry94 the product's voice by themselves.95- Explain meaningful upstream and downstream skill relationships naturally in96 the operator guide. Do not maintain a second machine-readable dependency97 registry in `SKILL.md`: native execution-closure inspection owns the exact98 edge set and operator preflight surfaces it. Prose explains why the chain99 exists; the runtime proves what it actually calls.100- Design capability chains by responsibility, not by whichever integration is101 easiest to name:102 - The domain skill owns domain evidence, interpretation, policy, and the103 truthful domain result.104 - A canonical capability or authority skill owns a reusable decision such as105 authorizing a send, spending funds, or preparing a release.106 - A provider adapter owns the bounded external API effect and independent107 readback.108 Do not collapse these roles into one package, and do not make a provider109 adapter a required part of a provider-neutral capability. Pin an adapter only110 when the objective genuinely requires provider-specific behavior; otherwise111 return a stable handoff that an operator can route to the selected adapter.112 For example, a meeting skill may produce grounded task proposals and a113 follow-up message; communication then goes through `send-as`, while task114 creation goes through the operator's selected task adapter. n8n, Zapier, or115 any other automation provider is optional unless the requested capability is116 explicitly about that provider.117- Search the catalog by operator outcome and authority owner, not only by words118 present in the request. Consider every material result independently: a119 workflow may need different next lanes for a message, task proposal, payment,120 publication, or unresolved ambiguity. Reuse the canonical capability at each121 boundary and explain why it owns that decision. Do not hide an unhandled122 outcome behind a generic "handoff" claim.123- Preserve the context that makes the next operator or skill intelligent.124 Handoffs carry the bounded evidence, decision rationale, unresolved125 ambiguity, stable content or proposal, intended audience or target, and126 effect status needed by the next lane. Do not squash these into a digest,127 terse status, or provider payload. Digests bind context; they do not replace128 it. Conversely, do not forward unrelated source material or secrets.129- Make finality explicit at every boundary. Distinguish observed evidence,130 model interpretation, draft, proposal, authorized action, attempted effect,131 provider-confirmed effect, and independently read-back effect. A downstream132 route is not proof it ran; a sealed plan is not approval; an adapter request133 is not delivery. The public result and operator guide must say what actually134 happened and what still has to happen.135- A skill declares domain procedure and policy. Runx owns generic input,136 packet, evidence, approval, request, credential, effect, and receipt mechanics.137- Place the capability in its real owner before choosing an implementation.138 Reusable skills, end-user and domain-operator commands and UX, local host139 loops, local queues, and default local-state orchestration belong in Runx OSS140 or the owning product repository. `runx/cloud` is not precedent for those141 concerns: it may provide the hosted control plane, custody provider142 credentials, resolve authoritative grants, and execute a fixed bounded143 provider operation. Using Hosted Connect does not move the surrounding skill,144 procedure, operator decision, or state into Cloud. If that operator surface is145 missing, return work to OSS or the product owner; never extend a Cloud script146 or hosted service as a substitute.147- For hosted provider work, compose native `provider.read` or148 `provider.mutate`; declare exact scopes and provider operations, and require149 provider readback. A scoped provider grant is sufficient by default. When an150 act genuinely needs a human decision, put one typed `approval` request in the151 `provider.mutate` inputs with a concrete reason and action-specific type. The152 native provider effect constructs the exact operator summary, binds the153 request to the plan, and suspends for `runx resume`; never add an adjacent154 graph approval for the same action. Use an explicit graph approval only for a155 consequential decision no native capability owns. One action has one156 approval owner. Payment effects must also provide the typed157 `amount: {units, unit}` input so the exact amount is visible and plan-bound;158 do not bury it only inside provider-specific payload JSON. Use159 `expected_result` to bind the returned resource identity and `result_fields`160 to admit only the fields the receipt needs. Secret-adjacent operations must161 project their result. Pass retry identity through the native162 `idempotency_key` input; do not copy it into the provider payload. Never add a163 package token loader or request client.164- Never model human authority as a caller-supplied approval string, boolean, or165 reference. A native approval gate must summarize the exact target and effect;166 its host-attested packet is the only approval input a credentialed provider167 tool may accept. If a provider API requires its own approval reference, derive168 the claim- or resource-bound value inside that tool after verifying169 `approved: true`, `actor: human`, the exact gate id, and the action-specific170 gate type. An agent-authored `answers` value must fail before provider171 execution.172- `run: approval` is a human gate. Agent provenance is rejected by the runtime;173 use `agent-task` for model judgment and keep its result distinct from human174 authority.175- Treat the selected runner's typed execution requirements as the complete176 permission request. Put opaque scope strings, exact non-secret environment177 names, the named credential requirement, and runtime metadata on their178 canonical runner or source fields—never under `runx`, in prose, or in a179 package loader. Runx resolves and records those declarations without180 inventing a scope vocabulary; the native capability or provider that owns a181 scope enforces it.182- Make every public runner contract recursively complete at the authoring183 boundary. `X.yaml` owns nested properties, closed objects, enums, bounds,184 and complete parser-validated invocation examples; `runx skill inspect`,185 MCP, agent tools, and generated exports must project that same declaration.186 When an identical input declaration is used by multiple runners, define it187 once with the manifest's exact input-definition reference rather than copy188 it or invent merge overrides. JavaScript may enforce irreducible189 relationships between otherwise valid fields, but must not repeat structural190 validation already owned by the profile.191- Dogfood the result through the real agent-facing surface, not only the192 package harness. A cold agent must be able to inspect the selected runner,193 construct a valid call without reading source or fixtures, understand a194 path-specific rejection, and continue from the resulting context. Exercise195 every materially different runner; a default-only export cannot certify a196 multi-runner skill. For an existing target, use197 `authoring_context.target_inspection` as the canonical runner-contract and198 execution-closure evidence. An `invalid` inspection is repair context, not199 permission to guess: read the declared target files, correct the owning200 contract, and validate the complete candidate.201- Design evidence admission around the operator's job, not the first provider202 implementation. When analysis is useful over local admitted files or203 artifacts as well as remote sources, support both through their canonical204 evidence boundaries; do not require HTTPS, Hosted Connect, or another205 provider merely to analyze evidence already available on the operator's206 machine. Provider-specific acquisition remains a separate runner or upstream207 skill when it adds real readback value.208- Make permission claims executable through the existing package harness.209 Permission-bearing native and provider paths need a realistic admitted case210 and, where the harness can exercise that owner, a refusal case with the211 required scope or grant withheld. The harness must call the same catalog,212 dispatcher, and capability/provider implementation as a real run; never add213 a mock permission evaluator, scope vocabulary, or parallel verification214 report. This proves enforcement owned by Runx capabilities and providers. It215 cannot prove that trusted host code avoided undeclared filesystem, network,216 or syscall access, so report that boundary as trusted rather than confined.217- Tool fixtures inherit the exact scopes declared by the canonically resolved218 manifest and pass declared packets through the production packet verifier.219 Use `expect.output.matches_packet` only when the whole fixture output is one220 self-described packet; named artifact packets are already verified from the221 manifest and should not be asserted through a second fixture path.222- Search the inspected native-tool and skill catalogs before designing files.223 Prefer an existing core tool or canonical skill over executable package code.224- Make every public runner input constructible from inspection. Use ordinary225 `schema` for runner-owned nested values. When an input is exactly one226 canonical Runx packet, declare `type: json` plus `packet: <packet-id>` and227 let the runtime resolve the catalog-owned schema into inspection, validation,228 exports, registry bundles, and harnesses. Never copy that packet schema into229 the consumer. If the canonical schema is too weak to make the input usable,230 improve the producing packet contract first; a packet reference is not a231 substitute for a complete schema. Do not mint a packet id for a runner-local232 nested value, graph intermediate, or one-run implementation detail. A packet233 exists only for the complete value crossing a named reusable skill, runtime,234 SDK, provider, receipt, or registry boundary, and it must have one active235 producer and consumer or an explicit public native owner. Remove the generated236 artifact when that ownership disappears. Every public runner still needs at237 least one realistic, copy-valid example unless its inputs are empty.238- A named packet must expose its semantic fields or reference a canonical typed239 contract. Bare `type: object`, unconstrained `{}`, and opaque property bags do240 not make a runner inspectable and must be repaired at the producing contract,241 not documented around in prose. Open JSON is admissible only as an explicitly242 named protocol extension or generic data payload inside an otherwise bounded243 semantic envelope.244- Apply that rule recursively. Every nested `type: object` declares meaningful245 properties or an explicit `additionalProperties` policy. If the value is246 intentionally arbitrary JSON, declare `type: json`; do not make an object247 declaration imply structure that the contract does not provide.248- Put a producer's nested output shape in that output declaration's `schema`.249 Do not hand-maintain the same shape in a packet file, fixture, exporter, or250 consumer: native parsing, agent context, runtime validation, packet251 generation, registry packaging, and harness replay all consume the producer's252 declaration.253- Express orchestration through `X.yaml`; keep all static agent operating254 knowledge and task contracts in `SKILL.md`. Never put model instructions in255 manifests, fixtures, or duplicated prompt fragments.256- Declare every harness-only support file explicitly in `harness.files` using a257 normalized profile-relative path under `fixtures/`. Runx stages only those258 declared files into the isolated harness workspace; it never guesses259 dependencies from arbitrary input strings. Do not turn the declaration into260 a second source tree or include unconsumed helpers.261- Put every typed output and packet contract on the step that actually produces262 it. A graph runner is composition and its receipt proves that composition; it263 must not declare a second runner-level `outputs` or `artifacts` contract with264 ambiguous ownership. Every graph runner declares `graph.result_from` as the265 intentional public result boundary. Name the final provider readback or266 package/finalize step, not every leaf: approvals, evidence gathering, and267 intermediate writes remain available in operator context and receipts without268 polluting the result. Multiple producers are valid only for mutually exclusive269 branches or when their distinct contracts are intentionally returned together;270 simultaneous producers may not emit the same key. When a graph needs one271 public result, end it with an explicit package/finalize step and let that272 producer own the packet schema.273- Add executable code only for irreducible deterministic domain computation.274 Explain its domain boundary and why native tools plus a declarative graph275 cannot express it. Do not add code merely to transform Runx contracts.276- For a genuinely separate CLI or protocol tool, keep one canonical277 `manifest.json`. It owns source, inputs and defaults, artifact projection,278 scopes and retry/idempotency. Effect and approval stay with the capability279 that invokes the tool; never duplicate them in this manifest. Never persist280 generated `runtime`, `output`, `runx`, hash, or toolkit fields beside that281 contract.282 `runx tool build` validates and reports derived hashes without rewriting the283 package. The extension SDK may carry the already-materialized JSON request284 and response across a process boundary; it must not become a second manifest285 or input-contract owner. The declared entrypoint must execute on the286 repository's supported runtime without probing for generated files or287 importing uncompiled TypeScript. A bundled tool lives at288 `tools/<namespace>/<name>/manifest.json`, its dotted manifest name must match289 that path, and aggregate package admission must bind every static local290 source dependency before the package can run or publish.291- Local CLI tools, process MCP servers, and process adapters are trusted host292 code. Runx controls their exact invocation, delivered environment and293 credentials, lifecycle, bounded output, and evidence; it does not turn294 declared scopes into portable filesystem, network, or syscall confinement.295 Use this lane only when the operation is genuinely irreducible to native296 capabilities, provider adapters, declarative composition, or deterministic297 JavaScript. Never author a sandbox declaration, wrapper, or fallback flag.298- When that computation is JavaScript, use the native `type: javascript`299 source. Prefer one cohesive module named for the skill with focused named300 exports of the form `(inputs, context) => JSON`; split it only when the301 computations have genuinely separate ownership. Runx owns input delivery,302 output serialization, errors, wall limits, and isolation. Do not add fake303 operation inputs, Node command declarations, per-runner wrapper files, or304 stdout/environment plumbing. Pure JavaScript receives only its validated305 in-memory module bundle, JSON input, and a frozen306 `context.environment` object containing the exact names declared in the307 runner's `environment.required` and `environment.optional` lists. A missing308 required name stops before worker execution; an absent optional name is309 omitted. Values never enter the manifest, agent context, inspection output,310 or receipts. Environment declarations are for non-secret runtime311 configuration; credentials stay on the native credential/provider boundary.312 The worker process itself has an empty ambient environment and no workspace313 path, filesystem, network, clock, randomness, subprocess, credential, or314 provider surface. The default wall limit is two seconds; a runner may declare315 `timeout_seconds` from 1 through 30 when irreducible computation genuinely316 needs it. The worker is ECMAScript, not a browser: use the frozen317 `Runx.parseUrl(value)` helper for absolute URLs and do not assume Web or Node318 globals exist.319- Classify volume before authoring. Small typed control values belong in normal320 runner inputs; `runx skill --inputs` is only a bounded transport for one321 complete control object. Large immutable local content belongs behind322 `artifact.admit`/bounded pages. Durable history belongs behind323 `data.read_events` cursors or a compact projection. A graph must not carry an324 archive, growing event history, or completed-id array simply because one CLI325 call can parse it.326- Use deterministic `pages` only for irreducible record transforms over one327 admitted JSON-array artifact. The runtime owns artifact admission, page328 framing, snapshot digest, record boundaries, offsets, retries, and the page329 loop; the module owns only330 decoding and domain selection. Treat `runx_page.artifact_ref` as an opaque,331 runtime-local read capability that belongs in receipt provenance; never place332 it in a plan or idempotency digest. Bind deterministic domain output to333 `runx_page.whole_digest`, which is stable for identical content. Keep334 continuation state proportional to the bounded result. Do not add a package335 file reader, manual byte cursor, hashing loop, high-volume profile, or raised336 worker limit. If safe framing or bounded state is impossible, choose337 `needs_core` or a genuinely separate protocol tool rather than338 smuggling filesystem authority into JavaScript.339- Prove a volume path at two materially different scales through the production340 owner. The result must be identical across page sizes, cursors must advance,341 process count must stay stable where session reuse applies, and failures must342 remain distinguishable from empty pages. A larger fixture alone is not343 performance evidence.344- A missing generic primitive is not permission for package code. Return345 `needs_core` with no writes and identify either a runtime/security invariant346 or two independent existing consumers.347- Never add package-local raw `RUNX_INPUTS_*` parsing, generic packet or348 evidence hashing, packet wrapping, generic status construction, or provider349 simulation when a shared Runx boundary can own it. Package code may retain a350 canonical hash only when that hash is an intrinsic field of an established351 domain or wire protocol, not as a substitute for receipt or effect integrity.352 State that exception at the computation boundary.353- Keep packages concise: normally `SKILL.md`, `X.yaml`, and focused fixtures;354 add narrowly scoped references, assets, tools, or domain code only when consumed.355- Judge the whole capability, not proxy metrics. Native reuse, fewer files,356 shorter code, green harnesses, and low resource ceilings are valuable only357 when the result remains understandable, useful, truthful, and complete.358 Keep JavaScript when it performs irreducible domain computation; remove it359 when it reimplements runtime mechanics. Never trade away domain semantics or360 operator context merely to reduce line count.361- Keep shared computation DRY. A helper used by multiple skills belongs in its362 existing native owner or a justified shared primitive, never copied scripts.363- Count the whole replacement and delete displaced scripts, manifests, schemas,364 fixtures, and tests in the same change. Do not leave dual paths.365- Do not add package READMEs, changelogs, installation guides, strategy files,366 generated state, or credentials.367- Match the documented capability to the execution profile and truthful terminal368 state.369- Review the documentation diff for semantic loss. A shorter `SKILL.md` is an370 improvement only when the removed material was false, duplicated, or371 irrelevant and the remaining document still passes the cold-operator test.372- Treat the catalog's manual check as an anti-stub backstop, not a writing373 target. The structural title/section/prose floor does not prove a guide is374 substantive. Do not pad prose to satisfy a word floor or turn natural375 operating guidance into a template checklist.376- Prefer extending an existing owner over adding a near-duplicate skill.377- Preserve registry identity as part of capability ownership. Inspect the live378 registry before publishing a shared package; update the intended existing379 owner/name rather than creating a first-party neighbor beside an older name.380 Preserve an accepted contributor's namespace in the `registry_owner`381 field of `SKILL.md` frontmatter; absence means the Runx-owned `runx`382 namespace.383 A deliberate rename must migrate or retire the prior identity through the384 registry operator. Never transfer a contributor's community-owned row into385 the first-party namespace unless that ownership transfer is explicit.386- Treat registry portability as execution truth, not a publish-time smoke test.387 A local cross-package skill edge must be present in the digest-bound registry388 package bundle, and the publish harness must execute that exact materialized389 package. Never copy sibling source beside a harness while omitting it from the390 published artifact, rewrite the source graph for registry-only execution, or391 certify a package that needs the original checkout to run.392- Include a realistic happy path and refusal, stop, or error path.393- Never treat supplied agent answers as provider-effect proof.394- For every public package, make the native readiness report the acceptance395 boundary. One executable `standalone` journey must select the actual default396 runner and name at least two existing nearby public skills as `confusors`.397 One executable `composed` journey must consume named prior evidence and state398 the work or effects it must not repeat. A journey on a convenient phase runner399 cannot prove the standalone default. A graph-level harness may use400 `exercises_runner` only to identify the public runner it really invokes.401- Read `semantic_report.readiness` from `runx skill inspect`; do not recreate its402 classification in package code, prose, or a second test script. Public work is403 not ready unless `evaluated`, `coldSelection`, `standaloneDefault`, and404 `composedReuse` are true and native semantic diagnostics are empty.405- Keep provider evidence labels exact. Deterministic replay is `harness`, not406 `live`. A sealed provider-readback case supplied through caller agent answers407 does not prove provider execution. Harnesses must not inherit local Runx408 grants, tokens, credential delivery, or global configuration; every fake409 binding must be explicit in the fixture, and live proof must come from a410 separately identified provider run.411412Before admitting an architecture, perform a cold-operator trial against the413actual proposed result:4144151. Can the operator tell what the skill concluded and which evidence supports416 it?4172. Can they distinguish missing or ambiguous information from a negative418 result?4193. Can they tell which effects happened, which are only proposed or420 authorized, and which remain unattempted?4214. Can they continue each material outcome through the correct canonical skill422 and the declared provider-selection boundary without reconstructing lost423 context?4245. Does one clear owner hold each decision, approval, mutation, and readback?4256. Would this still be the architecture chosen from scratch against the current426 Runx catalog?4277. Can a cold agent actually invoke every public runner from inspection alone,428 using local or remote evidence appropriate to the job, without source-diving,429 guessed JSON, or an unnecessary provider dependency?430431If any answer is no, the package is not ready even if its schemas, tests, and432budgets pass. Fix the capability design or return `no_skill`/`needs_core`;433do not compensate with more fixtures, prose padding, or a bespoke wrapper.434435## Outputs436437- `architecture_decision`: the agent's closed ownership and execution design.438- `architecture_plan`: that decision bound by native code to the exact439 inspection digest. Design stops here.440- `change_draft`: package bytes and intent authored against the admitted plan;441 it contains no model-authored integrity values.442- `change_bundle`: the native, digest-bound transaction candidate produced from443 the plan and draft.444- `apply_result`: unchanged, needs-core, or validated-and-applied, with exact445 changed/deleted paths, package digest, focused proof, and line/file deltas.446 For a shared/public package, this is the exact local half of the registry447 publication handoff; registry publish and readback evidence remain separate.448449## Inputs450451- `objective` (required): capability or improvement to deliver.452- `package_name` (optional, build): explicit identity for a newly requested453 package; use it for `SKILL.md` and `X.yaml` even when the target directory has454 a different basename.455- `repo_root` (optional): workspace root; defaults to the caller workspace.456- `target_dir` (required for `build`, `improve`, and `harness`): repo-relative package directory.457- `project_context` (optional): product, repository, and operator constraints.458- `receipt_id`, `receipt_summary`, `harness_output`, `failure_packet` (improve):459 failure evidence, including the stable packet from `diagnose-skill-run`.460461## Agent task contracts462463### `skill-lab-architecture`464465Call `runx_final_result` with exactly one root field,466`{"architecture_decision": <decision>}`. The inner decision uses467`runx.skill.architecture_decision.v1`. Choose `build`, `extend_existing`,468`no_skill`, or `needs_core`. Explain the operator value and the manual's469knowledge contract: purpose, required evidence, decision logic, stop conditions,470and recovery. Assign every required behavior to exactly one real execution lane471(`manual`, `graph`, `agent_task`, `native_capability`, `domain_module`,472`cli_tool`, or `provider_adapter`). A native lane names a selected capability;473a domain module supplies a specific justification. Record inspected, selected,474and genuinely missing native capabilities; use `needs_core` only for a runtime475or security invariant or a primitive with two independent existing consumers.476Before calling `runx_final_result`, call `runx.skill.plan` once with the exact477`authoring_context.base_digest` and candidate `architecture_decision`. Repair478any deterministic architecture error it returns, then submit the same validated479decision. For every `native_capability` behavior, `reuse_ref` must be exactly one480entry from `native_reuse.selected_capabilities`; split a behavior when it needs481more than one capability. This prevalidation is read-only and does not replace482the graph's native digest-binding step.483When `package_name` is supplied, treat it as the requested package identity;484do not silently rename the package from its target path.485486Inspect an existing target in one bounded pass. Use the target file list and487repository root in `authoring_context` to read the relevant files together with488`fs.read_bundle`; do not crawl them one at a time or reread files already489present in context. Once the evidence is sufficient, return the declared490architecture decision instead of spending the remaining round budget on491optional discovery.492493For every `build` or `extend_existing` decision, make the identity decision494explicit. Record the current and proposed name, choose `keep`, `rename`,495`create`, or `internalize`, state whether the package is public or internal,496and explain why that name is the operation a cold agent will reach for. A497rename or internalization is a clean cutover: identify every consumer and do498not plan aliases or duplicate discovery rows. Internal packages have no public499direct-use contract.500501For every public package, declare both operator contexts before authoring:502503- `direct_use` names realistic natural-language trigger and non-trigger504 requests, the default outcome, routine work the host should do normally, the505 exact boundary where Runx adds value, the terminal result, one actionable506 blocker behavior, and the context-preserving native escape path.507- `chain_use` names accepted typed inputs, the reusable result, prior evidence508 and effects that survive the boundary, and work that must not repeat.509510The proof plan must contain distinct `selection_trial`,511`standalone_operator_journey`, and `composed_operator_journey` entries for a512public package. They are different claims: intuitive selection, useful direct513completion, and evidence-preserving composition. A generic harness or sealed514receipt may supplement them but cannot replace them. The selection trial names515at least two real public catalog confusors; the standalone journey runs the516actual default; and the composed journey names both reused prior evidence and517work that must not repeat. The final package inspection must report all four518native readiness facts true with no semantic diagnostics.519520Declare effects, authority scopes, approval meaning, provider boundary, skill521routes, resource ceilings, preservation obligations, exact intended deletions,522and a proof plan. For every skill route, state the domain result being handed523off, the canonical capability or authority owner, whether a provider adapter is524required or operator-selected, the context that must survive the boundary, and525the truthful effect state before and after that route. Cover every material526outcome independently. Reject an unnecessary provider pin even when it appears527in prior work or the request's implementation sketch. Apply the cold-operator528trial to the proposed public result and chain before choosing a disposition.529Classify every potentially large value as control input,530immutable artifact, durable cursor/projection, or bounded domain result, and531name its production owner plus small/large proof. Reads, drafts, local532validation, reversible package writes, and routine grant-scoped provider533mutations do not gain ceremonial human approval. Add an exact resumable gate534only when the action genuinely requires a separate human decision. Assign each535such action exactly one approval owner; never pair536an explicit graph approval with an effect-owned approval for the same action.537Budgets are operational ceilings, not guesses to be widened after validation.538Do not write files, calculate a digest, invent provider proof, or solve an539ownership gap with package code.540541For a shared/public package, also preserve its intended registry identity and542state whether registry availability is in scope. If it is, the plan ends local543authoring at the exact applied package and names the canonical registry544operator as the separate publish-and-readback boundary. Do not plan embedded545registry HTTP, credentials, auto-publish, or an adjacent owner/name.546547For `improve`, diagnose only from supplied receipt or harness evidence and548distinguish contract, implementation, fixture, environment, and operator549failures. When evidence cannot justify a change, choose `extend_existing` and550let the author return `no_change`. For `harness`, plan fixture-only changes and551preserve all production behavior.552553### `skill-lab-author`554555Receive the exact native `architecture_plan` and return one `change_draft` using556`runx.skill.change_draft.v1`. Never copy or calculate `base_digest`,557`plan_digest`, architecture, or any other integrity field; native bind owns558those values. Choose `write`, `no_skill`, `no_change`, or `needs_core` in a way559that agrees with the plan. A non-write draft has empty `writes` and `deletes`.560A write contains the smallest complete target-relative file set, the exact561planned deletions, a truthful summary and non-goals, and the outputs the package562will actually produce.563564When source bytes are needed, read the planned target files together with565`fs.read_bundle`. Do not spend separate rounds reopening files already supplied566by `authoring_context` or the architecture plan; reserve the final round for the567complete `change_draft`.568569When `package_name` is supplied, use it consistently in the `SKILL.md`570frontmatter and the `X.yaml` `skill` field. The directory is a placement571decision, not a second source of package identity.572573Put static operating knowledge and task-specific agent rules in `SKILL.md` and574execution structure in `X.yaml`. Compose selected native capabilities and575declared skill routes first. Ensure the manual explains what each route is for,576what context crosses it, and what remains unperformed; do not substitute an577adapter name for that explanation. Add a domain module only when the architecture578admits it, and keep the module inside its stated computation boundary. Include579focused proof for a useful path and a stop, refusal, or regression path. In580`harness` mode, every write or delete must be under `fixtures/*.yaml`. Preserve581useful behavior and delete superseded implementation in the same draft. Never582add auxiliary docs, generated state, credentials, placeholder modules,583duplicated generic Runx mechanics, or an undeclared provider boundary.584Registry publication code, credentials, and live-state claims are likewise585outside the authored package; preserve only the canonical package identity586needed by the later registry operator.