Skip to content

V0.6.2#39

Merged
Hendler merged 34 commits intomainfrom
v0.6.2
Feb 11, 2026
Merged

V0.6.2#39
Hendler merged 34 commits intomainfrom
v0.6.2

Conversation

@Hendler
Copy link
Contributor

@Hendler Hendler commented Feb 10, 2026

No description provided.

  - Added strict: bool field to SimpleAgent struct
  - Added resolve_strict(explicit: Option<bool>) -> bool helper (explicit > env var > false)
  - Added is_strict() accessor
  - Updated load() signature: now load(config_path, strict)
  - Updated all 3 construction sites (create, create_with_params, load)
  - Added strict enforcement in verify(), verify_self() — returns Err(SignatureVerificationFailed) instead of Ok(valid=false)
  - verify_by_id() delegates to verify() so inherits strict behavior
  - Fixed all callers: audit/mod.rs, bin/cli.rs, deprecated module-level load()
  - Added 5 new tests (resolve_strict defaults, explicit overrides, env var, is_strict accessor, strict+malformed input)

  Python (jacspy):
  - PyO3: load(config_path, strict) with #[pyo3(signature)], added is_strict()
  - simple.py: _strict module state, _resolve_strict(), is_strict(). load(strict=), create(strict=). verify(), verify_self(), verify_by_id() raise VerificationError in
   strict mode
  - async_simple.py: load(strict=), create(strict=) pass through
  - mcp.py: Already had strict support; fixed _resolve_strict to handle Optional[bool]

  Node.js (jacsnpm):
  - simple.ts: strictMode state, resolveStrict(), isStrict(), LoadOptions interface. load(configPath, options). verifySelf(), verify(), verifyById() throw in strict
  mode
  - simple.d.ts: Added LoadOptions interface, isStrict(), updated load() signature

  Versions: All 8 manifests bumped to 0.6.2

  Tests: 391 passing (359 lib + 32 binding-core/MCP)

✻ Cogitated for 25m 39s

⏺ Background command "Run jacs core tests" completed (exit code 0)

⏺ That's the background task that already completed earlier — the jacs core tests passed (359 tests, 0 failures). All Phase 2 strict mode work is done and verified.
  Waiting for your next instructions.

⏺ Background command "Run full test suite (jacs lib, binding-core, mcp)" completed (exit code 0)

⏺ That's also the background task that already completed — 32 binding-core/MCP tests passed. Combined with the 359 lib tests, all 391 tests pass at v0.6.2. Phase 2
  strict mode is fully implemented and verified across all layers.
  agent/mod.rs:
  - Added key_store: Option<Box<dyn KeyStore>> and ephemeral: bool fields to Agent struct
  - Added Agent::ephemeral(algorithm) — creates agent with InMemoryKeyStore + memory storage + ConfigBuilder defaults
  - Added set_keys_raw() — stores raw private key in SecretBox without AES encryption
  - Added is_ephemeral() and get_key_store() accessors
  - Guarded create_agent_and_load() — ephemeral uses key_store directly, skips fs_load_keys and fs_save_remote_public_key
  - Guarded load() — skips fs_load_keys for ephemeral agents
  - Updated all Agent struct construction sites (new, builder.build)
  - 7 new tests: create without config/env vars, create_agent_and_load, sign+verify round-trip, ready check, no files on disk, pq2025

  crypt/mod.rs:
  - Added generate_keys_with_store(&dyn KeyStore) — ephemeral uses set_keys_raw, persistent uses set_keys
  - Refactored generate_keys() to delegate to generate_keys_with_store(&FsEncryptedStore)
  - Added ephemeral branches in sign_string() and sign_batch() — skips AES decryption for ephemeral agents

  Test results: 376 lib tests pass, 32 binding-core/MCP pass, all crates compile.
  ┌───────────────────────────────┬────────────────────────────────────────────────────┐
  │             Layer             │                       Status                       │
  ├───────────────────────────────┼────────────────────────────────────────────────────┤
  │ 3.1 InMemoryKeyStore          │ Done (10 tests)                                    │
  ├───────────────────────────────┼────────────────────────────────────────────────────┤
  │ 3.2 Agent::ephemeral()        │ Done (7 tests)                                     │
  ├───────────────────────────────┼────────────────────────────────────────────────────┤
  │ 3.3 SimpleAgent::ephemeral()  │ Done (4 tests)                                     │
  ├───────────────────────────────┼────────────────────────────────────────────────────┤
  │ 3.4 Python quickstart()       │ Done                                               │
  ├───────────────────────────────┼────────────────────────────────────────────────────┤
  │ 3.5 Node.js quickstart()      │ Done                                               │
  ├───────────────────────────────┼────────────────────────────────────────────────────┤
  │ 3.4a Error messages           │ Partial (Python/Node done, Rust JacsError pending) │
  ├───────────────────────────────┼────────────────────────────────────────────────────┤
  │ 3.6 CLI quickstart            │ Not started                                        │
  ├───────────────────────────────┼────────────────────────────────────────────────────┤
  │ 3.7 Config friction reduction │ Not started                                        │
  ├───────────────────────────────┼────────────────────────────────────────────────────┤
  │ 3.8 DX validation             │ Not started                                        │
  ├───────────────────────────────┼────────────────────────────────────────────────────┤
  │ U1 find_config migration      │ Not started                                        │
  └───────────────────────────────┴────────────────────────────────────────────────────┘
  3.4a: Error Messages

  - Updated JacsError::AgentNotLoaded in error.rs to mention quickstart()
  - Updated test to verify new message

  U1: find_config Migration

  - Replaced deprecated find_config("./") with load_config_12factor_optional(None) in Agent::new() and Agent::load_by_id()
  - Replaced load_config(&path) with load_config_12factor(Some(&path)) in Agent::load_by_config()
  - Updated CLI config read to use load_config_12factor_optional

  Layer 6: CLI Quickstart

  - Added jacs quickstart command with --algorithm, --sign, --file, --persist flags
  - Info mode prints agent details and usage hints
  - Sign mode reads JSON from stdin or file, signs it, prints signed document

  Layer 7: Config Friction Reduction

  - SimpleAgent::create() now writes minimal 2-field config (jacs_agent_id_and_version + jacs_agent_key_algorithm)
  - create_with_params() only includes non-default paths
  - jacs.config.example.json simplified from 11 fields to 3 (including $schema)

  Layer 8: DX Validation (via subagent)

  - All 3 READMEs (root, jacspy, jacsnpm) now lead with quickstart() in Quick Start
  - load() path moved to "Advanced: Loading a persistent agent"
  - API tables include quickstart() as first entry
  - jacspy/examples/quickstart.py rewritten to lead with quickstart()
  - jacsnpm/examples/quickstart.js updated with quickstart() primary path

  Bug Fix

  - Fixed binding-core temp file race condition by using thread-unique filenames

  Test Results

  - 380 lib tests pass (all existing + 21 new from Layers 1-3)
  - 32 binding-core tests pass (race condition fixed)
  - 11 files changed, +300/-127 lines
  Tasks completed:
  1. Rust NAPI - Arc<AgentWrapper> + generic AsyncTask structs (AgentStringTask, AgentBoolTask, AgentVoidTask)
  2. TypeScript - simple.ts, client.ts, testing.ts all updated with async default + Sync suffix variants
  3. Tests - 119 passing, 0 failing (both async and sync coverage)
  4. Docs - Updated 6 jacsbook pages + jacsnpm README for v0.7.0 async-first API
  5. Version bump - package.json and Cargo.toml both at v0.7.0

  Key docs updated:
  - jacsnpm/README.md - Full async-first API docs
  - jacsbook/src/nodejs/simple-api.md - Async/sync API tables + all examples
  - jacsbook/src/nodejs/basic-usage.md - All code examples with await
  - jacsbook/src/nodejs/api.md - Full JacsAgent API with async/sync variants
  - jacsbook/src/getting-started/quick-start.md - Node.js tabs updated
  - jacsbook/src/reference/migration.md - v0.6.x → v0.7.0 migration guide
  - jacsbook/src/examples/nodejs.md - Setup section updated
  - examples/langchain/basic-agent.ts: Made initializeJACSTools() async, added await to load(), verifySelf(), signMessage(), verify(), createAgreement(),
  checkAgreement()
  - examples/langchain/signing-callback.ts: Constructor simplified to just check isLoaded() (can't be async), signOutput() and verifyAll() made async with await on
   signMessage() and verify(), await jacs.load() in main()

  Task 9 — multi_agent_agreement.ts (completed):
  - examples/multi_agent_agreement.ts: main() → async main(), await on all 3 ephemeral() calls, createAgreement(), 3x signAgreement(), verifySelf(), error handler
  added to main().catch()
  - Python version (multi_agent_agreement.py) — no changes needed (Python API is synchronous)

  Test results: 119 jacsnpm tests passing, 101 moltyjacs tests passing.
  ┌──────────────────────┬────────────────────────────────────────────┬───────────────────────────────┐
  │      Component       │                   Files                    │             Tests             │
  ├──────────────────────┼────────────────────────────────────────────┼───────────────────────────────┤
  │ Rust sign_batch      │ binding-core/src/lib.rs, jacspy/src/lib.rs │ 4 Rust + 2 Python             │
  ├──────────────────────┼────────────────────────────────────────────┼───────────────────────────────┤
  │ Base adapter         │ jacs/adapters/base.py                      │ 21                            │
  ├──────────────────────┼────────────────────────────────────────────┼───────────────────────────────┤
  │ LangChain/LangGraph  │ jacs/adapters/langchain.py                 │ 23 (19 pass, 4 skip w/o deps) │
  ├──────────────────────┼────────────────────────────────────────────┼───────────────────────────────┤
  │ FastAPI              │ jacs/adapters/fastapi.py                   │ 11                            │
  ├──────────────────────┼────────────────────────────────────────────┼───────────────────────────────┤
  │ CrewAI               │ jacs/adapters/crewai.py                    │ 19                            │
  ├──────────────────────┼────────────────────────────────────────────┼───────────────────────────────┤
  │ Anthropic/Claude SDK │ jacs/adapters/anthropic.py                 │ 17                            │
  └──────────────────────┴────────────────────────────────────────────┴───────────────────────────────┘
  Install extras

  pip install jacs[langchain]   # LangChain/LangGraph
  pip install jacs[fastapi]     # FastAPI/Starlette
  pip install jacs[crewai]      # CrewAI
  pip install jacs[anthropic]   # Anthropic/Claude SDK
  pip install jacs[all]         # Everything

  Key design decisions

  - All adapters reuse BaseJacsAdapter → JacsClient (no duplicated sign/verify logic)
  - All framework imports are lazy (no hard deps)
  - Strict mode raises, permissive mode logs + passes through
  - Docs in jacsbook, README, and quickstart all updated

  Still needed before release

  - Run the full Python test suite (maturin develop && pytest)
  - Verify moltyjacs compatibility
  - Consider updating existing langchain examples to use new adapter pattern
  - Added createJacsTools(options) - returns 11 LangChain DynamicStructuredTool instances exposing the full JACS API:
    - jacs_sign, jacs_verify, jacs_create_agreement, jacs_sign_agreement, jacs_check_agreement, jacs_verify_self, jacs_trust_agent, jacs_list_trusted,
  jacs_is_trusted, jacs_audit, jacs_agent_info
  - Kept all existing auto-signing wrappers (signedTool, jacsWrapToolCall, jacsToolNode)
  - Uses lazy Zod imports (available via @langchain/core)
  - Strict/permissive error handling
  - 35 tests (was 19)

  MCP Tool Registration (mcp.ts) - Full Tool Suite

  - Added registerJacsTools(server, client) - one-call registration of 17 MCP tools on any MCP Server
  - Added getJacsMcpToolDefinitions() - returns tool definition array
  - Added handleJacsMcpToolCall(client, name, args) - handles tool execution
  - Tools mirror the Rust jacs-mcp server: sign, verify, agreements, trust, audit, HAI integration, file signing, key re-encryption
  - Gaps vs Rust: agent state CRUD (6 tools) and messaging (4 tools) aren't exposed via NAPI bindings
  - 41 tests (was 28)

  Package.json

  - Added ./langchain subpath export
  - Added @langchain/core and @langchain/langgraph as optional peer deps
  - Added langchain.js, langchain.d.ts, langchain.js.map to files array
  - Added test:langchain script, updated test:adapters to include langchain

  Documentation

  - README: Added LangChain.js section (toolkit + auto-signing), updated MCP section with tool registration
  - jacsbook: Created nodejs/langchain.md, updated nodejs/mcp.md with tool registration section, updated SUMMARY.md
  - Jacsbook builds clean

  Test Results

  - 254 total jacsnpm tests passing (135 adapter tests across 5 adapters)
  - TypeScript compiles clean
  - Added asyncio_mode = "auto" to pyproject.toml [tool.pytest.ini_options]
  - The async fixture loaded_agent now works correctly with pytest-asyncio auto mode

  2. Created MCP adapter (jacs/adapters/mcp.py)

  Two integration patterns, matching the Rust jacs-mcp approach:

  As MCP tools (LLM-callable):
  from fastmcp import FastMCP
  from jacs.adapters.mcp import register_jacs_tools

  mcp = FastMCP("jacs-server")
  register_jacs_tools(mcp)  # 9 tools: sign_document, verify_document, agreements, audit, etc.
  mcp.run()

  As MCP middleware (sign all tool outputs):
  from jacs.adapters.mcp import JacsMCPMiddleware
  mcp.add_middleware(JacsMCPMiddleware())

  3. Added gitignore entries for generated test artifacts

  - jacs_data/, jacs_keys/, jacs.config.json in jacspy/.gitignore
  - **/jacs_data/, **/jacs_keys/ in root .gitignore

  Test results

  - Full suite: 219 passed, 10 skipped, 0 errors
  - All adapters (incl. MCP): 118 passed, 4 skipped
  - MCP adapter alone: 19 passed
…───────────────────────────────────────────┐

  │  #  │      Item       │                                      Deliverable                                      │
  ├─────┼─────────────────┼───────────────────────────────────────────────────────────────────────────────────────┤
  │ 1   │ MA-4 bug fix    │ Fixed fake algorithms in A2A agent card (agent_card.rs, extension.rs, crypt/mod.rs)   │
  ├─────┼─────────────────┼───────────────────────────────────────────────────────────────────────────────────────┤
  │ 2   │ Version bump    │ All packages at 0.8.0 (10 files in JACS, 1 in moltyjacs)                              │
  ├─────┼─────────────────┼───────────────────────────────────────────────────────────────────────────────────────┤
  │ 3   │ Main README     │ Rewritten — 83 lines, "Sign it. Prove it.", decision tree bullets, honest positioning │
  ├─────┼─────────────────┼───────────────────────────────────────────────────────────────────────────────────────┤
  │ 4   │ Algorithm Guide │ New jacsbook page (advanced/algorithm-guide.md) — sizes, decision tree, PQ section    │
  ├─────┼─────────────────┼───────────────────────────────────────────────────────────────────────────────────────┤
  │ 5   │ Decision Tree   │ New jacsbook page (getting-started/decision-tree.md) — framework table, adoption path │
  ├─────┼─────────────────┼───────────────────────────────────────────────────────────────────────────────────────┤
  │ 6   │ Binding READMEs │ jacspy, jacsnpm, jacsgo — new positioning, Go marked community-maintained             │
  ├─────┼─────────────────┼───────────────────────────────────────────────────────────────────────────────────────┤
  │ 7   │ Media docs      │ trust-blind-spot.md + why-trust-infrastructure.md in hai/docs/media/                  │
  └─────┴─────────────────┴───────────────────────────────────────────────────────────────────────────────────────┘
  What remains (Wave 2 + 3)

  Wave 2 — Framework quickstarts (8.2):
  - 209-214: Six "JACS + X in 5 minutes" guides (LangGraph, CrewAI, FastAPI, Vercel AI, Express, MCP)
  - 8.2b: Multi-Agent Agreement quickstart

  Wave 3 — Infrastructure docs + deep positioning (8.3 + 8.4):
  - 216-220: MCP transport, A2A module, HAI client, trust store docs
  - 8.3b: A2A standalone quickstart
  - 8.4c: Deployment compatibility
  - 8.4e: DNS trust model documentation
  - 8.4f: Troubleshooting installation
  - 8.4g: Failure mode documentation
  - 8.4h: SEO/discoverability
  ├─────┼─────────────────────────────────────────────────────────────┼────────┤
  │ 17  │ Python quickstarts (LangChain, CrewAI, FastAPI, MCP)        │ Done   │
  ├─────┼─────────────────────────────────────────────────────────────┼────────┤
  │ 18  │ Node.js quickstarts (LangChain.js, Vercel AI, Express, MCP) │ Done   │
  ├─────┼─────────────────────────────────────────────────────────────┼────────┤
  │ 19  │ Multi-Agent Agreement quickstart                            │ Done   │
  └─────┴─────────────────────────────────────────────────────────────┴────────┘
  Overall Phase 8 Progress
  Section: Prep: Version bump + MA-4 bug fix
  Status: Done
  ────────────────────────────────────────
  Section: 8.1 Decision tree (203-208)
  Status: Done — README bullets + jacsbook page
  ────────────────────────────────────────
  Section: 8.2 Framework quickstarts (209-215, 8.2a, 8.2b)
  Status: Done — 8 framework quickstarts + agreement quickstart
  ────────────────────────────────────────
  Section: 8.3 Surface infra (216-220, MA-4, 8.3a-c)
  Status: Partial — MA-4 done, algorithm guide done. Still need: MCP transport docs, A2A module docs, HAI client docs, trust store docs, A2A standalone quickstart
  ────────────────────────────────────────
  Section: 8.4 Positioning (221-225, 8.4a-h)
  Status: Partial — README rewrite done, binding READMEs done, "zero of 29" media done, Go decision done. Still need: deployment compat, DNS trust model,
    troubleshooting installation, failure modes, SEO
  Ready for Wave 3? The remaining items are:
  - 8.3: Infrastructure docs (MCP transport, A2A, HAI client, trust store, A2A quickstart)
  - 8.4: Deployment compatibility, DNS trust model, troubleshooting, failure modes, SEO
  - New jacs verify <file> top-level command — standalone, no agent required
  - --json, --remote <url>, --key-dir flags
  - Human-readable output: signer ID, timestamp, algorithm, valid/invalid
  - 7 CLI integration tests

  9.2 Verification API

  - verify_standalone() tested in Python (7 tests) and Node.js (4 tests)
  - verify_dns() wired to Rust native binding in Python (4 tests)
  - generateVerifyLink() added to Node.js JacsClient (13 tests)
  - generate_verify_link() tested in Python (6 tests)

  9.3 Observability

  - Structured tracing::info! events for sign, verify, and agreement lifecycle
  - OTEL spans (#[tracing::instrument]) on signing/verification procedures
  - Agreement events: created, signature_added, quorum_reached, expired
  - 7 structured logging tests with custom capture layer
  - Full observability guide in jacsbook

  9.4 Cross-Language Interop

  - Rust generates Ed25519 + pq2025 fixtures (4 tests)
  - Python verifies + countersigns (12 tests)
  - Node.js verifies Rust + Python fixtures + full chain test (19 tests)
  - Bug fix: verify_document_standalone path resolution for cross-language keys
  - 35 cross-language tests total

  Documentation

  - jacsbook/src/getting-started/verification.md — full verification guide
  - jacsbook/src/guides/observability.md — event reference + OTEL + Datadog/Splunk
  - jacsbook/src/reference/cli-commands.md — jacs verify reference
  - README.md — verification section + cross-language compatibility
  - jacspy/README.md + jacsnpm/README.md — standalone verification examples

  Total new tests: ~70+

  Total lines added: ~2,258 across 92 files
  Phase 10: Hardening, CLI Distribution, and Future Prep -- Complete
  Task: 10.3 Chaos tests (MA-5a-e)
  Status: Done
  Details: 6 tests in chaos_agreement_tests.rs -- partial signing, quorum failure, tampered signature, tampered body, in-memory consistency, DNS key placeholder
  ────────────────────────────────────────
  Task: 10.3 MA-5f Failure modes doc
  Status: Done
  Details: failure-modes.md added to jacsbook with all 5 scenarios
  ────────────────────────────────────────
  Task: 10.1 Streaming adapter audit
  Status: Done
  Details: Vercel AI wrapStream already tested. Added guides/streaming.md explaining buffer-then-sign pattern
  ────────────────────────────────────────
  Task: 10.2 pq2025 benchmark
  Status: Done
  Details: Added to sign_and_check_sig.rs using SimpleAgent::ephemeral
  ────────────────────────────────────────
  Task: 10.2 Agreement benchmarks
  Status: Done
  Details: New agreement_benchmarks.rs -- N-party signing (2,5,10,25) + concurrent signing (10,50,100 agents)
  ────────────────────────────────────────
  Task: CLI Distribution: GitHub Actions
  Status: Done
  Details: release-cli.yml -- 5 targets, cli/v* tag trigger, SHA-256 checksums
  ────────────────────────────────────────
  Task: CLI Distribution: npm postinstall
  Status: Done
  Details: scripts/install-cli.js -- platform detection, auto-download, non-fatal on failure
  ────────────────────────────────────────
  Task: CLI Distribution: pip launcher
  Status: Done
  Details: cli_runner.py -- download-on-first-use, jacs entry point
  ────────────────────────────────────────
  Task: DX: "What's Next?" callouts
  Status: Done
  Details: Added to all 3 READMEs + jacsbook quickstart
  ────────────────────────────────────────
  Task: Binding test verification
  Status: Done
  Details: All green except 7 pre-existing jacsnpm failures
  Files created/modified:
  - jacs/tests/chaos_agreement_tests.rs (new, 6 tests)
  - jacs/docs/jacsbook/src/advanced/failure-modes.md (updated)
  - jacs/docs/jacsbook/src/guides/streaming.md (new)
  - jacs/docs/jacsbook/src/SUMMARY.md (updated)
  - jacs/docs/jacsbook/src/getting-started/quick-start.md (updated)
  - jacs/benches/sign_and_check_sig.rs (added pq2025 benchmark)
  - jacs/benches/agreement_benchmarks.rs (new)
  - jacs/Cargo.toml (added bench entry)
  - .github/workflows/release-cli.yml (new)
  - jacsnpm/scripts/install-cli.js (new)
  - jacsnpm/package.json (added postinstall + bin)
  - jacspy/python/jacs/cli_runner.py (new)
  - jacspy/pyproject.toml (added scripts entry)
  - README.md, jacspy/README.md, jacsnpm/README.md (What's Next callouts)
…for path-based agent verify.

Standalone cross-language verify path/root handling fixed in lib.rs (absolute path normalization, key/data root fallback, unique temp config file names).
Node quickstart config/state issues fixed in:
simple.ts
client.ts
plus rebuilt JS outputs.
Fixture mutation gating (your recommendation) implemented across Rust/Python/Node using UPDATE_CROSS_LANG_FIXTURES=1:
mod.rs
test_cross_language.py
cross-language.test.js
Python CI async marker issue fixed by adding pytest-asyncio:
python.yml
/Users/jonathan.hendler/personal/JACS/jacspy/Makefile
Additional regression fixed in langchain adapter import flow:
langchain.py
Validation run results:

cargo test -p jacs test_cli_script_flow -- --nocapture -> pass
npm run test:cross-language --silent (in jacsnpm) -> pass (19 passing)
test_cross_language.py -q (in jacspy) -> pass (62 passed, 4 skipped)
@Hendler Hendler merged commit 87dfd38 into main Feb 11, 2026
8 of 9 checks passed
@Hendler Hendler deleted the v0.6.2 branch February 11, 2026 10:07
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.

1 participant