diff --git a/.gitignore b/.gitignore index 167738e..cad6b20 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ # Secrets .env +# Infrastructure manifest (local only — commit RESOURCES.example.md instead) +RESOURCES.md + # Runtime state *.log *.log.* diff --git a/RESOURCES.example.md b/RESOURCES.example.md new file mode 100644 index 0000000..f52737f --- /dev/null +++ b/RESOURCES.example.md @@ -0,0 +1,43 @@ +# RESOURCES.md — Factory infrastructure inventory +# Copy to RESOURCES.md and fill in your actual values. +# RESOURCES.md is gitignored — never commit real hostnames, IPs, or credentials. + +## Compute + +### +- **Specs**: e.g. 8 GB RAM, 4 vCPU, 80 GB disk +- **Location**: e.g. region / datacenter +- **Access**: e.g. `ssh user@host-alias` (key in ~/.ssh/id_ed25519) +- **Running**: list current workloads, e.g. woodpecker-ci, disinto, postgres +- **Available for**: what it can still absorb, e.g. staging deploy, build cache +- **Projects**: which projects use this host, e.g. myorg/myproject + +### +- **Specs**: +- **Location**: +- **Access**: +- **Running**: +- **Available for**: +- **Projects**: + +## Domains + +| Domain | Status | Project | Notes | +|--------|--------|---------|-------| +| example.com | active | myorg/myproject | main domain, auto-renew on | +| staging.example.com | active | myorg/myproject | points to staging server | + +## External accounts + +| Service | Purpose | Limits | +|---------|---------|--------| +| Codeberg | source hosting + CI triggers | 10 GB storage, 1000 min/mo CI | +| Anthropic | Claude API | $X/mo budget, rate limit: 100k TPM | +| Cloudflare | DNS + CDN | free tier | + +## Budget + +- **Compute**: e.g. €20/mo cap — current spend €12/mo (2 VPS) +- **Domains**: e.g. €30/yr — next renewal: 2025-11-01 +- **APIs**: e.g. $50/mo Anthropic — alert at $40 +- **Other**: any other constraints diff --git a/planner/planner-agent.sh b/planner/planner-agent.sh index 24acdd9..fad87ea 100755 --- a/planner/planner-agent.sh +++ b/planner/planner-agent.sh @@ -19,6 +19,7 @@ source "$FACTORY_ROOT/lib/env.sh" LOG_FILE="$SCRIPT_DIR/planner.log" CLAUDE_TIMEOUT="${CLAUDE_TIMEOUT:-3600}" VISION_FILE="${PROJECT_REPO_ROOT}/VISION.md" +RESOURCES_FILE="${FACTORY_ROOT}/RESOURCES.md" log() { echo "[$(date -u +%Y-%m-%dT%H:%M:%S)Z] $*" >> "$LOG_FILE"; } @@ -178,6 +179,9 @@ if [ -z "$VISION" ]; then exit 0 fi +RESOURCES="" +[ -f "$RESOURCES_FILE" ] && RESOURCES=$(cat "$RESOURCES_FILE") + # Fetch open issues (all labels) OPEN_ISSUES=$(codeberg_api GET "/issues?state=open&type=issues&limit=50&sort=updated&direction=desc" 2>/dev/null || true) if [ -z "$OPEN_ISSUES" ] || [ "$OPEN_ISSUES" = "null" ]; then @@ -198,6 +202,9 @@ ${VISION} ## Current project state (AGENTS.md tree) ${PROJECT_STATE} +## RESOURCES.md (shared factory infrastructure) +${RESOURCES:-"(not found — copy RESOURCES.example.md to RESOURCES.md and fill in your infrastructure)"} + ## Vision-labeled issues (goal anchors) ${VISION_ISSUES:-"(none)"} @@ -206,6 +213,7 @@ ${OPEN_SUMMARY} ## Task Identify gaps — things implied by VISION.md that are neither reflected in the project state nor covered by an existing open issue. +When a gap involves deploying, hosting, or operating a service, reference the specific resource alias from RESOURCES.md (e.g. \"deploy to \") so issues are actionable. For each gap, output a JSON object (one per line, no array wrapper): {\"title\": \"action-oriented title\", \"body\": \"problem statement + why it matters + rough approach\", \"depends\": [list of blocking issue numbers or empty]}