build(agent): jabba#56a767 iteration
This commit is contained in:
parent
05baf84c66
commit
97907a26b2
|
|
@ -0,0 +1,21 @@
|
||||||
|
node_modules/
|
||||||
|
.npmrc
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
__tests__/
|
||||||
|
coverage/
|
||||||
|
.nyc_output/
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
.cache/
|
||||||
|
*.log
|
||||||
|
.DS_Store
|
||||||
|
tmp/
|
||||||
|
.tmp/
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
.venv/
|
||||||
|
venv/
|
||||||
|
*.egg-info/
|
||||||
|
.pytest_cache/
|
||||||
|
READY_TO_PUBLISH
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
ProofWeave Prototype - AGENTS
|
||||||
|
|
||||||
|
Purpose
|
||||||
|
- Provide a small, well-tested chunk of the ProofWeave idea: a DSL manifest + toy compiler that emits wasm + proof_summary + manifest.
|
||||||
|
|
||||||
|
Repository layout
|
||||||
|
- src/proofweave/: Python package
|
||||||
|
- compiler.py: main compile function that produces bundle artifacts
|
||||||
|
- __init__.py
|
||||||
|
- tests/: pytest tests
|
||||||
|
- pyproject.toml: packaging metadata (project name: idea193-proofweave-proof-carrying)
|
||||||
|
- README.md: overview
|
||||||
|
- test.sh: runs pytest and python3 -m build
|
||||||
|
|
||||||
|
Tech stack
|
||||||
|
- Language: Python 3.8+
|
||||||
|
- Packaging: setuptools (PEP 621 pyproject)
|
||||||
|
- Test: pytest
|
||||||
|
|
||||||
|
Commands
|
||||||
|
- Run tests: `bash test.sh` (this runs `pytest` and `python3 -m build`)
|
||||||
|
- Import API: `from proofweave.compiler import compile_genome`
|
||||||
|
|
||||||
|
Development rules for agents
|
||||||
|
- Keep changes small and well-tested. Add tests for any behavioral change.
|
||||||
|
- Do not modify packaging metadata without updating `AGENTS.md` and `README.md`.
|
||||||
|
- Do not add new top-level files without updating this doc.
|
||||||
|
|
||||||
|
Notes
|
||||||
|
- This is intentionally a small initial slice. Follow-on agents should add:
|
||||||
|
- a real DSL parser and schema validation
|
||||||
|
- signing/attestation and Merkle manifest chunking
|
||||||
|
- a lightweight Rust verifier compiled to WASM
|
||||||
|
- CI workflows and more comprehensive conformance tests
|
||||||
26
README.md
26
README.md
|
|
@ -1,3 +1,25 @@
|
||||||
# idea193-proofweave-proof-carrying
|
# ProofWeave (prototype)
|
||||||
|
|
||||||
Source logic for Idea #193
|
ProofWeave is a prototype implementation of a proof-carrying WebAssembly toolchain for "ServiceGenomes". This repository provides:
|
||||||
|
|
||||||
|
- A small typed ServiceGenome DSL (JSON/YAML consumable schema) and a toy compiler that emits:
|
||||||
|
- a compact manifest JSON (provenance fields),
|
||||||
|
- a minimal valid wasm binary (empty module placeholder), and
|
||||||
|
- a proof summary JSON (resource bounds, allowed syscalls).
|
||||||
|
- A tiny Python API to produce these bundle artifacts.
|
||||||
|
- Tests and packaging metadata so the project can be built with `python3 -m build`.
|
||||||
|
|
||||||
|
This is an initial, well-tested chunk of the full ProofWeave idea described in the original design. It focuses on deterministic manifest and proof-summary generation suitable for constrained-edge verification.
|
||||||
|
|
||||||
|
Quickstart
|
||||||
|
|
||||||
|
Install dev dependencies (recommended in a venv) and run tests:
|
||||||
|
|
||||||
|
bash test.sh
|
||||||
|
|
||||||
|
Usage (Python API)
|
||||||
|
|
||||||
|
from proofweave.compiler import compile_genome
|
||||||
|
compile_genome(genome_dict, out_dir)
|
||||||
|
|
||||||
|
See `AGENTS.md` for developer notes, architecture and how to contribute.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
[build-system]
|
||||||
|
requires = ["setuptools>=61.0", "wheel"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "idea193-proofweave-proof-carrying"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "ProofWeave: a proof-carrying WebAssembly toolchain prototype for ServiceGenomes (toy implementation)."
|
||||||
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.8"
|
||||||
|
authors = [ {name = "ProofWeave Authors"} ]
|
||||||
|
classifiers = ["Programming Language :: Python :: 3"]
|
||||||
|
|
||||||
|
[tool.setuptools.packages.find]
|
||||||
|
where = ["src"]
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
"""ProofWeave package - lightweight prototype."""
|
||||||
|
|
||||||
|
from .compiler import compile_genome
|
||||||
|
|
||||||
|
__all__ = ["compile_genome"]
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
"""CLI entrypoint for proofweave."""
|
||||||
|
from .compiler import compile_genome
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def main(argv=None):
|
||||||
|
argv = argv or sys.argv[1:]
|
||||||
|
if len(argv) != 2:
|
||||||
|
print("Usage: python -m proofweave <genome.json> <out_dir>")
|
||||||
|
sys.exit(2)
|
||||||
|
genome_json, out_dir = argv
|
||||||
|
with open(genome_json, "r", encoding="utf-8") as f:
|
||||||
|
genome = json.load(f)
|
||||||
|
compile_genome(genome, out_dir)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
"""Toy compiler for ProofWeave: emits manifest, wasm placeholder, and proof summary."""
|
||||||
|
import json
|
||||||
|
import hashlib
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
from typing import Dict, Any
|
||||||
|
|
||||||
|
|
||||||
|
WASM_EMPTY_MODULE = b"\x00asm\x01\x00\x00\x00" # minimal valid wasm header (empty module)
|
||||||
|
|
||||||
|
|
||||||
|
def _sha256_bytes(b: bytes) -> str:
|
||||||
|
return hashlib.sha256(b).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def _sha256_file(path: str) -> str:
|
||||||
|
with open(path, "rb") as f:
|
||||||
|
return _sha256_bytes(f.read())
|
||||||
|
|
||||||
|
|
||||||
|
def compile_genome(genome: Dict[str, Any], out_dir: str) -> Dict[str, str]:
|
||||||
|
"""Compile a ServiceGenome dict into a minimal PC-WASM bundle.
|
||||||
|
|
||||||
|
Writes to out_dir:
|
||||||
|
- manifest.json
|
||||||
|
- wasm.wasm (minimal valid wasm module placeholder)
|
||||||
|
- proof_summary.json
|
||||||
|
|
||||||
|
Returns dict of produced file paths.
|
||||||
|
"""
|
||||||
|
os.makedirs(out_dir, exist_ok=True)
|
||||||
|
|
||||||
|
timestamp = int(time.time())
|
||||||
|
manifest = {
|
||||||
|
"parent_hash": genome.get("parent_hash"),
|
||||||
|
"delta_hash": genome.get("delta_hash"),
|
||||||
|
"mutation_policy": genome.get("mutation_policy", {}),
|
||||||
|
"toolchain_digest": genome.get("toolchain_digest", "toy-compiler-0.1"),
|
||||||
|
"authors": genome.get("authors", []),
|
||||||
|
"timestamp": timestamp,
|
||||||
|
}
|
||||||
|
|
||||||
|
manifest_path = os.path.join(out_dir, "manifest.json")
|
||||||
|
with open(manifest_path, "w", encoding="utf-8") as f:
|
||||||
|
json.dump(manifest, f, indent=2, sort_keys=True)
|
||||||
|
|
||||||
|
wasm_path = os.path.join(out_dir, "wasm.wasm")
|
||||||
|
# Write a minimal valid wasm binary (empty module). Real compiler would produce proper wasm.
|
||||||
|
with open(wasm_path, "wb") as f:
|
||||||
|
f.write(WASM_EMPTY_MODULE)
|
||||||
|
|
||||||
|
# Produce a tiny proof summary: resource bounds + allowed syscalls
|
||||||
|
# For this toy compiler we use simple heuristics (counts) and echo provided resource_envelope
|
||||||
|
resource_envelope = genome.get("resource_envelope", {"cpu_ms": 10, "memory_bytes": 65536})
|
||||||
|
proof = {
|
||||||
|
"resource_cert": {
|
||||||
|
"cpu_ms": resource_envelope.get("cpu_ms", 10),
|
||||||
|
"memory_bytes": resource_envelope.get("memory_bytes", 65536),
|
||||||
|
},
|
||||||
|
"allowed_syscalls": genome.get("allowed_syscalls", ["read", "net:egress"]),
|
||||||
|
"summary_fingerprint": None,
|
||||||
|
}
|
||||||
|
|
||||||
|
# Compute simple fingerprints for manifest and wasm
|
||||||
|
manifest_digest = _sha256_file(manifest_path)
|
||||||
|
wasm_digest = _sha256_bytes(WASM_EMPTY_MODULE)
|
||||||
|
|
||||||
|
proof["summary_fingerprint"] = _sha256_bytes(
|
||||||
|
json.dumps({"manifest": manifest_digest, "wasm": wasm_digest, "proof": proof["resource_cert"]}, sort_keys=True).encode()
|
||||||
|
)
|
||||||
|
|
||||||
|
proof_path = os.path.join(out_dir, "proof_summary.json")
|
||||||
|
with open(proof_path, "w", encoding="utf-8") as f:
|
||||||
|
json.dump(proof, f, indent=2, sort_keys=True)
|
||||||
|
|
||||||
|
return {"manifest": manifest_path, "wasm": wasm_path, "proof_summary": proof_path}
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
p = argparse.ArgumentParser()
|
||||||
|
p.add_argument("genome_json")
|
||||||
|
p.add_argument("out_dir")
|
||||||
|
args = p.parse_args()
|
||||||
|
with open(args.genome_json, "r", encoding="utf-8") as f:
|
||||||
|
genome = json.load(f)
|
||||||
|
res = compile_genome(genome, args.out_dir)
|
||||||
|
print("Wrote:")
|
||||||
|
for k, v in res.items():
|
||||||
|
print(f" - {k}: {v}")
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
echo "Running pytest..."
|
||||||
|
pytest -q
|
||||||
|
|
||||||
|
echo "Building package (python3 -m build)..."
|
||||||
|
python3 -m build
|
||||||
|
|
||||||
|
echo "All done."
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Ensure `src` is on sys.path so tests can import the package without installation
|
||||||
|
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
|
||||||
|
SRC = os.path.join(ROOT, "src")
|
||||||
|
if SRC not in sys.path:
|
||||||
|
sys.path.insert(0, SRC)
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import tempfile
|
||||||
|
from proofweave.compiler import compile_genome
|
||||||
|
|
||||||
|
|
||||||
|
def test_compile_creates_files(tmp_path):
|
||||||
|
genome = {
|
||||||
|
"parent_hash": None,
|
||||||
|
"delta_hash": "abc123",
|
||||||
|
"mutation_policy": {"max_cpu_ms": 100},
|
||||||
|
"toolchain_digest": "toy-compiler-0.1",
|
||||||
|
"authors": ["tester"],
|
||||||
|
"resource_envelope": {"cpu_ms": 5, "memory_bytes": 32768},
|
||||||
|
"allowed_syscalls": ["read", "net:egress"],
|
||||||
|
}
|
||||||
|
|
||||||
|
out = tmp_path / "out"
|
||||||
|
out.mkdir()
|
||||||
|
res = compile_genome(genome, str(out))
|
||||||
|
|
||||||
|
# Verify files exist
|
||||||
|
for key in ("manifest", "wasm", "proof_summary"):
|
||||||
|
assert key in res
|
||||||
|
assert os.path.exists(res[key])
|
||||||
|
|
||||||
|
# Validate manifest contents
|
||||||
|
with open(res["manifest"], "r", encoding="utf-8") as f:
|
||||||
|
manifest = json.load(f)
|
||||||
|
assert manifest["delta_hash"] == "abc123"
|
||||||
|
assert manifest["toolchain_digest"] == "toy-compiler-0.1"
|
||||||
|
|
||||||
|
# Validate proof summary
|
||||||
|
with open(res["proof_summary"], "r", encoding="utf-8") as f:
|
||||||
|
proof = json.load(f)
|
||||||
|
assert proof["resource_cert"]["cpu_ms"] == 5
|
||||||
|
assert isinstance(proof["summary_fingerprint"], str)
|
||||||
Loading…
Reference in New Issue