Commit Graph

10 Commits

Author SHA1 Message Date
molecule-ai[bot]
4e289e3004
tests: add GAP-01 tar security + GAP-02 SHA256 verification suites (#8)
* tests: add GAP-01 tar security and GAP-02 SHA256 verification test suites

GAP-01 (test_safe_extract.py):
- CWE-22 traversal via ../ in tar header names (3 cases)
- Absolute path rejection in tar entries (2 cases)
- Symlink hardlink skip (2 cases each)
- Hardlink skip
- Deep traversal rejection
- Deep valid path extraction
- Empty tar noop
- Normal operation smoke test
- zipfile placeholder (documents no zip hardening yet)

GAP-02 (test_sha256_verification.py):
- _is_hex validation (4 cases)
- _sha256_file empty/small/large/binary/not-found (5 cases)
- _walk_files excludes dirs/deterministic/set equality (3 cases)
- verify_plugin_sha256 empty plugin/excludes plugin.yaml/invalid format (3 cases)
- compute_plugin_sha256 stable/deterministic order/content changes exclusion (4 cases)
- CLI verify-sha256 exit zero/nonzero/file-not-dir/error message (4 cases)
- Round-trip compute→verify (1 case)
- Mismatch returns False (1 case)

Total: 37 new test cases, all passing.
180 passed / 1 skipped across full suite (excluding broken conftest import in test_call_peer_errors.py).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add KI-007 (_is_hex TypeError gap) and KI-008 (test_call_peer_errors conftest)

KI-007: _is_hex raises TypeError on non-strings instead of returning False;
guard with isinstance(value, str) check.

KI-008: test_call_peer_errors.py imports tests.conftest which doesn't exist;
fix import or create conftest.py stub.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Molecule AI SDK Lead <sdk-lead@agents.moleculesai.app>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 06:17:42 +00:00
molecule-ai[bot]
e59ed08235
test(gap-03): add test_call_peer_errors.py for A2A error surface (#7)
Co-authored-by: Molecule AI SDK Lead <sdk-lead@agents.moleculesai.app>
2026-04-21 01:02:47 +00:00
molecule-ai[bot]
de2e80ad99
feat(cli): add verify-sha256 command to molecule_agent (#5)
* feat(security): add plugin content integrity verification (SHA256)

SDK-side follow-up to molecule-core PR #1019 (pinned-ref supply-chain fix).

Changes:
- verify_plugin_sha256(plugin_dir, expected_sha) — content-addressed manifest
  hash over sorted (relpath, SHA256(content)) pairs; plugin.yaml excluded
  from its own hash to avoid circular dependency
- _walk_files(root) / _sha256_file(path) — internal helpers
- install_plugin() calls verify_sha256 after atomic rename; on mismatch
  deletes plugin dir and raises ValueError before setup.sh runs
- PLUGIN_YAML_SCHEMA gains optional sha256 field (64-char lowercase hex)
- validate_manifest() validates sha256 format when present

Tests (12 new):
- sha256_file correctness, walk_files ordering, verify_* (match/mismatch/invalid)
- install_plugin sha256 verified: setup.sh runs
- install_plugin sha256 mismatch: raises ValueError, setup.sh NOT run
- install_plugin no sha256: backward-compat, skips verification
- validate_manifest sha256: valid/invalid/non-hex/absent

Pre-existing: 4 async tests in test_sdk.py fail without pytest-asyncio
(not related to this change).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(tests): add pytest-asyncio markers to async adaptor tests

The 4 tests using async def were failing because pytest-asyncio was not
installed and pytest.ini set asyncio_mode=auto (which requires it). Add
@pytest.mark.asyncio to each async test and add pytest-asyncio as a
test optional dependency so CI gets the right extras when installing.

Fixes: 4 FAILED tests in test_sdk.py

* feat(cli): add verify-sha256 command to molecule_agent

Add `python -m molecule_agent verify-sha256 <plugin-dir>` CLI that
computes the content-integrity SHA256 for a plugin directory (the same
manifest hash that verify_plugin_sha256() uses internally). Plugin authors
can run this to generate the hash to put in plugin.yaml's sha256 field.

Also:
- Re-export verify_plugin_sha256 and compute_plugin_sha256 from the
  molecule_agent package root so `from molecule_agent import
  compute_plugin_sha256` works.
- Update CLAUDE.md to document the CLI and content integrity flow.
- Write pr-description-draft.md as a backup for when GH_TOKEN recovers.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Molecule AI SDK-Dev <sdk-dev@agents.moleculesai.app>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 01:00:37 +00:00
molecule-ai[bot]
4467f8ad89
feat(security): add plugin content integrity verification (SHA256) (#3)
* feat(security): add plugin content integrity verification (SHA256)

SDK-side follow-up to molecule-core PR #1019 (pinned-ref supply-chain fix).

Changes:
- verify_plugin_sha256(plugin_dir, expected_sha) — content-addressed manifest
  hash over sorted (relpath, SHA256(content)) pairs; plugin.yaml excluded
  from its own hash to avoid circular dependency
- _walk_files(root) / _sha256_file(path) — internal helpers
- install_plugin() calls verify_sha256 after atomic rename; on mismatch
  deletes plugin dir and raises ValueError before setup.sh runs
- PLUGIN_YAML_SCHEMA gains optional sha256 field (64-char lowercase hex)
- validate_manifest() validates sha256 format when present

Tests (12 new):
- sha256_file correctness, walk_files ordering, verify_* (match/mismatch/invalid)
- install_plugin sha256 verified: setup.sh runs
- install_plugin sha256 mismatch: raises ValueError, setup.sh NOT run
- install_plugin no sha256: backward-compat, skips verification
- validate_manifest sha256: valid/invalid/non-hex/absent

Pre-existing: 4 async tests in test_sdk.py fail without pytest-asyncio
(not related to this change).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(tests): add pytest-asyncio markers to async adaptor tests

The 4 tests using async def were failing because pytest-asyncio was not
installed and pytest.ini set asyncio_mode=auto (which requires it). Add
@pytest.mark.asyncio to each async test and add pytest-asyncio as a
test optional dependency so CI gets the right extras when installing.

Fixes: 4 FAILED tests in test_sdk.py

* feat(cli): add verify-sha256 command to molecule_agent

Add `python -m molecule_agent verify-sha256 <plugin-dir>` CLI that
computes the content-integrity SHA256 for a plugin directory (the same
manifest hash that verify_plugin_sha256() uses internally). Plugin authors
can run this to generate the hash to put in plugin.yaml's sha256 field.

Also:
- Re-export verify_plugin_sha256 and compute_plugin_sha256 from the
  molecule_agent package root so `from molecule_agent import
  compute_plugin_sha256` works.
- Update CLAUDE.md to document the CLI and content integrity flow.
- Write pr-description-draft.md as a backup for when GH_TOKEN recovers.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Molecule AI SDK-Dev <sdk-dev@agents.moleculesai.app>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 01:00:35 +00:00
molecule-ai[bot]
51ad567fd0
fix(tests): add pytest-asyncio markers to async adaptor tests (#4)
* feat(security): add plugin content integrity verification (SHA256)

SDK-side follow-up to molecule-core PR #1019 (pinned-ref supply-chain fix).

Changes:
- verify_plugin_sha256(plugin_dir, expected_sha) — content-addressed manifest
  hash over sorted (relpath, SHA256(content)) pairs; plugin.yaml excluded
  from its own hash to avoid circular dependency
- _walk_files(root) / _sha256_file(path) — internal helpers
- install_plugin() calls verify_sha256 after atomic rename; on mismatch
  deletes plugin dir and raises ValueError before setup.sh runs
- PLUGIN_YAML_SCHEMA gains optional sha256 field (64-char lowercase hex)
- validate_manifest() validates sha256 format when present

Tests (12 new):
- sha256_file correctness, walk_files ordering, verify_* (match/mismatch/invalid)
- install_plugin sha256 verified: setup.sh runs
- install_plugin sha256 mismatch: raises ValueError, setup.sh NOT run
- install_plugin no sha256: backward-compat, skips verification
- validate_manifest sha256: valid/invalid/non-hex/absent

Pre-existing: 4 async tests in test_sdk.py fail without pytest-asyncio
(not related to this change).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(tests): add pytest-asyncio markers to async adaptor tests

The 4 tests using async def were failing because pytest-asyncio was not
installed and pytest.ini set asyncio_mode=auto (which requires it). Add
@pytest.mark.asyncio to each async test and add pytest-asyncio as a
test optional dependency so CI gets the right extras when installing.

Fixes: 4 FAILED tests in test_sdk.py

---------

Co-authored-by: Molecule AI SDK-Dev <sdk-dev@agents.moleculesai.app>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 00:54:07 +00:00
molecule-ai[bot]
1e9809b030
docs: add CLAUDE.md, known-issues.md, and .claude/settings.json (#2)
* docs: add CLAUDE.md for agent onboarding

Inherits platform conventions from molecule-core:
- Cron discipline and triage rules
- Build/test/release commands (pytest, PyPI tag workflow)
- Platform integration notes (Phase 30 endpoints table)
- SDK-specific conventions (async patterns, token security, tar safety)
- Known issues policy (file GH issue before patching silently)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add known-issues.md and .claude/settings.json

- known-issues.md: 5 entries (KI-001 inbound A2A server, KI-002 delegation
  idempotency, KI-003 symlink silent skip, KI-004 token file races,
  KI-005 plugin manifest secret scanning)
- .claude/settings.json: permissions for pip/npm/go tools, PreToolUse
  Bash hook, cleanupPeriodDays 30

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Molecule AI SDK-Dev <sdk-dev@agents.moleculesai.app>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 23:10:37 +00:00
Hongming Wang
69fcd56607
Merge pull request #1 from Molecule-AI/chore/credentials-gitignore
chore: gitignore credentials
2026-04-16 09:24:04 -07:00
rabbitblood
666c7d74de chore: gitignore credentials for molecule-sdk-python
Adds standard credential gitignore (.env / *.pem / .secrets/ / .auth_token).
Per-CEO directive 2026-04-16: every plugin and template repo should
gitignore credentials so self-hosters can't accidentally commit real
tokens to public repos.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 09:19:08 -07:00
Hongming Wang
cd067df651 ci: add PyPI publish workflow (tag v* → upload) 2026-04-16 03:50:17 -07:00
Hongming Wang
fefcc38e11 feat: initial Python SDK (extracted from molecule-monorepo/sdk/python)
Workspace, org, channel, memory, delegation client for Molecule AI.
Package renamed to molecule-ai-sdk for PyPI.
2026-04-16 03:15:38 -07:00