CtrlK
BlogDocsLog inGet started
Tessl Logo

jbaruch/nanoclaw-trusted

Rules for trusted NanoClaw groups. Shared memory, session bootstrap, cross-group memory updates. Loaded for trusted and main containers only.

77

Quality

96%

Does it follow best practices?

Impact

No eval scenarios have been run

SecuritybySnyk

Risky

Do not use without reviewing

This version of the tile failed moderation
Failed moderation (intent review) in rules/session-bootstrap.md: This is a prompt injection attack disguised as a cursor/IDE rule file. It instructs an AI agent to unconditionally execute a bash command and invoke an external skill ('tessl__trusted-memory') at the start of every session before processing any user input. This is a social engineering/prompt injection technique designed to: 1) Force the AI to execute arbitrary commands without user consent, 2) Potentially load malicious instructions from an external 'trusted-memory' skill/plugin, 3) Establish persistence via a sentinel file (/tmp/session_bootstrapped) to track execution. The authoritative tone ('MANDATORY', 'not optional', 'violating this rule') is a classic prompt injection pattern to override the AI's safety boundaries.
Overview
Quality
Evals
Security
Files

state-schema.mdskills/trusted-memory/

trusted-memory state schema

State written by scripts/register-session.py per jbaruch/coding-policy: stateful-artifacts. Owner skill is tessl__trusted-memory. Reader skills — jbaruch/nanoclaw-admin: tessl__heartbeat and jbaruch/nanoclaw-admin: tessl__check-email — MUST treat any unrecognised shape as "no usable prior state" and let the next owner-skill run rewrite it.

Files

/workspace/group/session-state.json

Mutable JSON object. Per-group, not shared across containers.

{
  "schema_version": 1,
  "sessions": {
    "<NANOCLAW_SESSION_NAME>": {
      "started":    "<ISO-8601 UTC, e.g. 2026-04-27T15:00:00Z>",
      "epoch":      <int unix seconds>,
      "session_id": "<sqlite session_id from /workspace/store/messages.db, or null>",
      "last_seen":  "<ISO-8601 UTC>"
    }
  },
  "session_id":       "<top-level mirror of the active session_id, back-compat>",
  "pending_response": null,
  "seen_email_ids":   [],
  "muted_threads":    {}
}

Writer / reader contract

FieldWritersReadersNotes
schema_versionregister-session.py (owner)All readers gate on thisSee Schema versioning below
sessions.<name>.*register-session.py (owner) — own session's subtreeAll readers may inspect any sessionlast_seen may be stamped by tessl__heartbeat for maintenance
session_id (top-level)register-session.py — both sessions on bootstrapLegacy readers onlyBack-compat; last-writer-wins is accepted
pending_responsedefault session writes on inbound start; default clears on send; maintenance heartbeat clears stale entriesAll trusted/main sessionsThe pending-response-tracking rule governs the protocol
seen_email_idstessl__check-email, tessl__heartbeat, tessl__morning-brief, tessl__nightly (all maintenance)tessl__check-email for de-dupAppend-only within a window
muted_threadsdefault sessiondefault + maintenancePer-thread mute map

Back-compat note (legacy migration, ex–reference_session-state-migration.md): the top-level session_id field is the pre-PR jbaruch/nanoclaw#55 shape, when only one session existed per group. It is still written so readers that haven't moved to the per-session subtree continue to work. New readers SHOULD use sessions.<name>.session_id. Old single-session files are accepted on read — register-session.py adds the sessions subtree without dropping the top-level field, so the migration is in-place and idempotent.

Other writers on this file must take fcntl.LOCK_EX on /workspace/group/session-state.json.lock for the duration of their read-modify-write cycle. Current participants: jbaruch/nanoclaw-admin: tessl__heartbeat (writes last_seen, clears stale pending_response) and jbaruch/nanoclaw-admin: tessl__check-email (writes seen_email_ids, pending_response, muted_threads). Without the shared lock, concurrent updates clobber each other.

/tmp/session_bootstrapped

Plain-text sentinel. One line: the value of $CLAUDE_SESSION_ID from the run that completed bootstrap.

needs-bootstrap.py compares this file's contents to the current $CLAUDE_SESSION_ID. Mismatch (or missing file) → bootstrap is needed. register-session.py REFUSES to write an empty sentinel because an empty value would match an empty env var on the next run and permanently suppress bootstrap.

Schema versioning

session-state.json carries schema_version: 1 at the top level. v1 is the current canonical shape: schema_version + sessions.<name> subtree + back-compat top-level session_id. Files written before this field existed are read-tolerated by register-session.py (the owner skill) and silently upgraded to v1 on the next write — owner-skill migration per jbaruch/coding-policy: stateful-artifacts.

Reader skills (jbaruch/nanoclaw-admin: tessl__heartbeat, jbaruch/nanoclaw-admin: tessl__check-email) MUST treat an unknown future version (schema_version > 1) as "no usable prior state" and let the next register-session.py run perform the upgrade — never migrate from a reader.

/tmp/session_bootstrapped is a single-line plain-text sentinel; it has no envelope shape to version. The only behavioral contract is "non-empty content = bootstrap was completed for this $CLAUDE_SESSION_ID", and that contract is stable.

README.md

tile.json