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