Skip to content

Add new skill: RAPP Agent Converter - #279

Open
Kody Wildfeuer (kody-w) wants to merge 9 commits into
microsoft:mainfrom
kody-w:skill/rapp-agent-converter
Open

Add new skill: RAPP Agent Converter#279
Kody Wildfeuer (kody-w) wants to merge 9 commits into
microsoft:mainfrom
kody-w:skill/rapp-agent-converter

Conversation

@kody-w

Copy link
Copy Markdown

What this adds

submissions/rapp-agent-converter/ — a skill that converts RAPP single-file
agents (agent.py) into Agent Skills and back
, with byte-identical round
trips in both directions.

The emitted projection is a pair: a SKILL.md carrying the complete Python
inline plus an rci-capsule:v1: comment vaulting the byte-exact original
(sha256-verified restore, never a re-render), and a linked .py beside it that
literally is the agent.py — so execution hosts run the real implementation
first-party.

Targets Cowork, Copilot Studio, and Scout. The converter is stdlib-only
Python 3.9+, fully offline: no pip install, no network, no credentials.

Verification

  • selftest proves every verdict fires: match, checksum refusal, inline-tamper
    drift, raw-bread refusal, edit-honored
  • 16 real RAPP agents round-trip byte-identical (12 from a live brainstem,
    plus the bundled sample). A base-class file is correctly refused with a
    reason rather than silently converted
  • 3 existing gallery skills complete the full
    SKILL.md -> agent.py -> SKILL.md + linked agent -> agent.py chain with the
    Python preserved byte-exact
  • Copilot Studio sandbox contract exercised end to end: --tool exits 0,
    invocation with one JSON object returns success, and with the linked file
    deleted the agent is materialized from the fence byte-identical
    (sha256 4a42921a9bffbbe3) and still executes
  • Live hot-load: the restored agent dropped into a running RAPP brainstem's
    agents/ directory loaded with no restart and executed first-party
  • Capsule integrity survives this gallery's own pipeline — a bundled SKILL.md
    is byte-identical to the authored one, and still restores the original
    agent.py byte-exact

npm run check:submissions passes (all submissions), npm test passes, and
npm run build completes.

Notes for reviewers

  • Only submissions/rapp-agent-converter/** is touched — no site or
    infrastructure changes, and no generated artifacts committed by hand
  • The second commit renames the skill from the original RAPPtoMCS: the old
    name was one-directional and Copilot Studio specific, while the skill is
    bidirectional and host-agnostic. MCS also appears nowhere else in the
    gallery, where the convention is copilot-studio-*

Kody Wildfeuer (kody-w) and others added 2 commits August 9, 2026 19:53
Bring RAPP single-file agents (agent.py, the Rapid Agent Prototype Pattern)
into Microsoft Copilot Studio and back with zero fidelity loss. The emitted
projection is a pair: a SKILL.md carrying the complete Python inline plus an
rci-capsule comment vaulting the byte-exact original (sha256-verified restore,
never a re-render), and a linked python file beside it that literally is the
agent.py -- so execution hosts run the real implementation first-party.
Implements rapp-capability-interchange/1.0 for the agent<->skill pair,
interoperable with the reference toaster, with a rapp/1 /chat wire reference
for talking to live RAPP entities.

Verified: selftest proves every verdict fires (match, checksum refusal,
inline-tamper drift, raw-bread refusal, edit-honored); 29 real agents
round-trip byte-identical; three existing gallery skills complete the
raw SKILL.md -> agent.py -> SKILL.md+linked-agent -> agent.py chain with
the Python preserved byte-exact; cross-tool restore against the upstream
toaster is byte-identical in both directions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The old name was one-directional and Copilot Studio specific, but the
skill is bidirectional and host-agnostic: its own metadata targets
Cowork, Copilot Studio and Scout, and the SKILL.md states it works with
any host that consumes SKILL.md. "MCS" also appears nowhere else in the
gallery, where the convention is copilot-studio-*, and 80 of 82
submissions use lowercase-hyphenated slugs.

Keeps "rapp" because that is the activation trigger for the audience
that has agent.py cartridges, and matches the existing
doc-format-converter naming precedent.

Updates the folder, SKILL.md frontmatter name, metadata display name and
description, and the README heading and cd line. No payload changes:
selftest still passes and the bundled sample still round-trips
byte-identical.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings August 10, 2026 14:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new submission skill, RAPP Agent Converter, to the gallery under submissions/rapp-agent-converter/. The skill provides an offline, stdlib-only Python tool and accompanying documentation to convert between RAPP single-file agents (*_agent.py) and gallery Agent Skills (SKILL.md), including capsule-based byte-exact restoration.

Changes:

  • Introduces a new skill (SKILL.md) plus human-facing overview (README.md) and submission metadata (metadata.json).
  • Adds the deterministic converter implementation (scripts/toast.py) and reference docs for the RAPP contract/protocol.
  • Adds a sample RAPP agent cartridge (assets/hello_rapp_agent.py) for round-trip verification and demos.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
submissions/rapp-agent-converter/SKILL.md Agent-facing operational instructions for running conversions/verification and interacting with a live RAPP brainstem.
submissions/rapp-agent-converter/scripts/toast.py Stdlib-only converter implementation handling capsule pack/unpack, agent/skill parsing, projection, and selftests.
submissions/rapp-agent-converter/references/rapp1-protocol.md Reference for the /chat wire protocol and interop rules when talking to a live RAPP entity.
submissions/rapp-agent-converter/references/rapp-agent-contract.md Reference contract for RAPP single-file agents (structure, loader gates, portability shim).
submissions/rapp-agent-converter/README.md Human-facing skill overview, rationale, and quick-start instructions for gallery viewers.
submissions/rapp-agent-converter/metadata.json Submission metadata (name/description/platforms/tags/author/version/dates).
submissions/rapp-agent-converter/assets/hello_rapp_agent.py Sample minimal RAPP agent cartridge used for demos and conversion round-trip checks.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +308 to +310
rci["name"] = name if isinstance(name, str) else cls.name
rci["slug"] = _kebab(manifest.get("display_name") or "") or rci.get("slug") \
or _kebab(rci["name"])
perform = (" def perform(self, **kwargs):\n"
+ textwrap.indent(impl["perform_body"], " "))
else:
perform = DEFAULT_PERFORM
Comment on lines +42 to +46
python3 scripts/toast.py convert <path> --to skill -o out/SKILL.md # agent.py -> SKILL.md + linked agent
python3 scripts/toast.py convert <path> --to agent # SKILL.md -> agent.py
python3 scripts/toast.py roundtrip <path> # prove fidelity, exit 1 on drift
python3 scripts/toast.py inspect <path> # capsule status, identity, provenance
python3 scripts/toast.py selftest # prove every verdict can fire
Agents without __manifest__.display_name were projected with the literal slug
"capability" because _kebab("") returns that fallback before the converter
could use the capsule slug or agent name. Only call _kebab when display_name
is present, then fall through to the carried slug and tool name.

Add the no-display-name case to selftest so the gallery submission itself
owns the regression. Also remove the remaining Copilot-Studio-first opening
from the human and agent instructions; the pair targets every Agent Skill
host and Copilot Studio is one execution surface, not the format boundary.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 10, 2026 15:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (5)

submissions/rapp-agent-converter/SKILL.md:45

  • The skill targets Scout (cross-OS), but the command examples assume a Unix-like environment (bash) and a python3 launcher, which won’t work on many Windows machines. Please either add a Windows launcher note (e.g., py -3 / python) or make the command block OS-agnostic so the documented workflow matches the supported platforms.
```bash
python3 scripts/toast.py convert <path> --to skill -o out/SKILL.md   # agent.py -> SKILL.md + linked agent
python3 scripts/toast.py convert <path> --to agent                   # SKILL.md -> agent.py
python3 scripts/toast.py roundtrip <path>                            # prove fidelity, exit 1 on drift
python3 scripts/toast.py inspect <path>                              # capsule status, identity, provenance

submissions/rapp-agent-converter/scripts/toast.py:390

  • read_skill() decodes markdown with errors='replace', which can mask invalid UTF‑8 and make capsule detection / content parsing behave unpredictably. Since SKILL.md content must be UTF‑8 in practice, failing fast on decode errors avoids producing “successful” conversions from corrupted input.
def read_skill(raw: bytes, filename: str) -> dict:
    text = raw.decode("utf-8", "replace")
    got = _capsule_or_reparse(raw, filename, "skill")
    cap = got[1] if got and got[0] == "ok" else None
    rci = cap if cap else (got[1] if got else blank_rci())

submissions/rapp-agent-converter/scripts/toast.py:505

  • The generated “Run this” section hardcodes python3, but the submission claims Scout support (cross-OS) and Windows often won’t have a python3 launcher. Consider making the generated snippet OS-agnostic or adding a short Windows launcher note so the emitted skill text doesn’t instruct users to run a command that may not exist.
                "```bash\n"
                f"python3 {fn} '{{\"key\": \"value\"}}'      # arguments as one JSON object\n"
                f"echo '{{\"key\": \"value\"}}' | python3 {fn}   # or on stdin\n"
                f"python3 {fn} --tool                      # emit the JSON tool contract\n"
                "```\n\n"

submissions/rapp-agent-converter/scripts/toast.py:241

  • read_agent() decodes source with errors='replace', which can silently corrupt non‑UTF‑8 Python files (or files using a PEP 263 encoding) and undermine the “byte-identical” guarantees (e.g., a corrupted projection could still round-trip via the capsule while the visible embedded code differs). It’s safer to require UTF‑8 input (fail fast) or implement proper PEP 263 decoding and refuse encodings that cannot be represented losslessly in UTF‑8 markdown.

This issue also appears on line 386 of the same file.

def read_agent(raw: bytes, filename: str) -> dict:
    text = raw.decode("utf-8", "replace").lstrip("\ufeff")
    got = _capsule_or_reparse(raw, filename, "agent")
    cap = got[1] if got and got[0] == "ok" else None
    rci = cap if cap else (got[1] if got else blank_rci())

submissions/rapp-agent-converter/README.md:64

  • The quickstart example uses /tmp and assumes a python3 launcher. Since this submission claims Scout support (cross-OS), adding a brief Windows launcher note and using a relative output path would prevent the README quickstart from failing on Windows.
cd rapp-agent-converter
python3 scripts/toast.py selftest                                # every verdict fires
python3 scripts/toast.py convert assets/hello_rapp_agent.py --to skill -o /tmp/SKILL.md
python3 scripts/toast.py roundtrip assets/hello_rapp_agent.py    # IDENTICAL, or exit 1
python3 assets/hello_rapp_agent.py '{"person": "Ada"}'           # the cartridge itself runs anywhere

Make generated skills fail closed: malformed capsules, missing generated
regions, multiple deterministic fences, and inline Python edits now refuse on
all reads, including convert and inspect. The inline check is structural and
cannot be disabled by rewording prose or confused by an authored example
fence.

Make the oracle real in every mode. Agent fixed-point cycles now cross both
formats instead of restoring the same skill bytes, and --allow-raw performs a
skill->agent->skill->agent stability proof before returning success.

Restore the vaulted filename by default, accept byte-identical existing targets
idempotently, generate valid classes for numeric-leading skill names, preserve
standard Agent Skill permission frontmatter, and keep author/version/tags under
metadata instead of unsupported top-level fields.

Clarify raw-skill synthesis: instructions and explicit contracts travel, but
the converter never invents ordered commands from prose. Generated host
instructions now treat planner output as a tool result and execute returned
steps rather than presenting a plan as completed work.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 10, 2026 15:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Suppressed comments (3)

submissions/rapp-agent-converter/SKILL.md:46

  • The skill targets Scout (cross-OS), but the command examples hardcode python3, which commonly fails on Windows (python / py -3 are typical). This makes the documented execution steps non-portable for one of the declared platforms; adjust the examples to be cross-platform (or explicitly branch by OS).
python3 scripts/toast.py convert <path> --to skill -o out/SKILL.md   # agent.py -> SKILL.md + linked agent
python3 scripts/toast.py convert <path> --to agent                   # SKILL.md -> agent.py
python3 scripts/toast.py roundtrip <path>                            # prove fidelity, exit 1 on drift
python3 scripts/toast.py inspect <path>                              # capsule status, identity, provenance
python3 scripts/toast.py selftest                                    # prove every verdict can fire

submissions/rapp-agent-converter/scripts/toast.py:110

  • restore() assumes the capsule’s preserved entry is well-formed; malformed/malicious capsules can currently raise KeyError/binascii.Error/OSError and bubble up as an uncaught exception (traceback) instead of a clean [FAIL] ... message. Treat decode/decompress/key errors as a ValueError so callers reliably get a controlled failure mode.
def restore(rci: dict, fmt: str):
    p = rci.get("preserved", {}).get(fmt)
    if not p:
        return None
    raw = gzip.decompress(base64.b64decode(p["b64"]))

submissions/rapp-agent-converter/README.md:66

  • README command examples also hardcode python3, which is not reliably available on Windows (a supported Scout host). Updating these examples (or branching by OS) will make the quickstart runnable on all declared platforms.
cd rapp-agent-converter
python3 scripts/toast.py selftest                                # every verdict fires
python3 scripts/toast.py convert assets/hello_rapp_agent.py --to skill -o /tmp/SKILL.md
python3 scripts/toast.py roundtrip assets/hello_rapp_agent.py    # IDENTICAL, or exit 1
python3 assets/hello_rapp_agent.py '{"person": "Ada"}'           # the cartridge itself runs anywhere

Comment on lines +778 to +782
def linked_agent_name(rci: dict) -> str:
"""The sidecar name the projection links to — the vaulted original's own
filename when known, so the link and the restore always agree."""
return ((rci.get("preserved", {}).get("agent") or {}).get("filename")
or agent_filename(rci))
Fail closed on the complete generated projection, not only the Python fence:
read_skill now regenerates and byte-compares commands, parameters, prose, and
code against the checksum-verified agent. Capsule comments are parsed only in
their defined HTML/Python forms and decoded values must be valid RCI objects.

Reject capsule-controlled path traversal, non-UTF-8 source that cannot be
embedded byte-exact, ordinary example fences masquerading as implementation,
and malformed generated artifacts. Parse and preserve standard block-form YAML
metadata and permissions.

Preflight both files in the Agent Skill pair before writing, so a conflicting
linked agent cannot leave a broken SKILL.md behind. Normalize the gzip OS header
and pin a known compressed-byte fixture; projections are now byte-identical on
Python 3.11, 3.13, and 3.14.

Expand selftest to cover all regressions, including generated command tampering,
capsule shape, path traversal, metadata, raw prose examples, numeric slugs, and
non-UTF-8 refusal.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 10, 2026 16:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (3)

submissions/rapp-agent-converter/SKILL.md:122

  • These verification examples also hard-code python3, which isn’t consistently available on Windows (Scout can run on any OS). Consider using python in the documented invocation (and optionally mention python3/py -3 depending on OS) so the guidance matches the stated cross-OS target.
  file — only claim after `python3 <file> --tool` actually exits 0), **CODE**
  (the code travels in the fence), **SPEC** (typed contract only). Never report
  EXEC without having executed.
- Try it end to end on the bundled sample:
  `python3 scripts/toast.py roundtrip assets/hello_rapp_agent.py`

submissions/rapp-agent-converter/SKILL.md:47

  • The command examples assume a Bash-like shell and the python3 launcher. Since this skill targets Scout (cross-OS) too, these commands are not reliably runnable on Windows (where python3 is often absent and shell quoting differs). Prefer OS-agnostic examples (e.g., python with a note about py -3 on Windows) and avoid implying Bash by using a non-shell-specific fence.

This issue also appears on line 118 of the same file.

```bash
python3 scripts/toast.py convert <path> --to skill -o out/SKILL.md   # agent.py -> SKILL.md + linked agent
python3 scripts/toast.py convert <path> --to agent                   # SKILL.md -> agent.py
python3 scripts/toast.py roundtrip <path>                            # prove fidelity, exit 1 on drift
python3 scripts/toast.py inspect <path>                              # capsule status, identity, provenance

submissions/rapp-agent-converter/scripts/toast.py:716

  • The generated “Run this” section emits a bash fence, uses python3, and includes an echo ... | ... pipeline. For Scout’s cross-OS environment you can’t assume Bash, python3, or POSIX quoting/pipes. Consider emitting a non-shell-specific fence (e.g., text), using python, and showing stdin redirection from a file instead of a pipe.
                "```bash\n"
                f"python3 {fn} '{{\"key\": \"value\"}}'      # arguments as one JSON object\n"
                f"echo '{{\"key\": \"value\"}}' | python3 {fn}   # or on stdin\n"
                f"python3 {fn} --tool                      # emit the JSON tool contract\n"
                "```\n\n"

Reject generated regions hidden inside Markdown fences or comments, conflicting
or invalid parameter schemas, aliased pair destinations, and malformed RCI
field types before rendering. The capsule validator now covers every consumed
field and the tool contract must be a JSON-Schema object.

Parse nested YAML block scalars as well as maps and lists, while treating only
explicit `python # rapp:deterministic` fences as implementation. Capsule syntax
is recognized only in defined HTML/Python comment forms, so prose can document
it safely.

The regression suite now covers hidden generated content, block metadata and
scalars, conflicting schemas, invalid RCI shapes, pair path collisions,
path traversal, non-UTF-8 source, cross-version gzip bytes, and ordinary Python
examples. The real CAT block-scalar fixture and Python 3.11/3.13/3.14 all pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 10, 2026 16:29
Require platform.metadata and platform.claude to be objects and validate the
rendered permission fields before write_skill consumes them. This closes the
last type-confusion path in the RCI record and adds it to selftest.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (2)

submissions/rapp-agent-converter/SKILL.md:46

  • These command examples assume a POSIX shell and python3, but the skill targets Scout as well (cross-OS). On Windows/Scout, python3 and the surrounding quoting/piping aren’t reliable; prefer a python-based invocation (or provide OS-specific alternatives) so the documented commands work on all advertised platforms.
python3 scripts/toast.py convert <path> --to skill -o out/SKILL.md   # agent.py -> SKILL.md + linked agent
python3 scripts/toast.py convert <path> --to agent                   # SKILL.md -> agent.py
python3 scripts/toast.py roundtrip <path>                            # prove fidelity, exit 1 on drift
python3 scripts/toast.py inspect <path>                              # capsule status, identity, provenance
python3 scripts/toast.py selftest                                    # prove every verdict can fire

submissions/rapp-agent-converter/scripts/toast.py:825

  • The generated “Run this” section hardcodes python3 and uses shell-specific JSON quoting/piping. Since this skill claims Scout support (cross-OS, unknown shell), the generated instructions should avoid assuming python3 or any particular quoting rules; otherwise the emitted SKILL.md guidance will fail on common Windows shells.
        try:
            code = source.decode("utf-8")
        except UnicodeDecodeError as exc:
            raise ValueError(
                "vaulted agent must be UTF-8 for an Agent Skill projection"

Copilot AI review requested due to automatic review settings August 10, 2026 16:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (2)

submissions/rapp-agent-converter/scripts/toast.py:629

  • split_frontmatter() only matches YAML frontmatter when it uses LF (\n). A SKILL.md checked out or authored with CRLF line endings will be treated as having no frontmatter, which can change the derived slug/metadata and break round-trips on Windows.
def split_frontmatter(text: str):
    m = re.match(r"---\s*\n(.*?)\n---\s*\n?(.*)$", text, re.S)
    if not m:
        return {}, text
    fm, body = {}, m.group(2)

submissions/rapp-agent-converter/scripts/toast.py:64

  • Several core regexes assume LF-only newlines (e.g., \n literals and EOL anchors without allowing a preceding \r). On Windows/CRLF files this can prevent capsule detection and generated-block matching, causing false drift/refusals or missed capsules despite byte-identical content.

This issue also appears on line 625 of the same file.

)
GENERATED_BEGIN = "<!-- toaster:generated:begin -->"
GENERATED_END = "<!-- toaster:generated:end -->"
GENERATED_BLOCK_RE = re.compile(
    r"^<!-- toaster:generated:begin -->[ \t]*\n"

Recognize generated markers only when they occupy their reserved top-level
comment lines. This lets the converter skill document its own marker syntax
without being mistaken for a damaged generated projection, while preserving
the fail-closed behavior for real marker blocks.

Add the self-hosting case to selftest and prove the converter SKILL.md can be
synthesized into its own RAPP launchpad agent.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 10, 2026 17:32
Some valid gallery skills end with an unclosed authored code fence. Appending
the generated pair contract would hide it inside that fence and correctly fail
verification. When authored Markdown leaves a fence or HTML comment open, emit
the generated contract before the authored body instead, preserving the source
instructions while keeping the linked-agent contract top-level and active.

Add an open-fence self-hosting regression to the cross-version selftest.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (4)

submissions/rapp-agent-converter/SKILL.md:39

  • The command examples assume the python3 launcher exists, but this skill targets Scout where users may run on Windows (often python/py -3 instead). Adding a short Windows note here would prevent the “Commands” section from being misleading on that platform.
Run from this skill's directory. Stdlib-only Python 3.9+, fully offline — no
pip install, no network, no credentials.

submissions/rapp-agent-converter/SKILL.md:58

  • The exit-code documentation says code 2 only means RAW BREAD, but toast.py roundtrip also returns 2 when a skill has a capsule but no vaulted agent (byte-level roundtrip still unavailable). Please document that exit 2 covers both cases to avoid consumers misclassifying failures.
Exit codes: 0 = verified, 1 = drift or refusal (message says which), 2 =
`RAW BREAD` — a capsule-less SKILL.md has no byte-exact return trip yet;
convert it to an agent first, or pass `--allow-raw` to measure
capability-level fidelity only. Treat only exit 1 as drift.

submissions/rapp-agent-converter/scripts/toast.py:849

  • The generated “Run this” snippet is labeled as bash and relies on POSIX-style quoting/pipes (single quotes, echo |). Since the skill claims to target Scout (cross-OS), it would be safer to emit a shell-neutral snippet and demonstrate stdin redirection (works in more shells) plus a Windows python fallback.
            )
    if params.get("properties") and not authored_params:
        generated += [f"\n{GENERATED_BEGIN}\n"
                      "\n## Parameters\n\nThe typed contract this capability "
                      "answers to (JSON Schema — the deterministic layer):\n\n"

submissions/rapp-agent-converter/README.md:67

  • The “Try it” commands use POSIX single-quote JSON ('{'...'}'), which won’t work in common Windows shells. Since this submission targets Scout, consider switching the example to stdin redirection (shell-agnostic) and noting the Windows python launcher as needed.
cd rapp-agent-converter
python3 scripts/toast.py selftest                                # every verdict fires
python3 scripts/toast.py convert assets/hello_rapp_agent.py --to skill -o /tmp/SKILL.md
python3 scripts/toast.py roundtrip assets/hello_rapp_agent.py    # IDENTICAL, or exit 1
python3 assets/hello_rapp_agent.py '{"person": "Ada"}'           # the cartridge itself runs anywhere

Copilot AI review requested due to automatic review settings August 10, 2026 17:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (5)

submissions/rapp-agent-converter/scripts/toast.py:250

  • unpack_capsule() gzip-decompresses the capsule JSON with no size limit. Because the capsule may come from user-provided SKILL.md/agent.py files, this allows decompression bombs that can exhaust memory/CPU during inspection, conversion, or roundtrip checks. Add a maximum decompressed size (and ideally a cap on the base64 payload length) before parsing JSON.
    if not re.fullmatch(r"[A-Za-z0-9+/=]+", payload):
        raise ValueError("malformed rci-capsule:v1 payload")
    try:
        decoded = json.loads(gzip.decompress(base64.b64decode(payload)))
    except Exception as exc:

submissions/rapp-agent-converter/SKILL.md:42

  • The command examples assume a POSIX shell (bash) and a python3 launcher. Since this submission targets Scout (cross-OS), these defaults will fail on common Windows setups (no python3, different shell semantics). Use a shell-agnostic fence and a launcher placeholder (or python/py -3 guidance) so the steps remain runnable across supported platforms.
Run from this skill's directory. Stdlib-only Python 3.9+, fully offline — no
pip install, no network, no credentials.

```bash
python3 scripts/toast.py convert <path> --to skill -o out/SKILL.md   # agent.py -> SKILL.md + linked agent

submissions/rapp-agent-converter/scripts/toast.py:125

  • restore() base64-decodes and gzip-decompresses untrusted capsule content with no size limit. A crafted capsule can cause memory/CPU exhaustion (decompression bomb) when converting or round-tripping, which is a realistic risk in sandboxed hosts. Add a maximum decompressed size and fail fast if exceeded.

This issue also appears on line 246 of the same file.

def restore(rci: dict, fmt: str):
    p = rci.get("preserved", {}).get(fmt)
    if not p:
        return None
    raw = gzip.decompress(base64.b64decode(p["b64"]))
    if _sha(raw) != p["sha256"]:
        raise ValueError(f"preserved {fmt} payload failed its checksum")
    return raw

submissions/rapp-agent-converter/scripts/toast.py:880

  • The generated "Run this" section bakes in a POSIX shell pipeline (echo ... |) and a python3 launcher. Since the emitted projection is described as working for Scout (cross-OS), the generated instructions should avoid assuming a particular shell/launcher. Using a neutral fence and a <python> placeholder keeps the emitted SKILL.md portable.
                "```bash\n"
                f"python3 {fn} '{{\"key\": \"value\"}}'      # arguments as one JSON object\n"
                f"echo '{{\"key\": \"value\"}}' | python3 {fn}   # or on stdin\n"
                f"python3 {fn} --tool                      # emit the JSON tool contract\n"
                "```\n\n"

submissions/rapp-agent-converter/README.md:68

  • The quickstart snippet is POSIX-specific (cd ... and /tmp/...) and uses python3, which makes it misleading for Windows users even though the submission targets Scout (cross-OS). Consider using a relative output path and a launcher placeholder so the quickstart works across supported platforms.
```bash
cd rapp-agent-converter
python3 scripts/toast.py selftest                                # every verdict fires
python3 scripts/toast.py convert assets/hello_rapp_agent.py --to skill -o /tmp/SKILL.md
python3 scripts/toast.py roundtrip assets/hello_rapp_agent.py    # IDENTICAL, or exit 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants