Skills and rules for the NanoClaw host agent (Claude Code on Mac), covering plugin promotion, container management, staging checks, repository safety, and upstream updates.
91%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Medium
Suggest reviewing before use
Contract: group-task-snapshot-v3
jbaruch/nanoclaw owns /workspace/ipc/current_tasks.json and /workspace/ipc/available_groups.json; src/group-snapshots.ts writes both projections.group-task-snapshot-v3 accepts legacy top-level arrays with record versions 0/1, unchanged published version-2 envelopes and the current version-3 envelope below. After the verified writer cutover, retire legacy arrays and version-2 envelopes from projection readers' accepted set as required below.schema_version, group_folder, generated_at, capabilities and tasks.schema_version is integer 3; group_folder is the actual registered receiving folder, using the folder syntax below; generated_at is the host's canonical UTC ISO-8601 timestamp with milliseconds.capabilities has exactly boolean floating_once and floating_cron. The compatible host produces these declarations from its implementation, never caller input or a mutable readiness flag.tasks is a complete array of version-3 task records for that receiving view. Empty arrays remain complete; the envelope can declare feature support without inventing a task.schedule_timezone. Their schema_version is integer 3. The finite historical retention grammar below belongs to version 3, not the published version-2 format.schedule_timezone is the actual stored null, literal local or valid IANA name. Do not synthesize it from current timezone, prompt, next run or missing source data.context_mode is the actual group or isolated value, never a default inferred from prompt or script.schema_version or integer schema_version: 0 and the same original fields below except context_mode; that field is absent or ignored in version 0 and supplies no context-mode proof.schema_version: 1, a groups array and UTC ISO-8601 lastSync; each group record explicitly carries integer schema_version: 1 and the field contract below.| Task field | Presence, JSON type and format for a usable record |
|---|---|
schema_version | Required integer 3 for a version-3 envelope row; integer 2 for unchanged version-2 rows; integer 1 for version 1; absent or integer 0 for legacy version 0 |
id | Required nonempty string containing the exact native task id; opaque, no default |
groupFolder | Required string naming the registered folder; native folder syntax is [A-Za-z0-9][A-Za-z0-9_-]{0,63}, with reserved global excluded |
prompt | Required stored prompt string; historical serialized Buffer values may be displayed defensively but never satisfy an exact string binding |
script | Optional string or null; omission/null means no script; native refreshers may omit an empty string, which supplies no executable-script proof |
schedule_type | Required string cron, interval or once |
schedule_value | Required string: native cron expression, decimal interval milliseconds or native ISO-8601 once value; legacy once values may use host-local time |
context_mode | Required version-1/2/3 string group or isolated; absent/ignored in version 0 |
schedule_timezone | Required actual null, local or valid IANA string in versions 2/3; absent/unproven in legacy versions |
status | Required stored string active, paused or completed; cancellation removes the task |
next_run | Required native ISO-8601 timestamp string or null; no fabricated next run |
| Group field | Presence, JSON type and format |
|---|---|
schema_version | Required integer literal 1 on every record |
jid | Required nonempty opaque native chat-id string |
name | Required native display-name string; no identity or approval authority |
lastActivity | Required native ISO-8601 activity timestamp string |
isRegistered | Required boolean |
folder | Required registered folder string when isRegistered is true; otherwise optional, with no default; same folder syntax as task records |
containerConfig | Optional host registration-config object; never caller-supplied role authority |
requiresTrigger | Optional host registration boolean; no synthesized default |
Separate a complete read-only inventory from a selected task's usable effect proof. The expanded historical grammar below applies only to current version-3 envelopes and records. Legacy arrays with record versions 0/1 and published version-2 envelopes retain their original grammar during compatibility; these newly accepted historical forms never become usable old-version effect or absence proof. Preserve unsupported old rows unchanged and hold that readback until the host supplies the current projection. Never drop a historical row, rewrite its schedule or infer a missing timezone to make an inventory usable.
The following complete version-3 historical records can remain in an inventory without supplying new effect proof:
status: cancelled is a retained historical tombstone. Keep its id present; it is not authoritative native removal, active creation or permission to re-arm an effect. Current native cancellation still removes the task.YYYY-MM-DD, or YYYY-MM-DD followed by T or one space and HH:mm[:ss[.fraction]]. Preserve the literal. Arbitrary human date strings and invalid calendar/time components are not accepted by this compatibility path.local does not qualify for this historical exception.parseInt(value, 10) result is a finite positive safe integer, including historical fractional or suffix forms. Preserve the full string; do not replace it with the parsed integer. A selected isolated watcher still requires the exact declared decimal interval contract.These cases do not relax required fields, JSON types, supported record versions, unique ids, actual scope, stable attachment or freshness. Partial records, unknown forms and malformed native declarations still hold the operation. A complete retained inventory can establish that a selected id is absent only by retaining and checking every id; a cancelled or unusable selected row is still present.
Creation, native wake, watcher binding and cancellation recovery separately validate the selected task's usable status and its exact intended schedule, timezone, context, script and prompt. Historical retention does not verify creation, authorize a claim/send, re-arm an uncertain cancellation or enable a native reminder from a historical row. A capability declaration describes the installed host implementation, not those historical rows' execution or delivery.
Read the installed jbaruch/nanoclaw-host provider's declared group-IPC rule and this complete reference before selecting native scheduling. The rule's taskSnapshotContract marker is group-task-snapshot-v3. A source checkout, copied document, tool listing, caller-supplied JSON or probe task supplies no installed capability proof.
A complete, fresh, scope-matching version-3 envelope on the protected host projection can declare current host floating support. Supported legacy arrays and published version-2 envelopes remain read-only compatibility inputs and do not enable new native plans. A legacy array supplies no timezone proof. Malformed, unsupported, linked, stale or rebound input holds the operation; it is not an empty inventory or a successful fallback. Validate every record and unique native id before effect readback or absence proof.
Capability-only discovery distinguishes the absence of a current declaration from effect proof. After fixed-path, bounded regular-file, single-link and unchanged held/named attachment checks, a legacy top-level array means unavailable for native selection even if its age or row content cannot prove an effect. That discovery result never validates the array for creation, cancellation or absence; those readers still require the complete supported inventory and operation freshness. Malformed, unsupported or stale native envelopes remain refusals, not a successful fallback.
The projection must be protected against writes by its consuming container through every alias before capability selection or effect readback. Trusted/Main mount the fixed IPC directory read-only, with only the existing canonical outgoing messages/tasks and own-session input directories writable. Preserve untrusted visibility and repair-lane isolation; refuse additional writable aliases intersecting host IPC authority. A file bind alone is insufficient when atomic replacement would leave a reader on an old inode. Before accepting version 3 for new native capability, check native read-only mount evidence on the held projection descriptor (os.fstatvfs(fd).f_flag & os.ST_RDONLY in the Python consumer); numeric ownership/mode or a caller flag does not establish this. Refuse a writable or indeterminate channel. This check proves the current channel, not an arbitrary executable; the verified cohort and alias guard remain required.
The declaration supplies no owner identity, approval, task creation, execution or delivery proof. It does not assert inspection of an arbitrary agent executable. Verify the actual compatible host and MCP images, all consumers and retired old SDK sessions through the ordered rollout before enabling native selection. Use only the fixed host projection and actual runtime context; no caller path, role or capability selector.
NANOCLAW_CHAT_JID; its SDK context supplies NANOCLAW_GROUP_FOLDER and NANOCLAW_IS_MAIN from the registered group.group_folder to actual host-derived context; preserve Main-all, trusted-own and untrusted-none filtering.schedule_timezone for zone proof; legacy records never establish it.generated_at and stable file freshness at least as new as the scheduling operation before accepting version-2/3 effect readback.{type: "cancel_task", taskId}; host src/ipc-handlers/tasks.ts derives authorization from the source folder, never caller-supplied role flags.The existing host ContainerInput.taskOccurrence has exactly taskId and canonical UTC scheduledFor. Forward that same host scheduling metadata to prechecks through nativeContextEnv as NANOCLAW_TASK_OCCURRENCE, matching its existing MCP use. Missing or malformed metadata supplies no accepted dispatch basis. Never manufacture environment values or treat them as a role, owner approval, send acknowledgment or effect attestation.
A native floating once precheck matches its immutable reminder/task contract against complete fresh version-3 readback: the same native id, local timezone, once wall time, prompt/script/context and the host's pre-dispatched completed row whose retained next_run equals scheduledFor. Evaluate its accepted due instant in UTC and use the existing durable once claim. Do not repeat hourly fallback's current-zone eligibility check after native dispatch; a timezone change after dispatch must not permanently discard the one-shot. Preserve unknown outcomes, existing claims and no-replay cancellation/mirror handling.
For native recurring dispatch, keep taskOccurrence unchanged. A separate optional ContainerInput.taskDispatch has exactly integer schema_version: 1, the same taskId, canonical UTC scheduledFor and valid IANA timezone. Capture the actual effective scheduling zone in the same synchronous eligibility decision before pre-advance/enqueue; preserve it through queueing and awaits. Never infer an old dispatch zone from UTC or a later timezone read. Forward this record as NANOCLAW_TASK_DISPATCH; omit absent legacy metadata and clear inherited values before forwarding actual host context. Malformed present metadata refuses.
A native cron precheck requires matching occurrence/dispatch coordinates and fresh complete own row-3 readback with the immutable cron/local/context/script/prompt contract. Derive its logical date from accepted scheduledFor in captured timezone, then use the existing locked date-occurrence claim. Do not retag the date or run hourly fallback eligibility against a later current timezone. Missing, historical unbound or mismatched metadata holds without guessed fallback, reset or effect replay. The scheduling declaration does not replace these bindings.
This metadata does not prove a live owner request, historical timezone transition, send or delivery. Keep those acceptance claims separate. Existing fallback and pinned entries retain their original versions and behavior; no automatic conversion, rekey, migration or reset is authorized.
cancel_task accepts task_id and optional request_id.TASK_CANCEL_REQUEST_ID in host-owned src/task-cancel-result.ts; the co-shipped MCP reader is container/agent-runner/src/task-cancel-result.ts.src/ipc-handlers/tasks.ts; docs/task-cancellation-results.md owns the complete schema, compatibility and failure semantics.schema_version, request_id, task_id, outcome and UTC observed_at.cancelled, absent, failed, denied and uncertain; only a correlated terminal failed result supplies definite non-application proof for recovery.observed_at, the same own id/group and exact intended schedule/context/script/prompt before recording one new cancellation attempt.src/ipc-auth.test.ts and container/agent-runner/src/task-cancel-result.test.ts; consumer jbaruch/nanoclaw-admin tests/test_watcher_workflow.py.jbaruch/nanoclaw src/group-snapshots.test.ts and container/agent-runner/src/format-task-row.test.ts; watcher consumer coverage lives in jbaruch/nanoclaw-admin tests/test_watcher_workflow.py..tessl-plugin
rules
skills
add-ugos-project
check-staging
extract-to-overlay
host-contracts
references
scripts
nuke
promote
reconcile
ship-code
update-from-upstream