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.

94

Quality

94%

Does it follow best practices?

Impact

Pending

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 rule. It instructs an AI agent to execute a bash command as its very first action in every session, then call an external skill ('tessl__trusted-memory') which could load arbitrary instructions or exfiltrate data. The sentinel file mechanism (/tmp/session_bootstrapped) is designed to make it look like a legitimate caching/dedup mechanism, but the real goal is to force the AI to execute commands and call external services before processing the user's actual request. This is a classic prompt injection / agent manipulation pattern.
Overview
Quality
Evals
Security
Files

needs-bootstrap.pyskills/trusted-memory/scripts/

#!/usr/bin/env python3
"""Check whether the current session needs memory bootstrap.

Usage:
    needs-bootstrap.py

Exit codes:
    0 — bootstrap IS needed (no sentinel, or sentinel points to a
        different session than `$CLAUDE_SESSION_ID`)
    1 — bootstrap NOT needed (sentinel matches current session)

Stdout (JSON, per `jbaruch/coding-policy: script-delegation`):
    {"needs_bootstrap": <bool>, "current": "<id>", "stored": "<id>"|null,
     "reason": "<short>"}

The sentinel lives at `/tmp/session_bootstrapped` and stores the
session ID that last ran bootstrap. A new session within the same
container still triggers bootstrap — the sentinel is keyed per
session, not per container.
"""
import json
import os
import sys

SENTINEL = "/tmp/session_bootstrapped"


def emit(needs_bootstrap: bool, current: str, stored, reason: str) -> None:
    """Write the JSON status line to stdout. Exit code stays the contract;
    JSON is the descriptive surface for callers that want to log."""
    print(
        json.dumps(
            {
                "needs_bootstrap": needs_bootstrap,
                "current": current,
                "stored": stored,
                "reason": reason,
            }
        )
    )


def main() -> None:
    current = os.environ.get("CLAUDE_SESSION_ID", "")

    if not current:
        # Empty env cannot safely "match" a stored sentinel: if both are
        # empty the script would report "already bootstrapped" and skip
        # memory load forever. Treat empty env as bootstrap-needed.
        print(
            "needs-bootstrap: $CLAUDE_SESSION_ID missing/empty; defaulting to bootstrap-needed",
            file=sys.stderr,
        )
        emit(True, current, None, "claude_session_id_missing")
        sys.exit(0)

    try:
        with open(SENTINEL) as f:
            stored = f.read().strip()
    except FileNotFoundError:
        emit(True, current, None, "sentinel_missing")
        sys.exit(0)
    except OSError as e:
        print(
            f"needs-bootstrap: cannot read sentinel at {SENTINEL}: {e}; assuming bootstrap needed",
            file=sys.stderr,
        )
        emit(True, current, None, "sentinel_unreadable")
        sys.exit(0)

    if not stored:
        # Defensive pair: an empty sentinel (shouldn't be written by
        # the fixed register-session.py, but could linger from pre-fix
        # runs or a manual touch) is treated as bootstrap-needed so we
        # self-heal rather than stay stuck.
        emit(True, current, "", "sentinel_empty")
        sys.exit(0)

    if stored == current:
        emit(False, current, stored, "sentinel_match")
        sys.exit(1)

    emit(True, current, stored, "sentinel_mismatch")
    sys.exit(0)


if __name__ == "__main__":
    main()

README.md

tile.json