SHELL := /bin/bash .ONESHELL: .SHELLFLAGS := -euo pipefail -c PYTHON ?= python3 REPO_ROOT := $(shell pwd) INBOUND_CORE := infra/volumes/handoff/inbound-to-core QUARANTINE := infra/volumes/handoff/quarantine TOOLREQ_DIR := infra/volumes/tool-exec/requests_in TOOLRES_DIR := infra/volumes/tool-exec/results_out .PHONY: help help: @cat <<'EOF' ThreeGate Makefile targets Core validation: make validate-packets Validate Research Packets (inbound-to-core) make validate-tool-requests Validate Tool Requests (requests_in) make validate-tool-results Validate Tool Results (results_out -> inbound-to-core) Tool-exec example: make tool-exec-example Run the hello-python Tool Request via ERA wrapper Infra: make compose-up Start docker-compose stack (skeleton images) make compose-down Stop docker-compose stack Firewall: make firewall-apply Apply DOCKER-USER egress policy (requires sudo) Setup: make perms chmod +x scripts Notes: - Validators are intentionally conservative; rejects go to quarantine. - tool-exec-example requires ERA 'agent' CLI installed and accessible. EOF .PHONY: perms perms: chmod +x tools/*.py tools/*.sh tool-exec/era/*.sh tool-exec/era/*.py infra/firewall/*.sh || true .PHONY: validate-packets validate-packets: perms IN_DIR="$(INBOUND_CORE)" QUAR_DIR="$(QUARANTINE)" VALIDATOR="./tools/validate_research_packet.py" \ ./tools/validate_and_quarantine_packets.sh .PHONY: validate-tool-requests validate-tool-requests: perms REQ_DIR="$(TOOLREQ_DIR)" QUAR_DIR="$(QUARANTINE)" VALIDATOR="./tools/validate_tool_request.py" \ ./tools/validate_and_quarantine_tool_requests.sh .PHONY: validate-tool-results validate-tool-results: perms RES_DIR="$(TOOLRES_DIR)" CORE_IN_DIR="$(INBOUND_CORE)" QUAR_DIR="$(QUARANTINE)" VALIDATOR="./tools/validate_tool_result.py" \ ./tools/validate_and_quarantine_tool_results.sh .PHONY: tool-exec-example tool-exec-example: perms @mkdir -p "$(TOOLRES_DIR)" PYTHONPATH="$(REPO_ROOT)" $(PYTHON) tool-exec/era/run_tool_request.py \ --request tool-exec/examples/TR-hello-python.md \ --results-dir "$(TOOLRES_DIR)" .PHONY: compose-up compose-up: @echo "NOTE: images are placeholders; build/pin images before real use." cd infra && docker compose up -d .PHONY: compose-down compose-down: cd infra && docker compose down .PHONY: firewall-apply firewall-apply: @echo "Applying DOCKER-USER egress policy (edit env vars as needed)..." @echo "You may want to pin IPAM subnets + PROXY_IP first." sudo LLMNET_SUBNET="$${LLMNET_SUBNET:-172.18.0.0/16}" \ FETchnet_SUBNET="$${FETchnet_SUBNET:-172.19.0.0/16}" \ EGRESSNET_SUBNET="$${EGRESSNET_SUBNET:-172.20.0.0/16}" \ PROXY_IP="$${PROXY_IP:-}" \ DNS_1="$${DNS_1:-1.1.1.1}" \ DNS_2="$${DNS_2:-8.8.8.8}" \ ./infra/firewall/docker-user-chain.sh .PHONY: fetch-crossref-doi fetch-crossref-doi: perms @if [[ -z "$$DOI" ]]; then echo "Set DOI=10.xxxx/xxxxx"; exit 2; fi @mkdir -p "$(INBOUND_CORE)" PYTHONPATH="$(REPO_ROOT)" CONTACT_EMAIL="$${CONTACT_EMAIL:-}" $(PYTHON) fetch/crossref/fetch_by_doi.py \ --doi "$$DOI" \ --out "$(INBOUND_CORE)/RP-crossref-$$(echo "$$DOI" | tr '/:' '---').md" .PHONY: fetch-url fetch-url: perms @if [[ -z "$$URL" ]]; then echo "Set URL=https://..."; exit 2; fi @mkdir -p "$(INBOUND_CORE)" PYTHONPATH="$(REPO_ROOT)" CONTACT_EMAIL="$${CONTACT_EMAIL:-}" $(PYTHON) fetch/url/fetch_text_allowlisted.py \ --url "$$URL" \ --out "$(INBOUND_CORE)/RP-url-$$(echo "$$URL" | sed -e 's@https://@@' -e 's@[^A-Za-z0-9._-]@-@g' | cut -c1-80).md" .PHONY: tool-exec-monty-example tool-exec-monty-example: perms @mkdir -p "$(TOOLRES_DIR)" PYTHONPATH="$(REPO_ROOT)" $(PYTHON) tool-exec/monty/run_tool_request.py \ --request tool-exec/examples/TR-monty-json-sum.md \ --results-dir "$(TOOLRES_DIR)"