Repository navigation
Release v1.0.0
Highlights
This release ships three batches of targeted hardening on the existing
feature/assembly line, plus operator-facing documentation:
- CAD generation hardening — deterministic coder path resolution,
last-fenced-block JSON extraction, and read-only Aider reference file. - Assembly validation improvements — under-connected mate-graph
rejection, zero-volume mesh QA, and URDF preflight. - Web security improvements — CSRF defense, endpoint validation,
artifact destination restrictions, and subprocess environment
hardening.
No public API contracts were renamed. No new dependencies were added.
Bug Fixes
- Builder registry — registered
bent_jaw_xz(registry 28 → 29);
mac_assembly/README.mdbuilder-count reference updated. - Deterministic coder failures —
_node_python_coder_deterministic
now resolves thetemp_design_*.py/temp_output_*.step/
temp_output_*.stlpaths before the code-generation attempt, so
a generation failure reports a concrete script path instead of
NameError. - JSON extraction —
_extract_json_from_llmnow takes the last
fencedjsonblock when an LLM emits multiple (was first),
matching_extract_code_from_llm_responsesemantics. Fixes a class
of silent parse failures when the LLM emitted an example block before
the real answer. - Mating validation — connectivity / single-root / acyclicity
checks now gate onn_graph > 1(wasplan.mates), so empty-mate
multi-part briefs no longer silently pass. Added necessary-condition
edge-count check (len(plan.mates) >= n_graph - 1); under-connected
mate graphs now fail validation with a clear error. - Collision handling —
_pair_collidesinmac_assembly/assembly_qa.py
now returnsUNVERIFIABLEfor zero-volume and non-finite-volume mesh
pairs instead of false-passing on flat plates, sheet metal,
single-triangle STLs, and NaN/inf volumes. - URDF validation —
export_urdfruns a zero-volume mesh preflight
before emitting any link; zero-volume links are rejected with a
clear error instead of silently emitting a URDF with wrong dynamics
that PyBullet/MuJoCo then reject downstream.
Security
This release closes four tracked security issues (BUG-010, BUG-011,
BUG-012, BUG-020):
- CSRF protection — every state-changing request
(POST/PUT/PATCH/DELETE) now requires anX-MAC-CSRF: 1
header. The browser frontend sends it automatically; non-browser
clients must add it manually or receive403. Layered with loopback
Hostallowlist (whenMAC_WEB_HOSTis loopback),Origin
validation, andSec-Fetch-Site: cross-siterejection.
DNS-rebinding-safe. - Endpoint validation —
DS_BASE_URLis validated server-side
before spawning a job. Scheme must behttporhttps(always
enforced). Host must match the provider allowlist (loopback,
api.openai.com,api.deepseek.com,
generativelanguage.googleapis.com,.aliyuncs.com,
.googleapis.com) unlessMAC_WEB_ALLOW_CUSTOM_ENDPOINT=1is set.
The operator's real DashScope key is not forwarded via the LLM-client
path. - Artifact destination restrictions —
MAC_WEB_ALLOW_DEST_PATH=1
now also requiresMAC_WEB_DEST_ROOT(absolute path);dest_path
must be relative and resolve under root. Absolutedest_pathand
..traversal are rejected._copy_artifactsre-checks containment
at write time as defense-in-depth. - Subprocess environment hardening — both
subprocess.runsites
that execute LLM-authored Python now pass an explicitenv=built
from a minimal allowlist (PATH,HOME,TMPDIR,TMP,TEMP,
LANG,LC_ALL,LC_CTYPE,PYTHONPATH,PYTHONIOENCODING,
LD_LIBRARY_PATH,DYLD_LIBRARY_PATH) plusITERATIONset per
child. Every provider key in the threat model
(DASHSCOPE_API_KEY,OPENAI_API_KEY,OPENAI_API_BASE,
ANTHROPIC_API_KEY,DEEPSEEK_API_KEY,MAC_CONFIG_FILE, etc.) is
stripped. Operator override viaMAC_CHILD_ENV_ALLOW=VAR1,VAR2.
Generated Python execution is not a sandbox. The env-secret
stripping closes one specific vector — env-var secret leakage — it does
not sandbox the generated Python. The generated code still runs with the
operator's UID and retains filesystem, network, and process-spawn
access. Run MAC only with trusted prompts and dependencies, preferably
in a disposable container or restricted account. See SECURITY.md.
Known Limitations
- Generated Python still has filesystem, network, and process-spawn
capability. Env-var stripping reduces secret leakage only; it is
not a sandbox. Real isolation is the operator's responsibility
(disposable container / restricted account) until a future release. - Full sandbox isolation is future work. Container / namespace /
seccomp /setrlimitsandboxing is deferred to a future minor
release. - No resolved-address SSRF check. The
DS_BASE_URLhost allowlist
matches on hostname/suffix; a DNS name that resolves to an internal
IP is not pre-resolved and rejected. - No AST scan / static analysis of generated Python. Considered and
explicitly rejected for this patch — would market a partial control
as a sandbox. - No cross-origin frontend deployment support. The CSRF defense
assumes a same-origin frontend or non-browser client. A future
cross-origin frontend would need a real CORS + token contract. - Aider subprocess env. Aider (separate from the generated-Python
subprocess) still inherits the parent env. Separate concern; not
touched by this release. - Five pre-existing baseline test failures
(tests/test_llm_timeouts.py× 4 —LLM_API_TIMEOUTconfig drift;
tests/test_natural_language_benchmark_prompts.py× 1 — benchmark
count drift) on files outside the Batch A/B/C diff scope. Not
regressions; should be triaged in a separate follow-up.
Commit range: d63de09..d1de0a1 (7 commits).
Branch: feature/assembly.
Release-contract suite: 89 passed, 3 skipped.
Full repository suite: 507 passed, 5 baseline failures (out of
scope), 6 skipped.