Target outcome

Place the business rules and required source code under /oasn so OpenClaw's main Agent can handle the same class of task in both development WebChat and formal invocations.

Confirm the target runtime first

ItemCurrent development Workspace baselineDevelopment implication
Business root/oasnBusiness files, Skills, Plugins, and optional services are all rooted here.
Agent RuntimeOpenClaw 2026.6.11Configuration and extensions must be validated against this pinned version.
Operating systemDebian GNU/Linux 12, amd64If local development uses another platform, remote verification remains authoritative.
Resources2 vCPU / 4 GiB / 10 GiB rootfsAvoid builds, models, or resident services that exceed these limits.
Preinstalled toolsNode.js 22, Python 3.12, Git, OpenSSHThe CLI does not report their exact versions. Measure them in the active Workspace with the commands below.

After the Workspace reaches status=active, run oasn-sa-dev workspace connect --workspace-id <workspace_id> using an existing local key. Only when the result reports ssh_binding_status=bound and ssh_verified=true should you copy its ssh_command exactly, enter the current Workspace, and run:

node --version
npm --version
python3 --version
python3 -m pip --version
git --version

Record the actual output in this development run's notes. Do not infer exact patch versions from this handbook, installation logs, or another Workspace.

Program area in the version workspace
Version workspace. The Program area shows VM, Chat, Models, and Resources. The actual business implementation is under remote /oasn.

Recommended directory structure

/oasn
/oasn/
├── AGENTS.md                              # Business rules for the main Agent
├── SOUL.md                                # Optional: voice and boundaries
├── IDENTITY.md                            # Optional: identity description
├── USER.md                                # Optional: user-context conventions
├── TOOLS.md                               # Optional: Tool usage instructions
├── skills/<skill-name>/SKILL.md           # Optional: business Skill
├── .openclaw/extensions/<plugin-id>/      # Optional: Workspace Plugin
├── service/                               # Optional: business service or source
└── Other business source and static assets
Do not treat runtime state as the Program.

Sessions, logs, PIDs, device identities, authentication databases, each Agent's models.json, Secrets, caches, and browser data must not become version content. /opt/oasn/platform and /usr/local/bin/openclaw are managed by the platform and may be overwritten during publishing.

Implement in this order

  1. Start with one clearly defined task

    In AGENTS.md, define applicable inputs, required information, output format, failure semantics, and safety boundaries. Make the smallest text-only task work before adding files, Tools, Plugins, or services.

  2. Make sure the capability belongs to the main Agent

    Formal invocations always enter through main. The main Agent may call other Agents or subagents, but do not configure the complete business capability only on another Agent.

  3. Place extensions in standard locations

    Put business Skills under /oasn/skills/<skill-name>/ and Workspace Plugins under /oasn/.openclaw/extensions/<plugin-id>/. Do not create unused directories merely to match the example structure.

  4. Validate dependencies in the target environment

    A dependency declaration, installation log, or existing file is not proof that a dependency works. Actually test the import/module, system command, Plugin runtime, any required service reload, and one real business request.

  5. Validate main through WebChat

    Use only the WebChat URL associated with the current active Workspace, and cover normal, attachment, and boundary requests. See “Testing and Acceptance” for the detailed gates.

Formal input contract

An ordinary Skill or Plugin normally handles the messages and attachment paths received by main directly; it does not need to parse the complete JSON itself. Only when the business logic truly requires the structured raw input should it read:

/oasn/in/invocation.json
FieldMeaningConstraint
input.user_promptUser text for this invocationIf it is empty or insufficient, explicitly ask the user for what is missing; do not invent it.
input.attachmentsList of attachment paths for this invocationProcess only the listed paths. Do not scan directories, guess paths, or reuse files from an earlier invocation.

/oasn/in is platform input for a formal invocation. The Program must not write to it or use it as persistent state. The actual invocation.json also contains platform and runtime fields and may carry short-lived sensitive material; never copy the entire file into logs, the final reply, or a screenshot. Development WebChat does not guarantee creation of the same formal-invocation JSON, so seeing a local file in WebChat is not evidence that the formal input contract has passed. See Structured Input and WebUI JSON for a sanitized sample, parsing code, and formal acceptance steps.

Output contract

Definition of done

The Program is complete only when all of the following are true: