diff --git a/Docs/AI/LocalAgentGuardrails.md b/Docs/AI/LocalAgentGuardrails.md new file mode 100644 index 0000000..0261937 --- /dev/null +++ b/Docs/AI/LocalAgentGuardrails.md @@ -0,0 +1,53 @@ +# Local AI Agent Guardrails + +These rules apply to any self-hosted AI coding assistant working on Agrarian. + +## Mandatory Behavior + +- Inspect existing project patterns before proposing changes. +- Classify every task as `low`, `medium`, or `high` risk. +- State evidence checked: files, docs, commands, logs, and build results. +- Make the smallest useful change. +- Do not refactor unrelated code. +- Do not invent APIs or project conventions. +- Do not merge directly to `main`. +- Do not store secrets, private keys, wallet keys, passwords, or tokens in the + repo. +- Passing tests/builds matter more than finishing the task. + +## Stop And Escalate + +Stop local work and prepare a Codex handoff when any of these are true: + +- confidence is below `0.65`, +- tests fail twice, +- build fails twice, +- Unreal compile errors persist after one focused fix, +- the task touches security, auth, payments, AGR wallet integration, save/load, + multiplayer, marketplace logic, migrations, or core engine architecture, +- the diff touches more files than the brief allows, +- local model context is overloaded, +- the model cannot point to evidence for its recommendation. + +## Required Handoff Format + +```text +Project: +Branch: +Goal: +Risk: +Confidence: +Files inspected: +Files changed: +Commands run: +Errors: +What local AI tried: +Why local AI stopped: +Requested Codex action: +``` + +## Quality Bar + +Local AI is useful only when it is disciplined. It should be allowed to be +uncertain, but it should not be allowed to be vague, overconfident, or +unverified. diff --git a/Docs/AI/SelfHostedAiDevelopmentStack.md b/Docs/AI/SelfHostedAiDevelopmentStack.md new file mode 100644 index 0000000..faf72ab --- /dev/null +++ b/Docs/AI/SelfHostedAiDevelopmentStack.md @@ -0,0 +1,74 @@ +# Agrarian Self-Hosted AI Development Stack + +This stack is meant to reduce pressure on Codex over time, not replace it +immediately. The first production target is supervised local assistance: +repository awareness, documentation, small safe edits, tests/builds, and clear +Codex escalation when local tooling is over its head. + +## Current Services + +- Gitea: + `http://192.168.5.21:3000/nathan/agrarian-game.git` +- Ollama: + `http://192.168.5.23:11434` +- Open WebUI: + `http://192.168.5.26:8085` +- Local AI worker VM: + `LinaAI / 192.168.5.27` +- Primary Unreal/Linux development VM: + `unreal-engine / 192.168.5.20` + +## Current Local Model + +- `qwen2.5-coder:7b` +- Role: + repo summaries, documentation, small patch suggestions, test generation, + straightforward scripts, and structured handoff preparation. +- Not the role: + broad Unreal architecture changes, risky save/multiplayer/economy rewrites, + security-sensitive code, or autonomous merges. + +## Operating Model + +1. Local AI gathers context and proposes small changes. +2. Work happens on a branch, not directly on `main`. +3. The agent reports risk, files inspected, commands run, and confidence. +4. Tests/builds decide whether a change is acceptable. +5. After two failed local attempts, stop and escalate. +6. Codex escalation uses the npm Codex CLI, not the API. +7. Human review controls merges. + +## Codex Escalation + +Use `Scripts/ai_codex_escalate.sh` with a completed task status file. The +script prefers a locally installed `codex` command and falls back to +`npx -y @openai/codex exec`. + +Codex should be called for: + +- confidence below `0.65`, +- two failed build/test attempts, +- Unreal compile errors that persist, +- tasks touching save systems, multiplayer, auth, payments, AGR wallet + integration, marketplace logic, migrations, or core architecture, +- patches that grow beyond the intended small scope, +- contradictions between local model output and official/project docs. + +## VM Boundaries + +- `LinaAI` owns local AI coding tools, Aider, Codex CLI escalation wrappers, + repo indexing, documentation generation, and small supervised branch work. +- `unreal-engine` owns Unreal Engine source, editor builds, commandlets, and + game compile/package verification. +- Keep these roles separated so AI tooling experiments do not destabilize the + Unreal build host. + +## Immediate Next Work + +- Verify Open WebUI model selection uses the Ollama backend at + `http://192.168.5.23:11434`. +- Use Aider from `LinaAI`, not from `unreal-engine`. +- Build project memory inside this repo under `Docs/` rather than creating a + separate documentation repository. +- Add small local-agent tasks first: summarize systems, write docs, generate + tests, inspect logs, and prepare Codex handoffs. diff --git a/Docs/Ops/HANDOFF.md b/Docs/Ops/HANDOFF.md index 05567ec..0d785a5 100644 --- a/Docs/Ops/HANDOFF.md +++ b/Docs/Ops/HANDOFF.md @@ -14,6 +14,56 @@ - The old `/home/nathan/agrarian/dev/ROADMAP.md` is coin/wallet-specific and should not be treated as the game roadmap. +## Self-Hosted AI Development Stack Bootstrap - 2026-05-23 + +- Nathan is starting a self-hosted AI build to reduce pressure on Codex while + keeping Codex as escalation through the npm Codex CLI rather than API usage. +- Current service inventory: + - Gitea: `http://192.168.5.21:3000` + - Ollama: `http://192.168.5.23:11434` + - Open WebUI: `http://192.168.5.26:8085` + - local AI worker VM: `LinaAI / 192.168.5.27` + - primary Unreal build VM: `unreal-engine / 192.168.5.20` +- Hardware observed: + - Unraid host: 12 CPU threads, 46 GiB RAM. + - `unreal-engine` VM: 8 CPU threads, 31 GiB RAM. + - local Codex shell host: 4 CPU threads, 3.7 GiB RAM. +- Ollama model currently available: + `qwen2.5-coder:7b`. +- Verified from `unreal-engine`: + Ollama chat API responded successfully with `local ai ready`. +- Open WebUI is reachable, but the container template currently shows + `OLLAMA_BASE_URL=http://localhost:11434`; corrected the running container and + Unraid template to use `http://192.168.5.23:11434` and port `8085`. +- Created `LinaAI` on Unraid: + - 4 vCPU, + - 12 GiB RAM, + - 100 GiB disk, + - static IP `192.168.5.27`, + - user `nathan`, + - passwordless sudo for MVP operations, + - autostart enabled. +- Reduced `unreal-engine` persistent next-boot allocation to 6 vCPU / 24 GiB + RAM so LinaAI and the Unreal build VM can coexist. The running Unreal VM was + not hot-resized. +- Cleaned the interrupted Aider install from `unreal-engine`; local AI tooling + belongs on `LinaAI`. +- Installed on `LinaAI`: + - `aider-chat` via `pipx`, + - npm `@openai/codex`, + - Gitea clone at `/home/nathan/repos/AgrarianGame`. +- Added self-hosted AI project documentation: + - `Docs/AI/SelfHostedAiDevelopmentStack.md` + - `Docs/AI/LocalAgentGuardrails.md` +- Added initial supervised-agent scripts: + - `Scripts/ai_check_stack.sh` + - `Scripts/ai_task_status_template.json` + - `Scripts/ai_codex_escalate.sh` +- Guardrail: + this is a supervised local-agent lane. No autonomous merges to `main`; local + AI prepares small changes, status files, verification results, and Codex + handoffs when confidence/build/test gates fail. + ## AGR Wallet Integration Roadmap Update - 2026-05-21 - Nathan clarified that AGR coin is a major investor hook for Agrarian: diff --git a/Scripts/ai_check_stack.sh b/Scripts/ai_check_stack.sh new file mode 100755 index 0000000..8806293 --- /dev/null +++ b/Scripts/ai_check_stack.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +set -euo pipefail + +OLLAMA_URL="${OLLAMA_URL:-http://192.168.5.23:11434}" +OPEN_WEBUI_URL="${OPEN_WEBUI_URL:-http://192.168.5.26:8085}" +GITEA_URL="${GITEA_URL:-http://192.168.5.21:3000}" +MODEL="${MODEL:-qwen2.5-coder:7b}" + +echo "Gitea: ${GITEA_URL}" +curl -fsSI "${GITEA_URL}/user/login" >/dev/null +echo " ok" + +echo "Ollama: ${OLLAMA_URL}" +curl -fsS "${OLLAMA_URL}/api/tags" >/tmp/agrarian_ollama_tags.json +if ! grep -q "\"${MODEL}\"" /tmp/agrarian_ollama_tags.json; then + echo " model ${MODEL} not found" + cat /tmp/agrarian_ollama_tags.json + exit 1 +fi +echo " ok, model ${MODEL} available" + +echo "Ollama chat smoke test" +curl -fsS "${OLLAMA_URL}/api/chat" \ + -H "Content-Type: application/json" \ + -d "{\"model\":\"${MODEL}\",\"messages\":[{\"role\":\"user\",\"content\":\"Reply with exactly: ok\"}],\"stream\":false}" \ + | grep -Eiq '"content":"[[:space:]]*ok[[:space:]]*"' +echo " ok" + +echo "Open WebUI: ${OPEN_WEBUI_URL}" +curl -fsSI "${OPEN_WEBUI_URL}" >/dev/null +echo " ok" + +echo "Self-hosted AI stack reachable." diff --git a/Scripts/ai_codex_escalate.sh b/Scripts/ai_codex_escalate.sh new file mode 100755 index 0000000..6cbbf29 --- /dev/null +++ b/Scripts/ai_codex_escalate.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [[ $# -lt 1 ]]; then + echo "Usage: $0 [extra prompt]" >&2 + exit 2 +fi + +STATUS_FILE="$1" +EXTRA_PROMPT="${2:-}" + +if [[ ! -f "$STATUS_FILE" ]]; then + echo "Missing status/handoff file: $STATUS_FILE" >&2 + exit 2 +fi + +ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)" +STAMP="$(date -u +%Y%m%dT%H%M%SZ)" +OUT_DIR="${ROOT}/Saved/AiEscalations/${STAMP}" +mkdir -p "$OUT_DIR" + +PROMPT_FILE="${OUT_DIR}/codex_prompt.txt" +LOG_FILE="${OUT_DIR}/codex_exec.log" + +{ + echo "You are Codex being called as an escalation worker for Agrarian." + echo "Use the repository at: ${ROOT}" + echo + echo "Local AI stopped and requested escalation. Review the status below," + echo "inspect the repo, make only the needed changes, run verification, and" + echo "summarize the result. Do not hide uncertainty." + echo + echo "Status / handoff:" + cat "$STATUS_FILE" + if [[ -n "$EXTRA_PROMPT" ]]; then + echo + echo "Extra prompt:" + echo "$EXTRA_PROMPT" + fi +} > "$PROMPT_FILE" + +echo "Prompt written to ${PROMPT_FILE}" + +if command -v codex >/dev/null 2>&1; then + codex exec "$(cat "$PROMPT_FILE")" 2>&1 | tee "$LOG_FILE" +else + npx -y @openai/codex exec "$(cat "$PROMPT_FILE")" 2>&1 | tee "$LOG_FILE" +fi + +echo "Codex escalation log written to ${LOG_FILE}" diff --git a/Scripts/ai_task_status_template.json b/Scripts/ai_task_status_template.json new file mode 100644 index 0000000..4a95253 --- /dev/null +++ b/Scripts/ai_task_status_template.json @@ -0,0 +1,16 @@ +{ + "task": "", + "project": "AgrarianGame", + "branch": "", + "risk": "low|medium|high", + "confidence": 0.0, + "attempts": 0, + "files_inspected": [], + "files_changed": [], + "commands_run": [], + "tests_passed": false, + "build_passed": false, + "blocked_reason": "", + "recommended_escalation": "none|codex|human", + "requested_codex_action": "" +}