Private handbook · do not share publicly · nmg.labs

Forge 2 · Edition 2 — The Qualifier

Starter 1 (OpenClaw, the hands) + Starter 2 (Hermes, the brain) in one online qualifier. Set up your two-agent system on a 100% free stack, wire it through Slack, and let your agents build one small, real app. Ship it and you earn your guaranteed in-person seat at Forge 2 Edition 2 on Saturday 8 August 2026.

Online · solo~ a focused build, not a marathonFree models onlySubmit: GitHub repo + live URL

Status: the Forge 2 · Edition 2 qualifier is live today — Saturday 4 July, 09:30 to 18:00 IST. Work at your own pace and submit when your build is ready — we review on a rolling basis. Watch the Forge Slack for any cut-off announcement.
Contents
00 · What this is & how to qualify

One qualifier, two agents, one small build.

Forge 2 is about orchestrating a team of AI agents instead of typing every line yourself. This qualifier proves you can stand up that team and drive it. You will:

  1. Set up OpenClaw — a coding agent you command from a chat channel (the hands).
  2. Set up Hermes — an orchestrator with memory + a skill that can run on its own (the brain).
  3. Wire both into Slack so every instruction and every agent reply is visible and you stay in the loop.
  4. Have your agents build one small, real app — a tiny Trello-style Kanban board (Laravel API + React UI).
  5. Push a public GitHub repo + deploy a live URL, then submit both.
This is deliberately a faint test. We are not grading a giant product. We are checking that your two-agent setup actually works, that a human → agent → result loop runs in chat, and that the little app runs. A clean, honest, working setup beats an ambitious broken one every time.

The path

StepYou are hereThen
This qualifier (online)Set up OpenClaw + Hermes + Slack, ship the tiny Kanban, submit repo + URL.Pass → guaranteed seat.
Forge 2 Edition 2 (in person, Sat 8 Aug 2026, NMG Gurugram)The real multi-agent sprint — Hermes orchestrates OpenClaw to ship a real build in one day.Top performers → Forge 3 + NMG offers.
01 · The stack (all free)

Everything here is free. Spend ₹0.

ComponentToolRoleCost
Coding agent (hands)OpenClawgithub.com/openclaw/openclawWrites/runs code, reports in chatfree / OSS
Orchestrator (brain)Hermes AgentNousResearch/hermes-agentPlans, remembers, runs a skill, can run on a schedulefree / OSS
Comms (human-in-the-loop)Slack (free workspace)The channel you command agents from; everything visiblefree
ModelsOllama (local) · Groq free · Google Gemini freePower the agentsfree tiers / local
Version controlGitHub (public repo)Where the agents' code landsfree
HostingVercel / Netlify (frontend) · Render/Railway free (API)Your live URLfree tiers
No paid anything. No paid API keys, no paid subscriptions. If you use a paid model you lose the free-stack points and tie-breakers. DeepSeek is not free (it needs billing) — do not use it. Stick to Ollama, Groq, or Gemini.
Safety: OpenClaw and Hermes are powerful, very new agents that run shell commands on your machine and connect to chat. Run them in a dedicated folder, use a throwaway Slack workspace for the qualifier, and never put real banking/personal secrets in their reach. A spare laptop, VM, or container is ideal.
02 · Accounts & prerequisites

Before you start (10 minutes)

Don't have everything? That's fine — your agents can help install missing pieces. The point is to get to a working loop, not a perfect machine.
03 · Set up OpenClaw — the hands

A coding agent you drive from a chat channel.

Install

npm install -g openclaw@latest      # needs Node 22.19+ (24 recommended)
openclaw onboard                    # guided wizard: gateway, workspace, channels
openclaw doctor                     # diagnose any config/channel problems

Config lives in openclaw.json. You apply changes with config "patches".

Connect OpenClaw to Slack

Create a Slack app first (see §05 for the full Slack steps and the exact bot scopes). Then:

openclaw plugins install @openclaw/slack
export SLACK_APP_TOKEN=xapp-...     # app-level token, scope: connections:write
export SLACK_BOT_TOKEN=xoxb-...     # bot user OAuth token

cat > slack.socket.patch.json5 <<'JSON5'
{ channels: { slack: {
    enabled: true,
    mode: "socket",
    appToken: { source: "env", provider: "default", id: "SLACK_APP_TOKEN" },
    botToken: { source: "env", provider: "default", id: "SLACK_BOT_TOKEN" },
} } }
JSON5

openclaw config patch --file ./slack.socket.patch.json5 --dry-run   # preview
openclaw config patch --file ./slack.socket.patch.json5             # apply
openclaw gateway                                                    # run it

✅ Verify OpenClaw is right

04 · Set up Hermes — the brain

An orchestrator that plans, remembers, and can run on its own.

Install

# Linux / macOS / WSL2
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash
# Windows (PowerShell, native)
iex (irm https://hermes-agent.nousresearch.com/install.ps1)

source ~/.bashrc        # or ~/.zshrc / restart shell
hermes setup            # setup wizard
hermes model            # choose a (free) model provider — see §06
hermes                  # start the agent (TUI)

Give it the three things judges check

1. Memory

Tell Hermes a fact in one message ("our repo is forge2-qualifier-priya, default branch main"). In a later session, ask it to recall that fact. Hermes ships persistent memory + cross-session search — confirm it remembers without you re-pasting.

2. A skill (SKILL.md)

Create one reusable skill so a task type runs the same way every time. Minimal example committed to your repo at skills/status-report/SKILL.md:

---
name: status-report
description: Post a What I Did / What's Left / What Needs Your Call update to Slack.
---
When asked for a status update, gather: tasks completed, tasks remaining,
and any decision you need from the human. Reply in exactly three sections:
**What I Did** / **What's Left** / **What Needs Your Call**.

3. One autonomous run

Use Hermes' built-in cron to fire at least once without a manual prompt (e.g. "every 10 minutes, post a one-line progress update to #sprint-main"). Capture proof it ran on its own.

✅ Verify Hermes is right

05 · Wire brain + hands through Slack

Everything in the open. You stay in the loop.

Create the Slack app + bot token

  1. api.slack.com/appsCreate New App → From scratch.
  2. OAuth & Permissions → Bot Token Scopes, add at minimum: chat:write, channels:history, channels:read, app_mentions:read, im:history, users:read. (OpenClaw's Slack plugin lists more optional scopes — add them if it asks.)
  3. Socket Mode → Enable (easiest on a laptop). It creates an App-Level token — give it scope connections:write, generate, copy the xapp-....
  4. Event Subscriptions → Enable, subscribe to bot events: message.channels, app_mention.
  5. Install to Workspace → copy the Bot User OAuth Token (xoxb-...).
  6. In Slack, /invite @YourBot into your channels.

Channel scheme (use exactly these)

ChannelPurpose
#sprint-mainYou talk to the brain (Hermes). Plans, decisions, status updates land here.
#agent-coderHermes assigns coding tasks; OpenClaw works and reports here.
#agent-logRaw agent activity / autonomous-run output. Your audit trail.
The loop that matters: you post a goal in #sprint-main → Hermes posts a plan → Hermes hands a task to OpenClaw in #agent-coder → OpenClaw writes code, runs it, and reports What I Did / What's Left / What Needs Your Call → you approve or correct. No agent works in private DMs or off-channel.

✅ Verify Slack is configured correctly (copy-paste test)

Run this round-trip — if all three succeed, your Slack wiring is correct:

export SLACK_BOT_TOKEN=xoxb-...
export CH=C0XXXXXXX            # your channel ID (channel → View details → bottom)

# 1) token valid?  -> {"ok":true,...,"user":"yourbot"}
curl -s -H "Authorization: Bearer $SLACK_BOT_TOKEN" https://slack.com/api/auth.test

# 2) can post?     -> {"ok":true,"ts":"..."}
curl -s -X POST https://slack.com/api/chat.postMessage \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN" -H "Content-Type: application/json" \
  -d "{\"channel\":\"$CH\",\"text\":\"round-trip test ✅\"}"

# 3) can read?     -> JSON containing your message
curl -s -H "Authorization: Bearer $SLACK_BOT_TOKEN" \
  "https://slack.com/api/conversations.history?channel=$CH&limit=5"

not_in_channel → invite the bot. missing_scope → add the scope and reinstall the app. Save these outputs (screenshot) — they are good submission evidence.

06 · Free model routing

Pick free models. Route smart: a stronger model plans, a cheaper one executes.

All three speak the OpenAI Chat format, so any agent that accepts a base URL + key + model id can use them.

Free optionBase URLModel idNotes
Ollama (local)http://localhost:11434/v1qwen2.5-coderTruly free, offline. ollama pull qwen2.5-coder. Key = any string.
Groq (free)https://api.groq.com/openai/v1openai/gpt-oss-120b, llama-3.3-70b-versatileVery fast. Key from console.groq.com. Free RPM/RPD limits apply.
Gemini (free)https://generativelanguage.googleapis.com/v1beta/openai/gemini-2.5-flashBig context. Key from aistudio.google.com.

Recommended routing: Hermes (brain / planning) → a stronger model (Groq gpt-oss-120b or Gemini 2.5-flash); OpenClaw (hands / execution) → qwen2.5-coder on Ollama or Groq llama-3.3-70b. Be ready to say why you routed it that way — judges reward the reasoning.

# quick model sanity test (Groq example)
curl https://api.groq.com/openai/v1/chat/completions \
  -H "Authorization: Bearer $GROQ_API_KEY" -H "Content-Type: application/json" \
  -d '{"model":"openai/gpt-oss-120b","messages":[{"role":"user","content":"reply: ok"}]}'
Free tiers rate-limit. If you hit a wall, switch the agent to Ollama (local, unlimited) or another free provider. Plan around limits — that's part of the skill.
07 · The build — a tiny Kanban board

Have your agents build a small Trello-style board. Laravel API + React UI.

This is the "real task" your two-agent system ships. Keep it small and working. You are the product owner: you describe it in #sprint-main, Hermes plans it, OpenClaw writes it, you review in chat.

Required features (must work)

Bonus (nice, not required)

Tech constraints

Scope honestly. A working board with the 5 required features beats a half-broken clone of Trello. If you're short on time, cut bonus features, not correctness.

Suggested first messages to your brain (Hermes) in #sprint-main

1. "Plan a tiny Trello-style Kanban: Laravel API (SQLite) + React (Vite).
    Entities: Board, List, Card, Tag, Member. Features: CRUD boards/lists/cards,
    move card between lists, tags, assign member, due date. Post the plan +
    task breakdown before writing any code."
2. (after you approve) "Assign task 1 to the coder. Have it scaffold the Laravel
    API with migrations + models + routes, run the migration, and report back."
3. "Now the React board UI that lists boards and renders lists/cards."
4. "Add tags, member assignment, and due dates. Show me a status report."
08 · What your repo MUST contain

Everything we judge is read from your public repo. Make it complete.

Commit incrementally (not one giant commit). Your public GitHub repo must contain:

We clone your repo at the moment you submit and score only what is inside it. Anything not committed does not exist for judging. No Google Drive, YouTube or Loom links: all evidence (Slack export, screenshots, walkthrough) goes in the repo.
Do not commit secrets. Remove real Slack/Groq/Gemini tokens before pushing. Use .env.example with placeholder values. Leaked tokens = we ask you to rotate them and it hurts your "repo & docs" score.
Make sure everything is actually pushed. Before submitting, clone your repo fresh into a new folder and confirm it has every file (config, logs, app, README). "It works on my machine" but isn't in the repo = we can't score it.
09 · Deploy a live URL (free)

We need a link we can open. Use any free host.

Pick the path of least resistance. The live URL is evidence the thing runs, not a devops exam.
10 · How to submit

Submit your build — repo + live URL + evidence.

Done (or want to lock in progress)? Submit right here — you can resubmit while the qualifier is open and we score your latest entry.

Make your repo public before you submit and keep it public until results are out — a private repo can't be scored.

📦 Everything we judge lives inside your public repo: Slack export, screenshots, agent-log, and a short screen-recording (or GIF) under evidence/. We clone your repo at submission and score only what is committed. No Google Drive, YouTube or Loom links.

Prefer a standalone page? Open the submission form ↗

11 · How you're judged

Hybrid review: automated checks + human judging.

Every submission goes through a hybrid evaluation — automated analysis of your repo and evidence, combined with human review — scored out of 100. It rewards a clean, working two-agent setup and loop, not scale or flashiness.

What we scoreWeightWhat "great" looks like
Agent setup correct18OpenClaw + Hermes both installed, configured, and demonstrably running on a free model.
Working chat loop22Human posts a goal → agent plans → codes → reports (What I Did / What's Left / What Needs Your Call) → you correct. Visible in Slack.
The Kanban app runs25Live URL (or clean local run) with the 5 required features working.
Memory + a skill12Hermes recalls a fact across sessions; your SKILL.md fires; one autonomous run.
Human-in-the-loop visibility10All agent activity in channels; nothing hidden; you can intervene.
Free stack5Ollama / Groq / Gemini only. No paid models.
Repo & docs8README, ARCHITECTURE, agent-log, incremental commits, no leaked secrets.

Small bonus (up to +3) for working email alerts + card comments. To earn a seat you need a solid overall score and a genuinely working loop + running app — a polished repo with no working agents will not pass.

Instant disqualifiers: a private repo when we score it · fabricated/edited evidence · no agent setup and no loop at all · 75%+ copied from an existing public repo · conduct violation, or evidence reachable only through external links (Google Drive, YouTube, Loom) instead of committed to the repo.
11a · Free models — the full menu + fallback ladder

Pick free. Have a backup ready.

All of these speak the OpenAI chat format, so any agent that takes a base URL + key + model id can use them. Old Groq IDs (kimi-k2, old llama tags) are decommissioned — a tutorial that gives you one will fail with 400 model_decommissioned. Use the current IDs below.

ProviderBase URLCurrent model id(s)Free?
Ollama (local)http://localhost:11434/v1qwen2.5-coder✓ unlimited, offline
Groqhttps://api.groq.com/openai/v1openai/gpt-oss-120b, openai/gpt-oss-20b✓ no card · low TPM
Google Geminihttps://generativelanguage.googleapis.com/v1beta/openai/gemini-2.5-flash✓ most generous
OpenRouterhttps://openrouter.ai/api/v1any …:free model✓ 50/day (1000 after one-time $10)
Cerebrashttps://api.cerebras.ai/v1gpt-oss-120b✓ ~1M tokens/day
Cloudflare Workers AI…/accounts/<id>/ai/v1Llama / Qwen variants✓ 10k neurons/day
Recommended routing: Hermes (planning) → Groq openai/gpt-oss-120b or Gemini gemini-2.5-flash; OpenClaw (coding) → Ollama qwen2.5-coder (local, unlimited). Fallback ladder on 429: Groq → Gemini → OpenRouter :free → Cerebras → Ollama. Unsure what's live? list a provider's models with GET /v1/models.
DeepSeek is NOT free (needs billing) — don't use it. Want a DeepSeek-family model free? route it via OpenRouter's :free variant.
11b · Troubleshooting — every error, pre-answered

When it breaks (and it will), start here.

Models & API keys

SymptomCause → Fix
400 … model_decommissionedDead Groq id (kimi-k2, old llama). → Use openai/gpt-oss-120b or -20b.
429 Too Many RequestsFree TPM/RPM hit (Groq's TPM is low for coding agents). → Lower max_tokens, add a few-second backoff, or switch to Gemini/Ollama (fallback ladder).
401 invalid_api_keyKey wrong/expired or wrong provider. → Recreate the key; make sure it matches the base URL's provider.
model_not_found / 404 on chatTypo/missing namespace or wrong base URL. → Groq ends /openai/v1, Ollama /v1, Gemini /v1beta/openai/.
"Groq free doesn't work at all"Almost always a dead model id (above). Groq free works with no card — recreate a key at console.groq.com and use a current id.

Ollama (local models)

SymptomCause → Fix
"model not found" / pull failsollama pull qwen2.5-coder first; verify the tag with ollama list.
Laptop freezes / "killed" / OOMModel too big for your RAM. → Smaller tag: 8 GB → :3b, 16 GB → :7b, 32 GB → :14b. Close other apps.
Painfully slowRunning on CPU (VRAM overflow). ollama ps shows CPU/GPU split — any CPU% = slow. → Smaller model or a free cloud API.
connection refused on :11434Ollama isn't running. → Start the Ollama app / ollama serve.
OpenAI endpoint 404Dropped the /v1. → http://localhost:11434/v1; key = any non-empty string.
Agent "configured" but model never usedWatch Ollama's console while it answers — if nothing hits it, the agent fell back. See OpenClaw #7211 below.
Laptop is just too weakDon't fight it. → Free cloud API (Groq gpt-oss-120b / Gemini gemini-2.5-flash), identical config.

OpenClaw (the hands)

SymptomCause → Fix
Install failsNode too old. → Need Node 22.19+ (24 best): node -v, then npm install -g openclaw@latest.
Gateway won't startopenclaw doctor and fix what it flags (config / port / channel).
Bot silent in SlackNot invited or missing scope. → /invite @YourBot; add scopes; reinstall the app after any scope change.
Uses the wrong model (issue #7211)Custom/local model silently ignored. → Confirm it shows in openclaw models list and watch your model server logs while it answers.

Hermes (the brain)

SymptomCause → Fix
Install path confusion (Windows)Native = %LOCALAPPDATA%\hermes; WSL/Linux = ~/.hermes. → Use one; reload the shell after install.
"Memory doesn't work"Memory is snapshotted at session start — new facts appear next session. → Verify recall across TWO sessions, not within one prompt.
SKILL.md never firesBad frontmatter / vague trigger. → Keep name/description frontmatter; make the trigger specific.
Cron / autonomous run never firesGateway must be running. → Start it; check ~/.hermes/cron/output/ for proof.

Slack bot

SymptomCause → Fix
not_in_channel/invite @YourBot into the channel.
missing_scopeAdd the scope, then reinstall the app (scopes don't apply until reinstall).
invalid_authWrong token. xoxb- = bot (API calls); xapp- = app-level (Socket Mode, connections:write). Don't mix.
Works in DMs, not channelsMissing message.channels event + channels:history scope. → Add both, reinstall.
Socket disconnects / no eventsSocket Mode off or app token missing. → Enable Socket Mode + app token with connections:write.

GitHub & deploy

SymptomCause → Fix
Repo private when judgedCan't be scored = DQ. → Make it public before submitting; keep it public.
Leaked a token in the repo→ Remove it, use .env.example with placeholders, rotate the key.
Live URL dead when judged→ Redeploy (Vercel/Netlify), or put clear local-run steps + a video in the README.
"Works on my machine" but not in repoClone fresh into a new folder and run it before submitting — unpushed files can't be seen.
Still stuck after the fix above? Post in the Forge Slack with the exact error text + what you tried — mentors are in the channel all day.
11c · Learning resources

Skim these if a concept is new.

12 · Rules & conduct
13 · Help & contact

Stuck during the window? Post in the Forge channel — mentors are around. For anything else:

Forge Captain: Ayush Gupta · labs@nmgdigital.com · response under 24h.

→ Submit your build OpenClaw repo Hermes repo