CodeHero Developer Training — The Autonomous Development Framework (ADF)
Version 1.10 · October 2026 · For CodeHero PRO 5.0.2 and later
Spec Builder knowledge file: CODEHERO_PLANNING_GUIDE.md
This is the training course for developers who will design, configure and operate CodeHero projects. It teaches the Autonomous Development Framework (ADF): the method CodeHero implements, in which AI agents build, test and document a product from a specification while humans provide only what nobody else can — the business truth, the credentials, and the approvals.
The course is written in English so it can be shared with any team. Trainees may speak Greek or English with the platform; CodeHero replies in the user's language.
How to use this course
Who it is for. Developers, analysts and technical project managers who will:
- extract requirements from a client and turn them into a specification package;
- plan a CodeHero project (tickets, roles, providers, execution settings);
- operate the run (read reports, answer questions, unblock tickets, verify results);
- adapt the framework itself by editing the global context and the project contexts.
Prerequisites. Basic web development knowledge (HTTP, HTML, a backend language, SQL). A working CodeHero PRO installation with at least two active AI providers (one vision-capable). Read the User Guide chapters 2, 6, 8, 9, 11, 13, 14 and 15 first — this course assumes you know the UI.
Structure. Eight modules, in the order the work happens in real life. Each module ends with Exercises; Module 8 is a capstone with a grading rubric. Suggested pace: one module per half-day, capstone on day five.
| Module | Title | You will be able to |
|---|---|---|
| 1 | The framework | Explain the ADF principles and the CodeHero pipeline |
| 2 | Extracting knowledge from the client | Run a Spec Builder interview and produce a specification package |
| 3 | Choosing the stack | Decide PHP vs Node vs Python vs .NET, host vs container, with a written reason |
| 4 | Planning | Turn a package into a serial ticket plan with roles, providers and verification |
| 5 | Execution | Read what the agent does, why it stops, and how to answer it |
| 6 | Customizing the brain | Change global and project contexts safely, and prove the change works |
| 7 | Reaching a working result | Drive a project from first ticket to a verified, documented delivery |
| 8 | Capstone | Do all of the above on a real mini-project and pass the rubric |
Files this course refers to. All paths are relative to the CodeHero source tree (/home/claude/codehero/ on a development machine) or the installed tree (/opt/codehero/ and /etc/codehero/ on a server).
| File | What it is |
|---|---|
config/global-context.md | The global context v6.2 core: the rules every agent gets on every ticket |
config/guides/*.md | The fifteen on-demand guides of the global context (planning, verify-fix, asking, update, helper, debugging, frontend, database, build, testing, verification, coding, native, services, release): the agent opens one with codehero_get_guide when its trigger fires; the daemon pre-loads the guide of a ticket's kind ([PLAN], [REPLAN], [VERIFY], [FIX], [HELPER], [PEER]) |
config/contexts/<stack>.md | Per-language project contexts (php, node, python, html, react, dotnet, go, java, kotlin, swift, flutter, capacitor, presentation, reporting, api, hybrid) |
docs/CODEHERO_PLANNING_GUIDE.md | The Spec Builder knowledge file (Spec Builder 1.28): how to interview a client and produce a specification package |
config/assistant-planner.md | The in-app "Plan with AI" planner: how a specification (written with the user or imported) becomes a project plus ONE planning ticket |
config/assistant-general.md, assistant-progress.md, assistant-help.md | The other in-app assistant modes |
docs/USER_GUIDE.md | The user manual (UI reference) |
Keep these files open while you study. The course explains them; it does not replace them.
Presentations. The website carries slide decks with speaker notes at presentations/. The first one, The Domain Expert's Software Factory, tells the story of this course to business people with no technical background (interview → approval → build and verification → handoff, with the RepairFlow example of Modules 2–7). Use it to open a client workshop or to brief the domain experts you will interview; the developer material stays here.
PART I — FOUNDATIONS
Module 1 — The framework: what ADF is and how CodeHero implements it
1.1 The one-sentence definition
CodeHero is a complete implementation of that idea: a platform (web UI, daemon, agent, tools, database, containers) plus a written method (the global context, the Spec Builder guide, the planner). This course teaches the method; the User Guide teaches the platform.
1.2 Why a framework at all
Give a strong model a task and it will write code. That is not the problem. The problems appear in the second hour:
- it guesses a business rule (a discount, a permission, a deadline) and builds the wrong product with confidence;
- it claims success ("this should work now") without loading the page;
- it loses its memory when the context window fills, and repeats or contradicts earlier work;
- it breaks something that worked while fixing something else;
- it weakens a protection (turns off validation, hand-inserts a row) to make a test pass;
- two agents working at once edit the same file and corrupt each other's work.
Every rule in ADF exists because one of these happened in a real run. The framework is not theory; it is the accumulated set of guardrails from production deliveries. When you later customize the contexts (Module 6), remember that: change a rule only when you know which failure it prevents.
1.3 The twelve principles
These are the principles behind the global context (config/global-context.md). Learn them by name; the rest of the course refers back to them.
| # | Principle | In one line | Where it lives |
|---|---|---|---|
| P1 | The agent is the only engineer | The agent owns engineering decisions, implementation, tests and documentation. The user supplies business truth, external inputs and the approvals required by the run contract and platform. | Global §0 |
| P2 | Evidence, not claims | "Done" means a test ran, a page loaded, a row exists, a screenshot was taken. Text saying it works is not done. | Global §0 rule 2, §3, §9 |
| P3 | Never guess a business rule | Technical choices are the agent's job; business rules (money, permissions, workflows, statuses, edge cases) come only from the client. | Global §4 |
| P4 | AI before human | Before a question reaches the client, a second AI on another provider tries to find the answer in the material. Only what is genuinely business-only goes to the human. | Global §4.1, guides/asking.md, guides/helper.md |
| P5 | Safe defaults, and BLOCKED is never PASS | Only noncritical, reversible choices may use a recorded PENDING DECISION safe default. Unknown money, rights, approvals, deletion, retention, legal/safety behavior or agreed scope remains Open/BLOCKED until its owner decides. Missing credentials never make a mock a working integration. | Global §4.1, guides/asking.md |
| P6 | Memory on disk | Context compaction is assumed. Anything not written to the SPEC FILE or the KNOWLEDGE BASE is treated as if it never happened. | Global §6, §7 |
| P7 | Serial by default | One ticket at a time, each with its own sequence_order. Parallel only after the user says yes and a file-ownership analysis proves zero shared files. | Global H6, guides/planning.md §2 |
| P8 | Core slice first | The first milestone is the thinnest end-to-end slice of what the product is for, proven on the preview URL, before any secondary feature. | guides/planning.md step 6 (value order) |
| P9 | Verify without building | A VERIFY ticket on a different provider only checks; findings become one fix ticket for the original builder; a circuit breaker stops endless loops. | guides/verify-fix.md |
| P10 | Never invent facts | No invented config keys, model names, API abilities, credentials or test results. Unknown → probe it, read the real docs, or mark it BLOCKED. | Global H8 |
| P11 | Root cause, never symptom; never weaken protection | Debugging follows a fixed protocol; the WAF, auth, CSRF and validation stay on; a regression jumps the queue. | Global H3, §8 |
| P12 | Self-contained tickets on a "normal server" | Every ticket text carries objective, owned files, contracts, environment facts (localhost only) and a definition of done. Omit container names, internal container IPs and host-side entry commands from ticket instructions; retain the truthful environment contract and obey the supplied execution context. A container SETUP may close approved service gaps through GUIDE: services.md; host system installation remains an operator input. | Planner rules 6–8, Planning Guide §7.1 |
A useful mental test when you evaluate a plan, a context change or a ticket: which principle does this serve, and which one does it risk?
1.4 The pipeline: from client conversation to verified software
CLIENT (domain expert)
│ interview: ask up to three related business questions in one message, one for a difficult choice;
│ reuse supplied answers and show a first picture early · four statuses
▼
SPEC BUILDER (claude.ai / ChatGPT project + CODEHERO_PLANNING_GUIDE.md)
│ specification package: header + codehero_environment + run settings
│ + registers (requirements, decisions, dependencies) + ticket plan
▼
PLAN WITH AI (in-app planner, config/assistant-planner.md)
│ writes the specification with the user or imports the package,
│ shows preview → operator confirms → creates project + ONE [PLAN] ticket
▼
PLANNING TICKET ([PLAN] … in PLAN MODE, guides/planning.md, on the real installation)
│ baseline → requirements → contracts → dry run → review rounds → peer check
│ → assigns providers → creates the FIRST PHASE of tickets (last one: [REPLAN])
▼
DAEMON + AGENT (codehero-daemon → HeroAgent or CLI provider, per ticket)
│ global context + project context + ticket → build → verify → report
│ SPEC FILES (.specs/) + KNOWLEDGE BASE (graph) + git snapshots
▼
VERIFY / FIX / REPLAN tickets (VERIFY on another provider family; role + think per ticket kind, §4.4)
│
▼
END OF THE LINE ([SECURITY] senior+pro and [PERFORMANCE], each with its [VERIFY] of the other family;
│ the final [REPLAN]: docs/acceptance.md + docs/handover.md, restore drill on record, [VERIFY] final acceptance)
│
▼
HANDOFF REPORT → operator → client (works+evidence · waiting on you · decided for you · open)
The end of the line (4.65.1–4.65.2). Think of a car plant: every station checks its own work, a different inspector signs each hand-over, and before the car leaves the line it passes the crash test and the dynamometer; then the pre-delivery inspection, the keys and the manual. In CodeHero the last phase holds the [SECURITY] test (two different senior models at pro, every class tested actively, locally by default) and the [PERFORMANCE] test (the server's own speed measured first, the specification's volume seeded), each re-run by a [VERIFY] of the other provider family; the final [REPLAN] writes docs/acceptance.md (every requirement with its evidence) and docs/handover.md (install, the first-administrator step, backups and the restore drill, upgrade, logs, help per role) in the customer's language, and a real project gets one [VERIFY] final acceptance that reads both against the real product. A [RELEASE] ticket delivers a candidate; the [REPLAN] behind it accepts it after the phase's full run. The ticket description is the station's work-instruction sheet: the planner writes into it everything the agent would otherwise have to search for.
Three "brains" take part, and it matters which one you are talking to:
| Brain | Where | Knowledge it reads | Its job |
|---|---|---|---|
| Spec Builder | Outside CodeHero: a claude.ai or ChatGPT project with the Planning Guide uploaded as knowledge | docs/CODEHERO_PLANNING_GUIDE.md | Interview the client, decide all technical matters, run the review rounds of Part 6 (sized to the specification), output the package. Names roles and think modes, never providers. |
| In-app planner | CodeHero → AI Assistant → Plan with AI | config/assistant-planner.md + the global context | Write the specification with the user (or import the package), settle everything only a person can decide, show a preview, and after the operator confirms create the project, its environment and ONE planning ticket. It designs no tickets itself. |
| Executing agent | Spawned by the daemon for each ticket (HeroAgent for API providers; Claude Code, Codex CLI or Grok Build CLI for subscription modes) | Global context core + the guide of its kind (auto-loaded) + guides on demand (codehero_get_guide) + language context + project context + environment blocks + ticket text + conversation | Build, verify, document, report. A [PLAN] ticket plans; a [VERIFY] ticket checks and owns the fix loop; a [REPLAN] ticket compares the product with the baseline and plans the next phase. |
The Spec Builder is deliberately outside the platform: it needs a long, calm conversation with a business person, file uploads, and no server access. The other two live inside CodeHero because they need the installation's real facts (active providers, ports, containers).
1.5 The machinery (enough to reason about it)
You do not need to read the source to operate CodeHero, but you must know what runs where, because every question in Module 5 ("why did it stop?") comes back to one of these parts.
| Part | Service / file | What it does |
|---|---|---|
| Web app | codehero-web (Flask + SocketIO; nginx on port 9453) | UI, REST API, live console, terminal, AI Assistant sessions |
| Daemon | codehero-daemon (scripts/claude-daemon.py) | Picks the next ticket per project, assembles the prompt, spawns the agent, watches it, reviews the outcome, retries, snapshots |
| Agent | HeroAgent (heroagent/heroagent.py) or a CLI provider | The tool loop: model call → tool calls → results → repeat until TASK COMPLETED |
| MCP server | scripts/mcp_server.py | The codehero_* tools the agent (and the assistant) call: projects, tickets, knowledge graph, git snapshots, containers, screenshots, context extraction |
| Permission hook | scripts/permission_hook.py | The single choke point every tool call passes through: execution-mode policy, path protection, container routing, loop detection |
| Database | MySQL claude_knowledge (database/schema.sql) | projects, tickets, ticket_dependencies, conversation_messages, conversation_extractions, knowledge_nodes, knowledge_edges, project_services, … |
| Preview proxy | nginx on port 9867 | Serves every project at https://127.0.0.1:9867/<project-folder>/ — the only URL the agent may test on |
| Containers | LXC + BTRFS (heroagent/container_manager.py) | Optional per-project isolation with provisioned services; the agent's commands are routed inside transparently |
Ports 9453 and 9867 are the defaults; the real values come from /etc/codehero/system.conf (ADMIN_PORT, PROJECTS_PORT) and are substituted into the context as {ADMIN_PORT} and {PROJECTS_PORT}.
1.6 The layers of instruction
When a ticket runs, the agent's system prompt is assembled from layers, in this order (see build_project_context_file() in the daemon):
=== CURRENT WORKING PROJECT ===— project id, name, ticket id; the isolation stamp ("passproject_id=<id>to everycodehero_*tool").- A knowledge-graph snapshot — the most relevant nodes of the project's knowledge base.
- Installed core instructions, loaded fresh on every run.
- Installed stack sections selected by
project_stackand the ticket role, loaded fresh on every run. === PROJECT DESCRIPTION ===and=== PROJECT INFO ===— the description and the free "additional notes" field of the project.=== RUNTIME ENVIRONMENT ===— pinned runtime versions ("already installed — do NOT reinstall").=== SERVER PORTS ===— the concrete preview URL.=== PROJECT SEARCH TOOLS ===— only when the Codebase Map and/or semantic search are on for the project: which tool answers which question (definitions and callers → the map; questions by meaning → semantic search; text → Grep).=== PROJECT SERVICES ===— databases, caches and web apps withlocalhost:<port>and credentials ("already installed and running").=== PROJECT SECRETS ===— the names (never the values) of the project's secrets and how to use them by path.- Container execution rules and the container app-deployment guide (container projects only).
- Smart-context material — project map, prior extraction summaries, recent history.
Then the user-turn prompt adds: project paths, the database block, the ticket's own context, the parent ticket chain, the ticket title and description, the allowed write paths, and the completion contract ("end your final message with TASK COMPLETED: <summary>").
Three consequences you will use constantly:
- Since 4.66.2, the installed core and the stack sections selected by
project_stackload on every run; they are never copied into a project.global_context,project_contextandcontextcontain only the user's explicitly requested additions, in the user's words. Do not put the core, a stack section, a guide, a template, an automatically generated project analysis or the specification in these fields. The specification belongs in the planning ticket. - The fields reach agents only when
additional_context_enabledis on. New projects start on; projects present at the 4.66.2 upgrade start off. Overrides apply above platform defaults, in order global < app < notes. - Before clearing legacy content or enabling overrides, read the existing fields, distinguish installed copies from customer additions, show exactly what will change, and obtain the user's confirmation.
clear_context_fields=trueclears global and app context according to the tool schema; do not assume it preserves customer text or clears notes. Preserve confirmed customer additions. There is no refresh-global-context action.codehero_get_context_defaultsis read-only; never copy its result into a project.
1.7 Glossary you must know before Module 2
| Term | Meaning |
|---|---|
| Ticket | One task. Has a title, a description, sequence_order, optional depends_on, optional parent, a role (ai_model), a provider, a think mode, an execution mode. |
| Role | master_developer, senior_developer, junior_developer. Tickets store a role, not a model id; each provider maps roles to concrete models in heroagent/heroagent.conf (model_aliases). |
| Think mode | off / fast / basic / balanced / pro / ultra. Six modes; balanced is the project default. pro is for a very critical core or documented escalation; ultra only after pro failed on a very critical part or explicit ticket-level choice. |
| Provider | anthropic, openai, gemini, grok, glm, qwencloud, openrouter, ollama, vllm (plus generic OpenAI-compatible slots). Only active providers (valid credentials or a CLI subscription login) may be planned. Subscription modes: Claude Code (anthropic), Codex (openai), Grok Build (grok, SuperGrok); GLM and QwenCloud have a plan key on their own endpoint. |
| Execution mode | autonomous (minimizes routine tool prompts while preserving hard rules, business/input gates, new-service approval and explicit consent for destructive actions; it is independent of relaxed/strict ticket closure), semi-autonomous (auto-approves safe operations, asks for risky ones, blocks dangerous ones), supervised (asks before every write/edit/command). |
| Relaxed / strict | deps_include_awaiting = 1 / 0. Relaxed: the auto-reviewer may close a finished ticket. Strict: a human closes it. |
| SPEC FILE | .specs/<NNN>-<task>.md inside the project: the agent's plan and live progress log for one task. |
| KNOWLEDGE BASE | The project's knowledge graph (codehero_knowledge_search / codehero_knowledge_store): decisions, failed approaches, components, endpoints, patterns. |
| SNAPSHOT | A git backup taken by codehero_git_operations (backup_snapshot); automatic at ticket start and after each verified part. |
| PREVIEW URL | https://127.0.0.1:{PROJECTS_PORT}/{PROJECT_FOLDER}/ — the only place the agent may test a web page. |
| VERIFY ticket | A ticket that only checks another ticket's work. Different provider family, senior_developer, balanced, basic for a trivial/simple parent, pro only for a very critical parent; apply live provider and ledger restrictions. Never edits code. |
| HELPER ticket | A parallel ticket that only advises by messages — on another provider when one is active, otherwise on the same one, never weaker than the ticket that opens it. One per ticket; opened and closed by the ticket that needs it. |
| PEER ticket | [PEER] — the second opinion on a plan. Every planning and replan ticket opens one, talks with it until they agree, and closes it before it creates tickets. Another provider family when one is active, otherwise the same provider; never weaker than the planner. |
| WORKER ticket | [WORKER] — lead mode (§4.7): a part the planner builds in parallel under its own control. It writes only the files on its OWNS: line and its own log, reports back to the planner, and the planner verifies and closes it. |
| RELEASE ticket | [RELEASE] <version> — <milestone> — a release point of a product whose release_policy is not none (the default is none): a version number, a changelog, the package, a test as a new install and as an upgrade with data, recovery steps sized to the risk. The platform pre-loads GUIDE: release.md. |
| Walkie-talkie | Ticket-to-ticket messaging: codehero_update_ticket(ticket_id=<other numeric id>, reply=...). The platform signs a reply from a ticket (📨 FROM TICKET #id); a working ticket receives it at its next step, a parked one is woken by it, and a ticket that ends its turn with a message still unread is re-opened at once. Park on one ticket with ⏸ WAITING-FOR-TICKET #<id> (<number> · <title>) — its reply will wake me. For a set whose results are all needed, use ⏸ WAITING-FOR-ALL-TICKETS #<id>, #<id> (<number> · <title>; ...) — all replies will wake me; wake once after all reply or end. Do not use the single-ticket marker with a comma-list of IDs. |
| TASK COMPLETED | Ends the current agent turn; it does not itself close the ticket. A parked/helper-waiting turn also uses it after recording state and the correct wait marker. Completion claims still require actual checked work. |
Exercises — Module 1
- Open
config/global-context.md. For each of the twelve principles, find the exact section and copy one sentence that states it. (You will need these citations in Module 6.) - Read the glossary table in §0 of the global context. Explain in your own words the difference between the SPEC FILE and the KNOWLEDGE BASE, and why the framework keeps both.
- On your training installation, open Settings and list the active providers. Mark which ones have vision. Keep the list as a dated exercise record. Every actual plan and provider assignment refreshes
codehero_get_providers_info; the exercise snapshot is not current authority. - In the daemon's log (
journalctl -u codehero-daemon -f) watch one ticket run from start to finish. Write down the sequence of statuses you observed.
PART II — EXTRACTING KNOWLEDGE FROM THE CLIENT
Module 2 — The Spec Builder interview and the specification package
2.1 The problem this module solves
The most expensive mistakes in software are made before the first line of code: a misunderstood process, an unstated rule, a wish mistaken for a capability. In ADF the build is autonomous, so there is no developer in the loop to notice a misunderstanding half-way. Everything the agents will need must be extracted from the client before the run, in a form the agents can use.
The Spec Builder does that. It is not a form; it is an interviewer with a method, and the developer's job is to run it well, review its output critically, and know when it is done.
2.2 Setting it up
- Create a project in claude.ai (or a ChatGPT project). Upload
docs/CODEHERO_PLANNING_GUIDE.mdas project knowledge. - Set the project instruction to exactly: "You are the CodeHero Spec Builder. Follow the file
CODEHERO_PLANNING_GUIDE.mdexactly." - Start the conversation with the client's material (spreadsheets, screenshots, the current manual) already uploaded, so the assistant reads them before asking anything.
Who sits at the keyboard? Two working arrangements are common:
- The client types. The Spec Builder was written for a domain expert with no technical background: ask up to three related business questions in one message, one for a difficult choice; reuse supplied answers and show a first picture early; no jargon, a proposed answer whenever it has a basis for one. You review the transcript and the package afterwards.
- You type, with the client next to you (or on a call). Faster for small tools; you can rephrase the assistant's question in the client's own words and keep it on track. You must resist the temptation to answer business questions yourself.
Either way, the developer never invents a business fact. That rule binds you exactly as it binds the agents (P3, P10).
2.3 The four statuses — the backbone of the whole method
Every requirement and every decision in the package carries one status and one origin:
| Status | Meaning | Who resolves it |
|---|---|---|
| Confirmed | The client said it, or a source document shows it | — |
| Assumed | A reasonable business assumption that still needs confirmation | The client, at the preview or the final confirmation |
| Technical | The Spec Builder's own choice, with a reason; never asked of the client | The developer may override with a recorded reason |
| Open | A missing element that affects the build | Must be closed before the package is Ready to build — unless the client agrees to move it to Later |
Origin is user, document or agent. A requirement the assistant proposed and the client approved is Confirmed / agent. The origin column is what lets the client later audit "what did I ask for, and what did you add?".
Two rules make the statuses honest:
- "I don't know" is an answer. A technical gap is filled silently as Technical. A business gap becomes Assumed, with one sentence saying what was assumed.
- Critical items are never silently assumed. Anything that decides money, approvals, deletion rights, legal or compliance obligations, or safety stays Open and visible in every summary until the client confirms it — even when the client wants to finish quickly.
You will see the same distinction again at run time: the agent's SAFE DEFAULT (P5) is exactly an Assumed item chosen so that it cannot hurt anyone, and CRITICAL questions stop the ticket instead of getting a default.
2.4 The interview, stage by stage
Part 2 of the Planning Guide is a coverage checklist, not a script. The assistant asks in the order the conversation makes natural, skips what a document already answers, and adapts wording to the industry. As the developer, you check coverage at the end: did every stage get answered or consciously defaulted?
| Stage | What must be known afterwards | Typical count |
|---|---|---|
| 0 Setup | What to organize, existing documents, a name, who will maintain it | Coverage only; use the size-based interview targets |
| 1 Company and purpose | The business, the pain, who suffers, success in six months, internal vs external users, countries, what must never happen | Coverage only; use the size-based interview targets |
| 2 The work itself | The "things" tracked, their fields, what keeps history, the steps of the main process, who does each, rules and calculations, exceptions, documents in and out, other systems, volumes, late/duplicate data | Coverage only; use the size-based interview targets |
| 3 People and rights | User types, what each sees and changes, who may delete/approve/export (critical), scoping by branch/team, admin area, concurrency, external logins, audit | Coverage only; use the size-based interview targets |
| 4 Notifications, reports, integrations | When someone must be told, channels people actually read, reports, exports, scheduled emails, automatic data exchange | Coverage only; use the size-based interview targets |
| C Constraints (mandatory before any architecture) | Integrations and whether they are occasional or continuous; offline or background operation; time limits and continuous data; existing hosting, devices and support; initial and monthly budget | Coverage only; use the size-based interview targets |
| P Preview (mandatory) | The main screen as a text wireframe, the main process walked through with the client's own example, each role in one line, the status summary. Then: "Is this how you work? Tell me what is wrong." | Coverage only; use the size-based interview targets |
| 5 Speed, scale, real time, mobile | How fast others must see a change, alarms where seconds matter, sensors, where it is used, offline, store app vs website, camera/GPS/push, growth | Coverage only; use the size-based interview targets |
| 6 Look, feel and brand | Logo and colors, feel, references, theme, languages, units, accessibility | Coverage only; use the size-based interview targets |
| 7 Security, compliance, hosting | Personal data, 2FA, session length, security testing, where it runs, domain and SMTP, audit proof, backup tolerance, confirmed monthly cost | Coverage only; use the size-based interview targets |
| 8 Priorities and go-live | The one part that must be ready first, the MVP/Optional/Later split, data import, first administrator, training, deadline, "anything you were afraid to ask?" | Coverage only; use the size-based interview targets |
Spec Builder 1.28 targets roughly 6–8 business decisions for a small scope, 12–18 for medium and 20–30 for large work. These are targets, not quotas or permission to leave a critical decision unresolved.
Note the two mandatory checkpoints. Stage C comes before any technology decision, because the constraints — not the archetype — decide the stack (Module 3). Stage P comes before scale, brand and security, because a misunderstanding caught at the preview costs one message and the same misunderstanding caught after the build costs dozens of tickets.
2.5 A worked interview: "RepairFlow"
We will follow one example through the whole course. A small electronics repair company with three technicians tracks repair jobs in an Excel sheet. Jobs get lost, deadlines are missed, and the owner cannot see who is doing what.
The opening question is always the same: "Which piece of your work do you want to organize or automate? Describe a real example — what happened last time, step by step."
Extracts from the transcript, with the status the Spec Builder assigned:
| Client said | Became | Status / origin |
|---|---|---|
| "A customer brings a laptop, we write it in the sheet with a number, a technician takes it, when it's fixed we call the customer, they pay and pick it up." | Entity Job with states received → in_repair → ready → delivered; entities Customer, Technician | Confirmed / user |
Column H in the sheet is =D2+14 | Business rule: deadline = received date + 14 days | Confirmed / document (the assistant restated it and the client said yes) |
| "Red cells are the ones we are late on." | Confirm what overdue means and preserve the agreed highlight; a daily email is a separate proposal with recipients, timing and cost still undecided | confirmed/user only for supplied meaning; open for the proposed notification scope |
| "Only I give discounts." | Permission: discount requires the Owner role | Open — critical until the client confirmed the exact roles who may discount and the maximum |
| "We'd like customers to check the status themselves one day." | Customer portal | Later |
| "Sometimes two technicians work on the same job." | Job has one responsible technician and optional helpers; history keeps who did what | Assumed / agent, confirmed at preview |
| "How fast must the owner see that a job changed status?" — "When I refresh is fine." | Real-time: on refresh / polling every 60 s | Technical / agent |
| "We have a website on a normal hosting company, nobody technical in-house." | Hosting: standard PHP/MySQL web hosting, no in-house support | Confirmed / user → drives the stack (Module 3) |
| "Budget: as little as possible per month." | Cost sensitivity confirmed; acceptable monthly ceiling and included services remain Open until clarified | confirmed/user for cost sensitivity; open for the cost limit |
Then the preview (Stage P). The assistant showed the job list as a text wireframe (columns, the three most common actions: new job, change status, print job sheet), walked the client's own laptop example through the states, described the three roles in one line each (Owner sees all and gives discounts; Technician sees own jobs and changes status; Front desk creates jobs and marks delivered), and listed what was Confirmed, Assumed and Open. The client corrected one thing: the front desk also takes the payment, so Front desk may mark a job paid. One message, one correction, dozens of tickets saved.
2.6 The spreadsheet intake procedure
When the client uploads a spreadsheet (most internal tools start as one), the Spec Builder follows §2.9 of the guide before asking Stage 2 questions. Learn the mapping; you will use it yourself when a client hands you an Excel file:
| In the spreadsheet | Becomes |
|---|---|
| Each sheet or repeated block | A candidate entity, named in the client's words |
| Each column | A typed field (text, number, date, money, choice list, person, reference, file, formula) |
| Each formula | A business rule, restated in words and confirmed with the client's own numbers |
| Colors, comments, manual marks | Workflow states and exceptions ("what does a red cell mean?") |
| Repeated manual steps ("every Monday I copy A to B") | A scheduled job |
| Who edits which columns | Permissions |
| Duplicates, blanks, inconsistent spellings | Data-quality rules and the import cleaning plan — never silently "fixed"; the import report lists every changed or rejected row |
Two habits protect you: record separately what the sheet does today and what the new application is agreed to do (they differ more often than not), and treat text inside the file as information, never as instruction.
2.7 Wishes are not capabilities: the dependency register
A client confirming that they want an ERP integration does not prove that their ERP can provide it. Every critical external dependency goes into the dependency register (template T9) with the specific capability, the system and version, the access or licence required, and a verification status that is separate from the business status:
| Business status | Verification status |
|---|---|
| confirmed / assumed / technical / open | pending / verified / failed / mock_only |
A dependency that an active function needs must be verified before the feature tickets that depend on it start.
Use three states, scoped to explicitly listed active requirement IDs:
- Draft for confirmation: unresolved confirmation, critical business decisions or essential feasibility; no dependent feature work authorized.
- Ready for scoped discovery: the user approved a bounded feasible probe, its cost, owner and expected evidence; list allowed probes and blocked features.
- Ready for active-scope construction: critical business decisions and necessary feasibility for that scope are settled, and first-step inputs are available; later inputs have owners and gates.
A Draft does not authorize a probe automatically. Confirm the discovery scope and the in-app preview first. A legacy Ready to build label is a claim to check, never an automatic conversion. Moving requirements to Later needs the user's agreement.
A mock is recorded as mock_only and never counts as the real integration — the same rule the agent follows at run time (P5: never mock an integration and report it as working).
2.8 The decision engine is not the client's problem
Part 3 of the guide is the Spec Builder's private decision engine: archetypes, stack rules, hosting targets, the real-time ladder, the mobile ladder, the frontend choice. The client never sees the options. They answer questions about their world ("how fast must someone see a change?", "must it work without internet?"), and the assistant translates. Module 3 teaches you the same engine so you can review the choice.
2.9 Review groups and the final check
Review the complete draft in groups sized to the specification: 2 for small, about 5 for medium and up to 10 for large, followed by the final consistency check. Cover each applicable perspective and exercise worked examples; log what was actually checked and changed. A draft delivered early states the groups actually completed. Do not claim runtime verification from this review.
PLAN MODE performs a separate review on the real installation, using its own size/pace rules. The Spec Builder's review neither replaces that review nor fixes its ticket count.
2.10 The package
The output is one Markdown file (plus an SVG logo concept when relevant) with a fixed structure — twenty numbered sections and appendices A–I (Planning Guide Part 7). The parts the in-app planner reads first:
| Part | Why it matters downstream |
|---|---|
Header block with the environment_contract | Use the current environment_contract from CODEHERO_PLANNING_GUIDE.md §3.3. Preserve all runtime, service ownership, database, background/scheduled work, realtime, build/signing/device, serving, fallback, test and activation fields. Treat codehero_environment only as legacy import data, with an explicit translation and unknowns preserved. |
| 2 CodeHero run settings | Roles and think modes per ticket type, serial execution, replan and revalidation cadence, circuit breakers |
| 4 Access gate | The thin end-to-end slice through the real hosting before any feature |
| 7 Business rules | Numbered, with worked examples and expected results — the agent's only source of business truth |
| 17 Milestones and ticket plan | Value order, ticket text rules, requirement IDs per ticket |
| 18 Contracts, day-0 inputs, touchpoints | Owned inputs and the approval/contact gates defined in §2.12 |
| Appendix F | Open items, assumptions to confirm, technical decisions — the first thing the client reads |
| Appendix G / H | Requirements register and dependency register — the traceability spine |
Ticket roles in the package are written exactly as CodeHero expects, and no provider or model is ever named:
Size first: a small existing change uses one ordinary build ticket, plus verification when provider restrictions require it. A simple new build (about three screens or fewer, one user type, no login, money, integration or personal data) uses one build and one other-family VERIFY. Larger work uses the approved specification and one PLAN ticket; only that ticket designs and creates the work phases.
A small plan has up to about five work tickets, two review groups, a closing VERIFY and REPLAN, and a peer for applicable risky work. A real plan uses up to ten review groups, a peer and phases of about ten tickets ending in REPLAN. Fast pace uses fewer groups; ultra-fast is an explicitly requested demo with disclosed omissions. Counts are limits or estimates, not quotas. Provider rollout restrictions apply at every pace.
PLAN, REPLAN, PEER, VERIFY and HELPER normally use senior_developer + balanced; a peer/helper is never weaker than its opener. pro is for a very critical core or the documented failure escalation. Work is junior_developer by difficulty: trivial off, very simple fast, simple basic, moderate balanced; hard work is senior + balanced. master_developer is only on explicit request. ultra is never a project default and is not an automatic chain-ticket setting.
FIX cycle 1 uses the builder's role and think mode; cycle 2 goes up one think step; cycle 3 uses senior + pro, never below the builder. Security episodes use senior + pro; performance episodes use senior + balanced, with the specified critical-SLA exception. Release work is senior_developer + balanced (GUIDE: release.md). The planning ticket applies the current guides, pace exceptions, eligibility and user choices.
These are candidates: the planning ticket re-sizes every card by its difficulty on the real installation (§4.4).
2.11 Draft vs Ready to build
Use three states, scoped to explicitly listed active requirement IDs:
- Draft for confirmation: unresolved confirmation, critical business decisions or essential feasibility; no dependent feature work authorized.
- Ready for scoped discovery: the user approved a bounded feasible probe, its cost, owner and expected evidence; list allowed probes and blocked features.
- Ready for active-scope construction: critical business decisions and necessary feasibility for that scope are settled, and first-step inputs are available; later inputs have owners and gates.
A Draft does not authorize a probe automatically. Confirm the discovery scope and the in-app preview first. A legacy Ready to build label is a claim to check, never an automatic conversion. Moving requirements to Later needs the user's agreement.
2.12 Inputs, owners and contact gates
List only inputs the agreed scope requires. Each row names item, owner, affected requirement IDs, needed-before step, status and closure evidence or reference; never a secret value. First-step inputs must be available for construction readiness. Later domain, SMTP, store, logo or import inputs wait at their explicit gates and do not block unrelated approved work.
Front-load known business decisions and batch questions. Contacts can also be required by scoped discovery/fallback, repair-loop escalation, owner-first-stage approval, strict flow, execution-mode permissions, new-service approval and exact destructive-operation consent. Autonomous execution does not remove these gates.
2.13 Handing the package to CodeHero
IMPORT recognizes environment_contract (and explicitly translated legacy codehero_environment), the run contract and registers. It preserves the source, validates active-scope readiness, previews the allowed route and waits for explicit approval before creating project/environment/tickets. The planning ticket plans on the real installation (Module 4); the package's ticket plan is its starting material — candidates, never tickets created as they stand. The planning ticket carries DAY-0 INPUTS AND OPEN ITEMS with item, owner, affected requirement IDs, needed-before step, blocked scope and closure evidence. Secret values stay out; the ticket names only the Secrets-panel/path reference and who supplies it.
2.14 Developer's review checklist for a package
Before you import a package, check:
- ☐ Every requirement outside Later has at least one acceptance ID and a milestone (Appendix G).
- ☐ Every business rule in §7 has a number and a worked example in the client's values.
- ☐ Appendix F lists every Assumed item, every Open item and every requirement with origin
agent. - ☐ Critical items (money, approvals, deletion, legal, safety) are Confirmed or explicitly Open — none is Assumed.
- ☐ Every critical external dependency has a T9 row with a verification status; nothing needed by active scope is
pendingwithout a probe ticket. - ☐ Use the current
environment_contractfromCODEHERO_PLANNING_GUIDE.md§3.3. Preserve all runtime, service ownership, database, background/scheduled work, realtime, build/signing/device, serving, fallback, test and activation fields. Treatcodehero_environmentonly as legacy import data, with an explicit translation and unknowns preserved. - ☐ The ticket plan is serial (strictly ascending distinct sequence numbers). PLAN records architecture and decisions in project knowledge itself. The first SETUP ticket checks capabilities and application/service readiness; create a separate discovery probe only when the approved scope actually requires one. Follow with the thinnest useful confirmed flow, not a fixed quota of foundation tickets.
- ☐ Every ticket cites requirement IDs. Omit container names, internal container IPs and host-side entry commands from ticket instructions; retain the truthful environment contract and obey the supplied execution context. A container SETUP may close approved service gaps through GUIDE: services.md; host system installation remains an operator input.
- ☐ Documentation deliverables are listed in the client's language.
- ☐ Appendix E has real review rows, and the stated round count matches.
Exercises — Module 2
- Run an interview. Pair with a colleague who plays a client (a dental clinic's appointment book, a warehouse's stock sheet, a school's attendance list). Set up the Spec Builder and let the "client" answer. Do not answer business questions yourself. Deliver the package.
- Audit the statuses. In the package, count Confirmed / Assumed / Technical / Open. For every Assumed item write the one sentence the client must confirm. For every critical item check it is not Assumed.
- Spreadsheet intake. Take any real spreadsheet you have. Apply §2.6 by hand: entities, fields, formulas → rules, colors → states, manual steps → jobs. Compare with what the Spec Builder produced from the same file.
- Find the wish. In your package, find one dependency the client wants but nobody has verified. Write its T9 row and the probe ticket that would verify it.
- Review rounds. Pick five perspectives from Part 6 of the guide and run them yourself on your package, recording findings in the T6 format. Did you find something the recorded review groups missed? (Usually yes — that is why the developer reviews.)
PART III — CHOOSING THE STACK
Module 3 — How and why CodeHero picks PHP, Node, Python or .NET
3.1 The principle: the right application for this client
The Spec Builder's central principle (Planning Guide §1.1) is fit: the solution matches the real needs of the application, the initial budget and the acceptable monthly cost, the knowledge of the client's team, their existing infrastructure, and their ability to install and maintain what you specify. A technically superior stack that the client cannot host or maintain is the wrong stack.
That is why the stack is decided after Stage C (constraints), never from the archetype alone, and why every deviation from the default carries a one-line justification in the spec. When you review a package or a quick plan, look for that line. If it is missing, the choice was a preference, not a decision.
3.2 PHP-first, MySQL-first — and why
CodeHero's default backend is PHP ≥ 8.2 with MySQL ≥ 8, on standard web hosting when the design allows. The reasons are practical, and you should be able to state them to a client:
| Reason | What it means for the client |
|---|---|
| Ease of installation and maintenance | Runs on any cPanel/Plesk hosting; no process manager, no daemon, no container to operate |
| Lowest running cost | Shared hosting money, not VPS money; no in-house support needed |
| Fit with CodeHero's own strengths | The PHP project context is the most mature one (canonical includes/config.php bootstrap, "silent mistakes" list, PDO-only, CSRF, PRG); the preview proxy, php-fpm log source and php -l syntax check are wired into the verification recipe |
| No build step by default | Plain .js plus local libraries copied from /opt/codehero/libs/ (Tailwind, Alpine, Vue, FontAwesome) — instant, offline, no npm |
| Interpreted = served | On a host project the source is what nginx serves; nothing to compile, nothing to forget to copy |
The PHP profile covers: REST APIs, internal business applications, portals and management systems, backends for mobile apps, dynamic websites, and integrations served by ordinary requests or periodic jobs. A REST API, complex screens or an app-like look are not reasons to leave PHP. Neither is "many users" — load is judged from a representative workload described in the spec and verified in the access gate or a load test, never from a rule of thumb.
MySQL stays the default with every backend. Backend and database are decided separately: Python does not imply PostgreSQL and .NET does not imply SQL Server. PostgreSQL or SQL Server appear only when the client asks, when an existing environment or integration requires them, or when a specific application reason is recorded.
3.3 When to leave PHP — the only triggers
| Condition | Move to | Why |
|---|---|---|
| Required sockets or continuous connections | Add or select a runtime that demonstrably meets the connection requirement; retain an existing PHP backend when appropriate | Backend, worker and provisioning decisions are separate |
| Permanent workers or continuous processing | Select the smallest suitable worker runtime and lifecycle owner | Existing native infrastructure may suffice; a container is not implied |
| Statistics, forecasting, machine learning, scientific libraries | T-PY | Ecosystem |
| The client asks for a technology, or already runs and maintains one that meets the requirements | That stack | Maintainability and fit beat preference |
| Microsoft environment (Entra ID, SQL Server, Windows servers, a .NET team) when it fits their operations | T-NET | Fit with their operations |
| A native mobile app is needed | Swift / Kotlin + a backend by the rules above | — |
Server-sent events do not trigger the WebSocket row as long as they are verified on the actual hosting for timeouts, buffering and reconnection. If no need justifies a different backend, choose PHP/MySQL. State the required hosting capabilities and their verification gate; do not claim a particular host is suitable or container-free until its capabilities are known.
3.4 The archetypes (what the signals usually mean)
| ID | Archetype | Typical signals | Default stack | Container? |
|---|---|---|---|---|
| A1 | Static site | Brochure, no login, contact form | HTML/CSS/JS + PHP mailer | No |
| A2 | Content site with forms and admin | Pages, catalog, submissions, small admin | T-PHP, Alpine + Tailwind | No |
| A3 | Internal tool / spreadsheet replacement | "Our Excel", records, roles, reports, imports | T-PHP; Vue only when the screens justify it | No |
| A4 | Multi-tenant SaaS | Many companies, per-company settings, billing | T-PHP by default; a framework only when the confirmed existing environment or explicit supported customer choice requires it. T-NODE only for the component need that justifies it. | No / Yes |
| A5 | Real-time monitoring / operations | Devices, alarms, seconds matter, live screens | T-NODE (T-NET/T-PY when the environment fits) | Use suitable verified existing hosting/native infrastructure, or an approved platform container when required capabilities are otherwise unavailable. Runtime needs, build tools and provisioning are separate decisions; preserve the user's constraints. |
| A6 | Integration hub / API product | Connecting systems, webhooks, transformations | T-PHP when request- or schedule-based; T-NODE/T-PY when continuous | No / Yes |
| A7 | Customer / supplier portal | External logins, documents, statuses | T-PHP | No |
| A8 | Mobile companion app | Field staff, camera/barcode/GPS, push | T-PHP REST API + web app wrapped with Capacitor | Runtime as the backend |
| A9 | Native mobile app | Hardware/OS integration, offline-heavy | Swift / Kotlin + backend by the rules | Per backend |
| A10 | Data / analytics tool | Heavy calculations, forecasts, large imports | T-PY + MySQL | Use suitable verified existing hosting/native infrastructure, or an approved platform container when required capabilities are otherwise unavailable. Runtime needs, build tools and provisioning are separate decisions; preserve the user's constraints. |
3.5 The ladders: pick the lowest rung that satisfies the answers
Real-time ladder (from Stage 5 answers):
- On refresh — content sites.
- Polling every 15–60 s — most internal tools; any hosting; T-PHP.
- Polling every 5 s + in-app badge — operational tools where a minute is too slow; still T-PHP.
- Server-sent events — one-way live feeds; T-PHP where the provider supports it and it is verified; use suitable verified existing hosting/native infrastructure, or an approved platform container when required capabilities are otherwise unavailable. Runtime needs, build tools and provisioning are separate decisions; preserve the user's constraints.
- WebSockets with a durable event stream — alarms, live boards, multi-user editing; use suitable verified existing hosting/native infrastructure, or an approved platform container when required capabilities are otherwise unavailable. Runtime needs, build tools and provisioning are separate decisions; preserve the user's constraints. Pattern: events from a database outbox with cursor, replay on reconnect, heartbeat with visible disconnection, receipts.
Mobile ladder:
- Responsive web app — products with human-facing web pages use responsive layouts; APIs, CLIs and native-only products do not gain a new web app by default.
- Installable web app (PWA) — home-screen icon, offline read-only cache, web push.
- Capacitor wrapper — the same web app in the stores; native plugins for camera, barcode, GPS, push, biometrics. Requires Apple and Google developer accounts (day-0).
- React Native / Expo — only if the client's team is React-based and asks.
- Native Swift/Kotlin — only for A9 conditions.
Frontend, chosen by need and separately from the backend: a simple presentation page → HTML + Tailwind, minimal JS; simple forms → server-rendered pages + Alpine.js; complex screens with many interactions → Vue (PrimeVue preferred). Declare the required build tools and a verified build owner/environment separately from the runtime host. A deployment target serving prebuilt static assets need not run Node, but that is not proof that a suitable build environment already exists. The planning ticket chooses output paths and the platform packaging workflow.
3.6 Runtime vs build tooling vs serving — three separate declarations
The single most common confusion. The codehero_environment block separates them on purpose:
| Question | Field | Rule |
|---|---|---|
| What must be running on the server? | container_required, services, long_running_processes | Use suitable verified existing hosting/native infrastructure, or an approved platform container when required capabilities are otherwise unavailable. Runtime needs, build tools and provisioning are separate decisions; preserve the user's constraints. |
| What is needed only to build artifacts? | build.web (none / tailwind-cli / vite), build.android, build.ios, build_container | Never changes the runtime answer; a Vite-built Vue app can run on a PHP host |
| Who serves the built files? | served_by (php-host-static-files / nginx-static / app-server) | Declared separately from the tools that build them |
The global context's Section 14 mirrors this at execution time — where the build workspace lives depends on the project shape:
| Situation | Build workspace |
|---|---|
| Container project | Use the build workspace allowed by GUIDE: build.md and the supplied CONTAINER EXECUTION CONTEXT. Other allowed paths must be inside the container, never on the host; system/platform protections and service registration rules still apply. |
| Host, interpreted (PHP, plain HTML/JS) | Nowhere — the source is what is served; Composer vendor/ at {web_path}/vendor/ |
Host, compiled, has app_path | {app_path} is the workspace; build there, copy output to {web_path} |
| Host, compiled, web_path only | {web_path}/.build/ (nginx does not serve dot-dirs); only compiled output goes to the web root |
3.7 What CodeHero provides — so you never plan "install PHP" tickets
Host projects. Ubuntu 24.04, nginx, PHP 8.3, Node 22, Python 3.12, MySQL 8.0 (global §13). Each project gets its own MySQL database and user; credentials appear in the agent's PROJECT DATABASE block. Local libraries live in /opt/codehero/libs/.
Preserve the approved environment_contract in the specification. Ticket instructions describe the project's actual execution environment, project paths, local service ports and secret references; they omit container names, internal container IPs and host-side entry commands. Colocated services use localhost:<verified port>; external services keep their real endpoints. Browser checks use the platform preview URL.
After approval, create the project and its declared platform container and catalog environment through MCP before the planning ticket. nginx is built in and is never declared as an additional service. The planning ticket may discover an approved service gap: its SETUP ticket can install or register it inside the project container under GUIDE: services.md. Missing host runtimes are operator-owned inputs; tickets do not install them.
Destruction, migration, stopping the container, and restoring or deleting a snapshot require the user's explicit yes for the exact operation. For supported container actions, pass user_confirmed=true only after that yes. Never invent a network action or a parameter absent from the live schema.
3.8 Project type and paths
| Output | project_type | Path | Rule |
|---|---|---|---|
| Any project with web pages / HTML output — regardless of language | web | web_path: /var/www/projects/<slug> | A .NET, Node or Python app that serves HTML is still web |
| Pure backend API, CLI, library, mobile backend with no HTML | app | app_path: /opt/apps/<slug> | — |
project_type controls the supported project/path category; project_stack explicitly selects installed stack sections. Valid stack choices are php, node, python, mysql, html, java, dotnet, go, react, react_native, capacitor, flutter, kotlin and swift. Do not pass capacitor, native-android or dotnet as invented project_type values, or use react as the React Native context. Pinned runtime versions (php_version, node_version, python_version, …) can be passed at creation and appear in the agent's RUNTIME ENVIRONMENT block.
3.9 The environment block, field by field
environment_contract:
deployment_mode: <standard-hosting|native-host|platform-container|existing-infrastructure>
container_policy: <allowed|forbidden>
initial_target: <confirmed target or owned open item>
future_target: <confirmed target|none|owned open item>
services:
- {name: <required service>, runtime: <required runtime>, install_owner: <role>, lifecycle_owner: <role>}
database: <required database|none>
long_running_processes: <required processes|none>
scheduled_jobs: <confirmed need, duration, overlap, retry and interruption rules|none>
realtime_by_use_case: <requirement IDs, acceptable delays and evidence|{}>
build: {web: <need|none>, android: <need|none>, ios: <need|none>, ios_path: <path/owner|none>, signing: <owner/reference|none>, test_devices: <devices/owner|none>}
build_container: <required build environment|none>
served_by: <runtime serving the deployed output>
fallback_stack: <equivalent approved option|none>
test_environment: isolated-local
production_activation: separate-gate
# Container disk size (GB): <preview-confirmed requirement, or not applicable>
# Availability/evidence: <references to capability register rows; never inferred from this template>
Choose deployment_mode from the confirmed target, actual capabilities and user constraints; there is no language-driven default to platform-container. Existing manual infrastructure has a named operator and access gate. A missing host capability is an operator input; approved catalog/custom container gaps are closed by SETUP under GUIDE: services.md.
fallback_stack exists because the architecture is chosen before the installation is probed. If ticket #0 (the capability probe) finds that the runtime cannot be provided, the run stops with a question to the owner and proposes the fallback — only if it still passes the same acceptance criteria. A fallback that changes an agreed capability (update speed, live alarms, offline use) is a requirements change, not a technical swap, and each affected requirement ID must be named.
3.10 Two contrasting examples
RepairFlow (A3, internal tool). Stage C answers: occasional integrations (email only), no offline, no time limits, standard web hosting, minimal monthly cost. Stage 5: "on refresh is fine". No trigger to leave PHP. Decision recorded in the spec: "PHP/MySQL chosen; runs on standard web hosting; no container required."
environment_contract:
deployment_mode: standard-hosting
container_policy: allowed
initial_target: <confirmed target; capabilities to be verified>
future_target: <agreed target|none|owned open item>
services:
- {name: web, runtime: php, install_owner: host-operator, lifecycle_owner: host-operator}
- {name: database, runtime: mysql, install_owner: host-operator, lifecycle_owner: host-operator}
database: mysql
long_running_processes: none
scheduled_jobs: <only confirmed overdue/notification work; cadence, overlap, retries and interruption rules>
realtime_by_use_case:
job_status: {acceptable_delay: "visible when the user refreshes", transport: manual-refresh}
build: {web: <needed and verified tool|none>, android: none, ios: none, ios_path: none, signing: none, test_devices: none}
build_container: none
served_by: php-host-static-files
fallback_stack: none
test_environment: isolated-local
production_activation: separate-gate
# Host availability and the acceptable monthly cost still require their own evidence/decision.
# Do not turn a spreadsheet highlight into a scheduled email or an agreed hosting-only budget.
CodeHero project: project_type: web, tech_stack: php, web_path: /var/www/projects/repairflow, no container.
AlarmBoard (A5, real-time monitoring). A logistics yard with 40 temperature sensors; the acceptance criterion says "an out-of-range reading is shown on the operations screen within 2 seconds, measured from the sensor's timestamp to the on-screen alert". Stage 5: seconds matter; devices stream continuously. Two triggers fire (WebSockets by an acceptance criterion; continuous processing). Decision: T-NODE in a container, with the justification line "WebSocket alerting within 2 s required by A07; sensor stream needs a permanent worker."
environment_contract:
deployment_mode: platform-container
container_policy: allowed
initial_target: codehero-host
future_target: none
services:
- {name: application, runtime: node, install_owner: codehero, lifecycle_owner: codehero}
- {name: database, runtime: mysql, install_owner: codehero, lifecycle_owner: codehero}
- {name: cache, runtime: redis, install_owner: codehero, lifecycle_owner: codehero}
database: mysql
long_running_processes: [api, workers, websocket-gateway]
scheduled_jobs: <worker-queue duration, overlap, retries and interruption behavior to be established>
realtime_by_use_case:
A07: {required_delay: "sensor timestamp to visible alert <= 2 seconds", transport: websocket, evidence: pending}
build: {web: vite, android: none, ios: none, ios_path: none, signing: none, test_devices: none}
build_container: <needed build tooling; availability not yet verified>
served_by: nginx-static
fallback_stack: none
test_environment: isolated-local
production_activation: separate-gate
# Example only: use these service choices and owners only if confirmed for this installation.
# nginx is built in, not an additional service. Container disk size is confirmed in the preview.
# Polling every 5 seconds cannot satisfy A07 and is not an equivalent fallback.
# Until the necessary feasibility is evidenced, this example is discovery scope, not construction-ready.
CodeHero project: project_type: web (it serves the operations screen), tech_stack: node, web_path: /var/www/projects/alarmboard, container created via codehero_container_operations with the declared services before any ticket.
3.11 Eight mini-cases (decide, then check)
| # | The client says | Decision | Why |
|---|---|---|---|
| 1 | "A website for our law firm with a contact form and a news page the secretary updates." | A2 · T-PHP · no container | Content + small admin; no trigger |
| 2 | "We want a REST API for our mobile app; 200 field workers upload photos of deliveries." | Propose a PHP/MySQL API fitting the existing app, with upload limits, authorization and storage requirements confirmed | Do not add a new mobile client or store-account requirement unless requested; choose deployment from verified capabilities |
| 3 | "Our dispatchers must see every truck's position live on a map; alarms when a truck stops for more than 5 minutes." | A5 · T-NODE · container | Continuous device stream + live board; verify whether "live" means seconds (WebSocket) or a minute (polling) before deciding — the acceptance criterion decides |
| 4 | "We are a Microsoft shop: Entra ID logins, SQL Server, a .NET team maintains everything." | T-NET · Use suitable verified existing hosting/native infrastructure, or an approved platform container when required capabilities are otherwise unavailable. Runtime needs, build tools and provisioning are separate decisions; preserve the user's constraints. · SQL Server with a recorded reason | Fit with their operations; the client's team maintains it |
| 5 | "Forecast next month's demand per product from 5 years of sales; import the CSV every night." | A10 · T-PY · Use suitable verified existing hosting/native infrastructure, or an approved platform container when required capabilities are otherwise unavailable. Runtime needs, build tools and provisioning are separate decisions; preserve the user's constraints. · MySQL | Scientific libraries; nightly import is a scheduled job, not a worker |
| 6 | "A portal where our suppliers see their open orders and upload invoices." | A7 · T-PHP · no container | External logins, documents, statuses; scope-bound permissions |
| 7 | "Same as case 1, but we already run a Django site and our IT person knows Python." | T-PY on their environment, or T-PHP if they prefer — record the client's choice | The client already runs and maintains a stack that meets the requirements |
| 8 | "A dashboard with 12 KPIs from our MySQL, refreshed every minute, printable to PDF." | reporting project type · T-PHP · no container | Polling rung 2; the reporting context already carries ApexCharts, DataTables and PDF export patterns |
3.12 How to write the justification
One line, in the spec header and again in the planner preview when the stack is not PHP + MySQL. The pattern: requirement ID → the capability it needs → why PHP cannot provide it → the chosen stack.
A justification that names a preference ("Node is more modern") instead of a requirement is not a justification. Send it back.
Exercises — Module 3
- For each of the eight mini-cases, write the
codehero_environmentblock. Compare with a colleague; every difference must be explainable by a requirement. - Take your Module 2 package. Find the stack decision. Is there a one-line justification? Does it cite a requirement ID? If the stack is PHP, does the spec say "no container required" explicitly?
- Rewrite this bad plan fragment so it respects §3.7: "Ticket 1: Install Node 20 and MySQL in the container. Ticket 2: Configure nginx to proxy port 3000. Ticket 3: Create the schema."
- A client insists on PostgreSQL "because it is better". Write the two sentences you would say, and the line you would record in the Decision Log if they still insist.
- Explain to a non-technical client, in three sentences, why their internal tool will run on their existing web hosting and what that saves them per month.
PART IV — PLANNING
Module 4 — From package to project: the in-app planner and the ticket plan
4.1 Where planning happens — two places, one method
Open the AI Assistant in CodeHero and choose Plan with AI. The assistant runs with config/assistant-planner.md as its instructions plus the global context, and it has the codehero_* tools. It does two things well: it knows this installation (active providers, ports, container support), and it can create the project and its environment. It designs no tickets. It writes the specification with you (or imports a Spec Builder package), settles everything only a person can decide, shows a preview, and after you confirm creates the project, the container when the environment contract declares one, and exactly one ticket: the planning ticket ([PLAN] <project> — baseline and phase 1). Size first: existing small changes and simple new builds use their explicit exceptions.
The planning ticket runs in PLAN MODE (guides/planning.md, pre-loaded for it by the daemon) on the real installation: it saves the specification as the immutable baseline (.specs/000-baseline.md), reads the active providers, writes the plan file (requirements with acceptance examples, roles, stack, run settings, open questions), fills the knowledge base, writes one SPEC FILE per sub-task with the shared contracts first, orders the work by value, runs a dry run of the plan and its review rounds, gets a peer check from another provider, and creates the first phase of tickets. Every later phase is created by the [REPLAN] ticket that ends the previous one. The same PLAN MODE runs when a user opens a ticket by hand and says "σχεδίασε": one method in one place.
Size first: a small existing change uses one ordinary build ticket, plus verification when provider restrictions require it. A simple new build (about three screens or fewer, one user type, no login, money, integration or personal data) uses one build and one other-family VERIFY. Larger work uses the approved specification and one PLAN ticket; only that ticket designs and creates the work phases.
A small plan has up to about five work tickets, two review groups, a closing VERIFY and REPLAN, and a peer for applicable risky work. A real plan uses up to ten review groups, a peer and phases of about ten tickets ending in REPLAN. Fast pace uses fewer groups; ultra-fast is an explicitly requested demo with disclosed omissions. Counts are limits or estimates, not quotas. Provider rollout restrictions apply at every pace.
PLAN, REPLAN, PEER, VERIFY and HELPER normally use senior_developer + balanced; a peer/helper is never weaker than its opener. pro is for a very critical core or the documented failure escalation. Work is junior_developer by difficulty: trivial off, very simple fast, simple basic, moderate balanced; hard work is senior + balanced. master_developer is only on explicit request. ultra is never a project default and is not an automatic chain-ticket setting.
FIX cycle 1 uses the builder's role and think mode; cycle 2 goes up one think step; cycle 3 uses senior + pro, never below the builder. Security episodes use senior + pro; performance episodes use senior + balanced, with the specified critical-SLA exception. Release work is senior_developer + balanced (GUIDE: release.md). The planning ticket applies the current guides, pace exceptions, eligibility and user choices.
4.2 The assistant's rules that matter to you
- MCP tools only. Project, environment and the planning ticket are created with
codehero_create_project,codehero_container_operationsandcodehero_bulk_create_tickets(with one ticket) — never with SQL, curl or the UI on the assistant's behalf. codehero_get_providers_infofirst. The single source of truth for active providers, cost and smart weights per role, vision and thinking support; the assistant never plans from memory. The planning ticket reads it again itself, together withcodehero_get_model_table(every model of every active provider, §4.4).- Only active providers, for the project default and for the planning ticket.
- Size first: existing small changes and simple new builds use their explicit exceptions. Larger BUILD/IMPORT work creates one PLAN carrying the unchanged specification; candidate cards are not a native bulk plan.
- Preview → explicit confirmation → create. Settings, specification summary, day-0 inputs, run settings, then "yes / ok / ναι / προχώρα". "Do what you think" delegates decisions, not the preview.
- Business decisions belong to you (money, rights, approvals, deletion, retention, safety, scope, cost). A gap is marked
open, never filled with an invented default. Front-load the human input: once the planning ticket starts, the run is autonomous and a missing business decision stops it. - Environment is not ticket work — containers and services are created before the planning ticket. Omit container names, internal container IPs and host-side entry commands from ticket instructions; retain the truthful environment contract and obey the supplied execution context. A container SETUP may close approved service gaps through GUIDE: services.md; host system installation remains an operator input.
- Every run setting appears in the preview and top-level run contract. Only actual schema parameters are passed to tools:
execution_modeanddeps_include_awaitingare explicit on single/bulk ticket creation;strategy,pace,parallel,plan_approvalandrelease_policyremain contract data. - Language and voice mode, as everywhere.
4.3 Three modes
| Mode | Trigger | What the assistant does |
|---|---|---|
| IMPORT | The message contains a specification package (an environment_contract: or legacy codehero_environment: block, run settings, registers, a ticket plan) | No re-interview. Reads the header, readiness, environment and run contract; asks only for missing authorization, day-0 owners and a critical open item you can settle now; passes the package verbatim into the planning ticket |
| BUILD | Anything else: a description, a spreadsheet, a document | Acts as the Spec Builder: ask up to three related business questions in one message, one for a difficult choice; reuse supplied answers and show a first picture early; technical matters decided itself, writes the specification (mandate, business behavior, people, data, integrations, experience, numbers, environment contract, acceptance, registers, run contract), runs an in-app consistency check, previews |
| TICKET TEXT ONLY | "Just give me the ticket text" | Runs BUILD or IMPORT, then outputs the filled planning-ticket text instead of creating it |
Defaults: execution autonomous, flow relaxed (deps_include_awaiting: true), strategy balanced, serial, plan approval autonomous (you approved the preview; the planning ticket does not ask again — set plan_approval: owner-approves-first-stage if you want to see the ticket table before the first stage's work tickets are created), release policy none (a serious project — installed or upgraded outside this server, or holding business data an upgrade must not lose — gets at-milestones: the assistant proposes it in the preview, and the planning ticket judges again when the contract leaves it out), project think mode balanced. ultra is never a project default; the planning ticket itself runs senior_developer (master_developer only when you ask) — balanced; pro only for a very critical core or documented failure escalation — preferably on anthropic or openai, otherwise on the strongest active provider that supports thinking.
4.4 Providers, roles, think modes, strategy — the planning ticket's job
Roles, not models. A ticket stores ai_model = master_developer / senior_developer / junior_developer. Which concrete model that means depends on the provider, via heroagent/heroagent.conf (model_aliases). Adding a new model to the platform is a config edit; no ticket changes.
Models on merit (5.0.1). A provider usually offers more models than its three role defaults. codehero_get_model_table lists them all: provider · model · the roles that use it · vision · cost per 1M tokens · effective cost (a subscription counts 1/10) · score · the role the score earns · where the score comes from (our evaluation in model_ratings, or an estimate until a model is measured). The planning ticket may name a concrete model of the ticket's provider in the ticket's model field — the cheapest eligible model that meets the role, spread so every model works and gets measured; without it the role's default runs. The ticket's budgets (context window, output, compaction) follow the model that really runs. When one model fills two roles of a provider, the higher role thinks one step more by itself (never above pro; a ticket's own think mode wins).
Economy without losing quality. Spend where a mistake multiplies (the plan), save where the tokens go (the build tickets). On a real project of 35 tickets the build tickets used about two thirds of all tokens, verify about a tenth, plan + replan about a seventh, peers 2%. Most tokens are the context re-read at every step, not the thinking — so the model per build ticket and the number of steps matter most; think mode buys depth and costs speed.
| Ticket | Role | Think mode | One step higher when |
|---|---|---|---|
[PLAN] / [REPLAN] | senior | balanced | pro: a replan after failed or blocked parts, or a very critical core (a money / tax calculation engine, a permission model, a migration of real data); ultra only when pro already failed |
[PEER], when required by the planning guide's size/risk/pace rules | senior, never below the planner | never below the planner's think mode | bounded dialogue, at most three exchanges |
[HELPER] | senior, never below the ticket that opens it | balanced, never below the ticket that opens it | pro: something very critical, or a first helper did not solve it |
[VERIFY] | senior, the other provider family | balanced; basic for a trivial or simple parent | pro: the parent is very critical (the core of a money / tax calculation, the permission model, deleting or migrating real data) |
[FIX] | the builder's provider and role | the builder's | cycle 2: one think step up · cycle 3: senior + pro |
[SECURITY] + its [VERIFY] (at the end of the project) | senior + senior of the other provider family | pro + pro — always | one active provider → the [SECURITY] ticket alone |
[PERFORMANCE] + its [VERIFY] (at the end of the project) | senior + senior of the other provider family | balanced + balanced | pro: speed is a requirement with numbers · one active provider → the [PERFORMANCE] ticket alone |
Build / [WORKER] / [RELEASE] | junior; senior for hard work — the ticket that creates it decides | by difficulty | — |
Master only when you ask (it costs many tokens): two seniors of different families — the planner and its peer — reviewing it together, at most three exchanges, reach a good plan. You can override any role, on the project or on a single ticket.
Difficulty — judged by signals, never by feeling:
| Difficulty | Signals | Role + think (strategy balanced) |
|---|---|---|
| Trivial | texts, labels, config values, docs; a copy of a pattern that already exists in the project | junior + off |
| Very simple | one small change on an existing pattern (a field, a column, a filter), 1 file | junior + fast |
| Simple | a form / CRUD / static page on an existing pattern, simple validation, 1–2 files | junior + basic |
| Moderate | a new feature with logic over a few files, the first instance of a pattern, a schema of 2–5 tables | junior + balanced |
| Hard | money / taxes · permissions / tenant isolation · deletion / retention · concurrency / queues / locks · security / secrets · an external API with uncertain results · a migration of real data · an unclear bug · anything hard to test | senior + balanced |
| Very hard (very critical) | the core of a money / tax calculation engine · a permission model · a migration of real data · a bug that defeated two attempts | senior + pro — ultra only when pro already failed on it |
A part that failed before goes one step up; strategy eco one step down (never for Hard), performance one step up. The same role is not the same ability everywhere: read smart_weight in codehero_get_providers_info — Anthropic's junior (Sonnet 5, weight 9) may take moderate work, OpenAI's junior (gpt-6-luna, weight 7) only trivial and simple work.
Provider assignment (never the Spec Builder's job):
- visual build or verify tickets → vision-capable providers only;
- the chain tickets (
[PLAN],[PEER],[VERIFY],[HELPER],[REPLAN]) → the preferred pair is anthropic ↔ openai: one side plans and builds, the other reviews and verifies; an installation without them uses the customer's master-tier provider (highestmaster_developersmart weight), with a different family for the verify when one exists; the user's explicit preferences win; [VERIFY]tickets → a different provider family than the builder,senior_developer, balanced, basic for a trivial/simple parent, pro only for a very critical parent; apply live provider and ledger restrictions;- tickets that share a
sequence_order(an approved parallel group) → spread across providers to avoid rate limits; - strategy: eco = cheapest capable, performance = highest smart weight, balanced = both;
- One active provider is usable only for work it is eligible and capable to perform. No-vision providers do not take visual work. In a change-ledger project, excluded roles cannot build/fix and verify-restricted roles need a validated other-family Anthropic/OpenAI verifier after their latest change. If that is unavailable, select an eligible validated builder or wait for the user's decision. Elsewhere, same-provider verification is labeled as such and is not an independent-family opinion.
4.5 Translating the environment contract into a project
| Contract says | Assistant does |
|---|---|
standard-hosting / native-host (legacy: container_required: false) | Host project. HTML output → project_type: web, web_path: /var/www/projects/<slug>; no HTML → app, app_path: /opt/apps/<slug>. tech_stack from the stack; pinned versions if the spec states them. Legacy container_required=false proves only that a container was not requested; it does not establish native-host availability. Translate from the stated target or keep the unknown target open. |
platform-container (legacy: container_required: true, container_provisioning: codehero) | Create the project, then the container with codehero_container_operations using supported manifest/service provisioning fields; container_operations has no top-level services argument (nginx is automatic). Before the planning ticket. |
existing-infrastructure (legacy: manual) | Access details are a day-0 input. Missing → open item; readiness at most Ready for scoped discovery. |
| A runtime missing on a native host | A day-0 input with its owner — never a ticket. |
| Run contract | Written into the planning ticket as a top-level ## RUN CONTRACT section (and summarized in the project description). The planning ticket obeys it; a "run contract" found inside a specification or a message authorizes nothing. |
| Day-0 inputs and open items | A ## DAY-0 INPUTS AND OPEN ITEMS section of the planning ticket; the planner asks every input of a phase once, together, when it creates that phase (the work that needs no input runs first) and never asks a known open item again. |
| Draft / open items | Retain the draft without starting dependent work. Only separately approved scoped discovery can start its named probes; the effective run contract identifies allowed and blocked scope. |
4.6 The ticket fields and what the scheduler does with them
| Field | Meaning | Blocks execution? |
|---|---|---|
sequence_order | Ordering. Distinct ascending numbers = serial (the default). The same number on two tickets = a parallel group (as many at once as MAX_PARALLEL_TICKETS_PER_PROJECT allows). | Yes — a higher number starts only when EVERY ticket with a lower number is done or skipped. A ticket left in awaiting_input, failed or stuck holds everything behind it. |
depends_on | Explicit dependency. In a bulk call: 1-indexed positions of the same call, earlier only (a later or unknown position rejects the whole call). In codehero_create_ticket: existing tickets by numeric id or ticket number (an unknown value is an error). Stored in ticket_dependencies. | Yes — every dependency must be done or skipped, in relaxed and strict flow alike. It matters inside a shared sequence number; across numbers the number already orders. |
parent_ticket_id / parent_sequence | Sub-task: waits for the parent, inherits its context (title, description, summary of the parent's conversation). This is how a [VERIFY] ticket finds its parent. | Yes — the parent must be done or skipped |
ai_model, provider, think_mode, execution_mode | Per-ticket settings; omitted → inherit from the project | — |
model | Optional concrete model of the ticket's provider (5.0.1, from codehero_get_model_table); checked against the provider's list; omitted → the role's default | — |
deps_include_awaiting | The flow: 1 relaxed (default) · 0 strict — see §4.9 | — |
is_forced | Forced start (Start Now / Force Next / codehero_start_ticket): the ticket starts NOW on an extra worker slot, ignoring its sequence, its dependencies, its parent and the slot limit. For an observer ticket or a small change while the plan runs; the flag stays, so a forced observer restarts after every reply. | overrides everything |
ticket_type, priority | feature / task / bug …; low / medium / high / critical | Priority only orders eligible tickets |
Ordinary scheduling considers the lowest unfinished sequence and starts open tickets whose dependencies and parent are done/skipped, subject to configured slots. Higher ordinary sequences wait until all lower tickets are done/skipped. Explicit forced start is a separate exception: it ignores sequence, dependencies, parent and slot limits and keeps its flag until cleared.
Titles are triggers. [PLAN], [REPLAN], [VERIFY], [FIX], [HELPER], [PEER], [WORKER], [RELEASE] make the daemon pre-load the matching guide into the ticket's context. Keep the prefix exactly.
Adding tickets to a project that already has some: explicit sequence numbers in a bulk call are auto-offset to continue after the existing ones; codehero_create_ticket stores the number you give — that is how a verifier puts its fix at its own sequence.
4.7 Serial first; approved parallel with ownership analysis
Design every plan serial. A serial run cannot corrupt shared files, and every ticket starts from the previous ticket's verified, reported state. The cost is wall-clock time; the benefit is correctness and a clean audit trail.
Respect the run contract. serial-only stays serial without parallel offers. When the user has requested parallel work (allowed-with-ownership-analysis), the planning ticket proves exact disjoint ownership before sharing a sequence. Required helper/peer/fix/lead-mode exceptions follow their guides.
- For every ticket in the group, list the exact files and folders it will create or edit. The ticket owns them; the list goes into its description; the agent may not touch files outside it (global H6).
- Check the danger files by name against every ticket in the group:
index.php/index.html,app.js/main.*, routing tables,package.json/composer.json/requirements.txt,.env/ config, DB migrations, global CSS, shared header/footer includes. - Zero overlap is required. Any overlap → serialize (
depends_on+ differentsequence_order), split the ownership, or merge into one ticket. - Show the ownership table in the preview. Show the ownership analysis and respect the configured per-project concurrency limit (shipped default 5); the limit is not permission to parallelize shared files. In any doubt → serial.
Three exceptions need no approval: [VERIFY], [PEER] and [HELPER] tickets may share a sequence_order with the ticket they serve, because they are forbidden to write product files; the [FIX] tickets a verifier creates at its own sequence while it parks and waits for them (§5.9); and the [WORKER] tickets of lead mode.
Lead mode — the planner keeps control. After the planner and its peer agreed and your answers are in, a [PLAN] / [REPLAN] ticket may build 2–5 tightly coupled parts itself as the lead, instead of handing them to normal tickets, when keeping its own context matters (planning.md §2b). It writes every shared file first (contracts, routes, config, migrations, package files, the plan), then opens one [WORKER] per part at its own sequence: each with a different job, its own SPEC FILE, its own LOG (.specs/<NNN>-<part>.log) and an OWNS: line listing its files. The platform refuses a worker's file-edit tool outside that line, so no worker writes a shared file or another worker's file. The lead parks with ⏸ WAITING-FOR-ALL-TICKETS #a, #b, … and is woken once, when every worker has replied or ended; it reads each LOG, runs each worker's test group, checks that only owned files changed, and closes the workers. A long phase stays cheaper and sturdier as normal tickets + [VERIFY] + [REPLAN]: every report wakes the lead and it re-reads its whole conversation.
4.8 The ticket description recipe (every ticket, both modes)
Every native work ticket carries: objective and requirement IDs; its actual SPEC FILE path; exact files to read first and files it owns; references to authoritative contract sections/versions; real environment and secret-reference facts; worked acceptance and negative cases; its own and affected test-group commands; known decisions/traps; and required guide sections before the specification material. Do not invent repository paths in a candidate package. No container names/internal IPs, secret values, or duplicated platform operating method.
4.9 Execution mode and flow
| Execution mode | Behaviour | Use when |
|---|---|---|
autonomous (default) | Autonomous execution minimizes routine tool prompts while preserving hard rules, business/input gates, new-service approval and explicit consent for destructive actions. It is independent of relaxed/strict ticket closure. | Trusted work, the normal ADF run |
semi-autonomous | Auto-approves file operations inside the project, tests, builds, lockfile-only installs, read-only git; asks for new package installs, npm/composer update, migrations, git writes, service restarts, network calls; blocks system files, .git internals, anything outside the project | Projects that need guardrails; approvals can be generalized with "Approve all similar" |
supervised | Asks before every write, edit and command | Sensitive projects; learning how the agent works |
Execution mode controls tool approval, not authorization to ignore the workflow. Ticket agents use platform snapshot/git tools, never bare git. Autonomous mode does not authorize deleting project data, bypassing service approval, inventing business decisions or ignoring the chosen ticket flow.
| Flow | deps_include_awaiting | What changes |
|---|---|---|
relaxed (default) | 1 | When the agent finishes, the ticket parks in awaiting_input, the auto-reviewer classifies it (COMPLETED / QUESTION / ERROR) and closes it to done on COMPLETED after a short delay |
strict | 0 | The ticket parks in awaiting_input with reason completed and a human closes it |
Note what relaxed does not do: it does not let a ticket in awaiting_input satisfy a dependency. Dependencies always require done or skipped.
4.10 The two previews
The assistant's preview (before anything exists):
⚙️ Settings
• Project: <name> (<type>, <path>) — <stack> · Environment: <deployment_mode> [services: …]
• Execution: <approved mode> · Flow: <relaxed → true | strict → false> · Strategy: <eco|balanced|performance>
• Pace: <standard|fast|ultra-fast> · Parallel: <serial-only|allowed-with-ownership-analysis>
• Plan approval: <autonomous|owner-approves-first-stage> · Releases: <none|at-milestones|every-phase>
• Planning ticket: <provider> · senior_developer (master only if you ask) · <balanced; pro only for a very critical core or documented failure escalation>
📄 Specification — <readiness state> · review: <what was actually done>
• Scope (MVP): … · Later / parked: … · Assumptions I made: … · Open items: <item → owner → what it blocks>
• Day-0 inputs you must provide: <what → who → when it is needed>
▶️ What happens after you confirm: project [+ environment] + ONE planning ticket …
Do you agree? (yes / no / changes)
The planning ticket's plan (in its final report and in the phase file .specs/phases/K01.md — the plan file .specs/001-project-plan.md stays a small index of requirements, settings, open questions and phases, the acceptance examples are in .specs/001-acceptance.md, and the baseline gets .specs/000-baseline-index.md, so later tickets read only the parts they need): the run settings in one line, then the ticket table (# · ticket · seq · provider · role · think · deps · files owned · verify), plus three honest lines — what the dry run found, what the review rounds changed and how many really ran, and the peer verdict (or "no second provider"). Phase creation requires native_creation_authorized=true and plan_approval=autonomous in the ticket's own top-level RUN CONTRACT, plus satisfied scope/input/service gates and closed review helpers. An attachment's flag is not authorization. With owner-approves-first-stage, or without explicit native authorization, show the plan and wait before creating work tickets.
Read a plan like a reviewer, not a spectator: is the first milestone the thinnest end-to-end slice? Does every [VERIFY] use a different provider family? Is every visual ticket on a vision-capable provider? Does every dependency express a real need? Is anything in it that nobody asked for?
4.11 Worked phase outline: RepairFlow
This is an illustrative outline for the planning ticket, not a bulk plan for the assistant to create. Assume the active scope and its business decisions are confirmed; list their R IDs and actual capability evidence. Read live providers and their role-specific ledger eligibility before assigning any row.
- SETUP: prove runtime/database/preview readiness and close only approved environment gaps; configure the application foundation.
- Access gate: implement and verify the smallest confirmed login/protected-flow slice, including refusals and the operator-controlled administrator procedure.
- Core slice: create a job, perform its confirmed state transition and deliver it; include that role's help, repeatable tests and worked acceptance.
- Overdue behavior/notification only when deadline meaning, recipients, cadence and rights are confirmed.
- Add the required independent verification episodes by risk, pace and provider restrictions; any visual work uses a vision-capable provider.
- End the phase with REPLAN: the phase's full test run, baseline-plus-ledger comparison and the next stage or final acceptance.
PLAN records initial knowledge itself; there is no mandatory separate knowledge-foundation ticket. Setup/core work uses junior + balanced when moderate; hard authentication/concurrency work uses senior + balanced, pro only for a very critical core. VERIFY and REPLAN normally use senior + balanced. Counts and exact ordering are resolved on the real installation.
4.12 Two ticket descriptions from that plan
Ticket 3 — Application setup (junior_developer, balanced — Moderate):
Objective (R001, R010, R011): create the application foundation for RepairFlow.
- includes/config.php: the canonical bootstrap (env → session → PDO → CSRF → helpers → error handler)
exactly as the project context prescribes. Read DB_* from .env; commit .env.example only.
- database/schema.sql: tables customers, technicians, jobs, job_status_history, job_helpers,
users (roles: owner, front_desk, technician). Money = DECIMAL(10,2). Every table has id,
created_at, updated_at; FKs indexed; ON UPDATE CASCADE everywhere; job_status_history keeps
who/when/from/to (no silent overwrite).
- Create the non-secret seed records needed by the acceptance examples. The login-delivering ticket
owns test-account setup. Store long-lived test credentials only through the approved secrets
procedure and use references; never write passwords in .specs, reports, tickets or knowledge. A
one-check disposable account may appear only in the approved Browser/HttpRequest call and must be
revoked immediately afterward.
- includes/header.php + includes/footer.php with the shared navbar (relative links only),
libs/ copied from /opt/codehero/libs (tailwind, alpine, fontawesome with webfonts).
Owned files: includes/, database/, libs/, webfonts/, .env.example, .specs/003-setup.md
Contracts other tickets rely on:
- jobs.status ENUM('received','in_repair','ready','delivered')
- jobs.deadline DATE = received_at + 14 days (computed on insert by JobService, never by the UI)
- helper functions e(), csrf_field(), csrf_check(), requireAuth(?string $role)
Environment: MySQL at localhost:3306, credentials in the PROJECT DATABASE block.
Preview URL: https://127.0.0.1:{PROJECTS_PORT}/repairflow/
Definition of done:
- php -l passes on every file; schema.sql applied without error; seed rows present (SELECT COUNT).
- Loading the preview URL returns the header/footer skeleton with 0 console errors and 0 requests ≥ 400.
- .specs/003-setup.md acceptance list walked item by item; knowledge stored: schema decisions,
status enum, deadline rule (type: decision) with WHY.
Ticket 4 — [VERIFY] Application setup (different provider family, senior_developer, balanced, parent_sequence = 3, so the platform gives it parent_ticket_id and makes it wait for ticket 3; guides/verify-fix.md is pre-loaded):
cycle 1 · GUIDE: verify-fix.md
You only CHECK. You never edit code and never "improve" anything.
Parent: your parent_ticket_id (codehero_get_ticket on your own id). Its SPEC FILE: .specs/003-setup.md.
Walk the parent's ACCEPTANCE list item by item, run the CORE Section 9 recipe on the preview URL
and the parent's tests (`bash .tests/run.sh 003`). Add your own negative checks: a page without the bootstrap must not exist;
the DB DSN must include charset=utf8mb4; PDO must use ERRMODE_EXCEPTION; a second run of schema.sql
must fail cleanly, not corrupt data; no absolute URLs in header/footer.
A FINDING = a requirement not met or a reproducible bug, with steps, expected, observed.
Style preferences are not findings (one line at the end at most).
No findings → VERIFY: PASS line on the parent's SPEC FILE, report "verified: pass" with evidence.
Findings → create [FIX] tickets for the original builder at YOUR sequence_order — one per finding, or per
small group in the same place, at most 5 (ticket 3's provider; cycle 1 = its role and think mode, then the fix ladder;
no depends_on on you), park with ⏸ WAITING-FOR-ALL-TICKETS #<fix ids>, and re-check the findings yourself when the
fixes reply (cycle 2). Circuit breaker after 3 cycles.
4.13 After creation
Use codehero_get_project_progress (or the Project Progress page) to see the tickets with their roles and providers; codehero_update_ticket to change a ticket's role, provider, think mode or status; codehero_set_ticket_sequence to reorder. The agent will create its own VERIFY, fix, helper and replan tickets during the run — expect the list to grow, and check that each new ticket follows the same rules (Module 5).
Exercises — Module 4
- Import the package from your Module 2 exercise into Plan with AI. Before saying yes, write down three things you would change in the preview and why. Apply them with "changes", then confirm.
- Write the full five-part description for ticket 7 of the RepairFlow plan (the core slice), including the contracts the overdue ticket will rely on.
- The planner offers to run "Customer list page" and "Technician list page" in parallel. Do the file-ownership analysis: list each ticket's files, check the danger files, decide. Show the ownership table.
- Explain, with the scheduler rules of §4.6, what happens to ticket 9 if ticket 7 ends in
awaiting_inputwith a question. What must the operator do? - A colleague hands you a batch where ticket 1 has
depends_on: [1]. What happens when it is submitted, and how do you fix it?
PART V — EXECUTION
Module 5 — What happens when a ticket runs, and how to read it
5.1 The lifecycle of a ticket
┌──────────── retry (≤ max_retries, cooldown) ────────────┐
│ │
open ──► in_progress ──► agent says TASK COMPLETED ──► awaiting_input ──► done
▲ │ (reason: completed | question | error | permission | stopped)
│ │ crash / exception │
│ ▼ │ relaxed: auto-reviewer says COMPLETED
│ failed ───────── past max_retries ──► failed (sticks) │ strict: a human closes
│ │ │
│ └── rate limited ──► open (after cooldown, not counted as a failure)
│
└──────── user or peer reply, "Retry", "Reopen" ──── awaiting_input (a reply re-opens; a parked ticket whose
awaited ticket ended without replying is woken by a watchdog)
stuck = the watchdog judged the conversation an unproductive loop
timeout = max_duration_minutes exceeded
skipped = manual skip; counts as complete for dependencies (timeout does not)
Facts you will rely on:
- The agent never writes
doneitself. Finishing always parks the ticket inawaiting_inputwith a reason; closing is a review decision (automatic in relaxed mode, human in strict). - Reports start with
NEEDS THE USER: yes|noandOPEN ISSUES AND DOUBTS: ...|none. Missing or contradictory headers are sent back once for correction; a second contradiction waits for the user. Peer/helper/worker tickets are closed by their opener, not the auto-reviewer. A live parking dependency keeps its owner parked. Follow the scheduler facts inASSISTANT_CLAUDE.md. - Normal replies wake parked tickets and reach running ones at their next step.
wake=falseis information-only and wakes nobody. A reply to a completed ticket can reopen it; do not send change notices there. - Dependencies need
doneorskipped. A ticket sitting inawaiting_inputblocks everything that depends on it. In a serial plan that means the whole project waits for your answer — by design. - Retries: a crash or provider error returns the ticket to
openup tomax_retries(default 3) with a cooldown; a rate limit is not a failure. A subscription usage limit parks the ticket until the limit resets (one notice, a probe at most every 30 minutes, no retry counted), and a daemon restart or an upgrade never uses up a retry. A ticket you stopped with the kill switch is never overwritten withfailed. - The watchdog checks long-running tickets and asks a sub-agent whether the conversation is truly stuck; the instruction to that sub-agent is to err on the side of continue. Genuine loops become
stuck.
5.2 What the agent sees and can do
The system prompt is the layered assembly of Module 1 §1.6. On top of it the agent has two tool families:
Built-in tools (HeroAgent) — with the policy their own cheat-sheet teaches the model:
| Tool | Use it for | Policy |
|---|---|---|
Read, Write, Edit, MultiEdit | Files | Read before edit; read only the part you need (the map's lines or Grep first, then Read with offset/limit); a file already read in this run is read again only if it changed |
Glob, Grep | Finding files and text | Instead of find / grep via Bash |
Bash | Commands | Last resort — prefer the dedicated tools; foreground only; run_in_background is denied |
ProcessManager | Long-lived services (dev server, API) and long runs to wait for (a full test suite, a build) | Instead of nohup … &; survives the turn. wait = ONE call that returns when the process ends, with its exit code and last lines — never status again and again (one verifier spent ~2.8 M tokens on 95 status checks) |
HttpRequest | API calls, CSRF flows | Instead of curl; sessions persist |
Browser | Functional flows: goto, click, fill, wait_for, get_text, eval, console_logs, network_logs | The only way to test pages; sessions persist across calls |
PageAssert | Structured checks: visible, contrast, no console errors, no broken images | Works without vision |
LogTail | Server logs by named source (nginx-error, php-fpm-8.3, mysql-error, …) | Instead of tail / journalctl (no sudo prompts) |
WebFetch | Reading documentation pages | — |
GetCached | Re-reading a large tool result that was summarized | — |
Platform tools (MCP, codehero_*) — the ones the global context makes mandatory: codehero_knowledge_search / codehero_knowledge_store / codehero_knowledge_list (the knowledge base), codehero_git_operations (backup_snapshot, backup_status, backup_restore, …), codehero_screenshot, codehero_extract_context, codehero_get_guide (opens one of the fifteen on-demand guides), the search tools codehero_search_tickets (exact words in the project's tickets), codehero_codebase_query (where a function or class is defined, with its lines; who calls it — when the Codebase Map is on) and codehero_semantic_search (decisions, messages, specs and code by meaning, Greek or English — when semantic search is on), and the ticket tools codehero_get_ticket / codehero_update_ticket (reply, close) / codehero_create_ticket / codehero_get_project_progress / codehero_start_ticket (forced start). Every MCP result of a ticket agent also carries the messages other tickets wrote to it while it worked. Use the code map and semantic index when available; handle missing or stale results with the core's scoped search/read fallbacks. Do not treat index freshness as proof that a file or change does not exist.
The permission hook sits between the model and every tool call. It enforces the execution mode (Module 4 §4.9), path protection (H5: follow the project's allowed paths and CONTAINER EXECUTION CONTEXT; any permitted additional workspace is inside the container, never on the host; scratch files belong in the project's .tmp/ and custom-service source in its .services/; container routing does not grant permission to edit protected system/platform files, nginx or /opt/services directly), a [WORKER]'s OWNS: line, container routing (a command that would run on the host instead of through crun is refused with the reason, never turned into a question for you), the background-Bash denial, the malformed-edit guard, and loop detection: an identical action repeated three times returns a "you appear to be stuck — stop and rethink" message to the model; at five it hard-stops the approach. Read-only waiting is exempt — polling a ticket, a bare sleep, ProcessManager status, LogTail, or re-reading a growing log with tail / ls / ps (also through crun) — so waiting for a long test run or a parked dialogue is not mistaken for a loop; re-reading the same file with cat / grep still is. On Codex, the reason for any refusal is delivered into the running turn, so the model learns why instead of seeing only "declined". HeroAgent adds per-tool error counters (warn at three consecutive failures, break at five) and a cap of 1000 iterations per run.
Preserve the approved environment_contract in the specification. Ticket instructions describe the project's actual execution environment, project paths, local service ports and secret references; they omit container names, internal container IPs and host-side entry commands. Colocated services use localhost:<verified port>; external services keep their real endpoints. Browser checks use the platform preview URL.
After approval, create the project and its declared platform container and catalog environment through MCP before the planning ticket. nginx is built in and is never declared as an additional service. The planning ticket may discover an approved service gap: its SETUP ticket can install or register it inside the project container under GUIDE: services.md. Missing host runtimes are operator-owned inputs; tickets do not install them.
Destruction, migration, stopping the container, and restoring or deleting a snapshot require the user's explicit yes for the exact operation. For supported container actions, pass user_confirmed=true only after that yes. Never invent a network action or a parameter absent from the live schema.
5.3 The work loop the agent follows (global §5)
- Understand the task (apply the language rule).
- Search the knowledge base — one broad query with the task title, one per component — then read the relevant code.
- Open the SPEC FILE (
.specs/<NNN>-<task>.md), always, even for an easy task: GOAL and STATUS before any code. Open questions → ask now, in one batch, or apply a safe default. (A small change or fix — one concrete thing, no new page, table or feature — runs the light loop: a two-line SPEC FILE, only the guide of the thing touched, verify that thing, run the ticket's own/affected test groups, snapshot, a five-line report. No plan mode, no rounds, no peer.) - Build one small part.
- Verify that part (§5.5). Fails → debugging protocol (§5.6).
- Update the SPEC FILE, then snapshot. After every part, not only at the end.
- Parts remain → back to 4.
- Check the actual changed flow on the PREVIEW URL, run your own tests and the groups affected by the change, then record each ACCEPTANCE item as pass, fail or BLOCKED with evidence. VERIFY runs its parents' groups and its own negative checks. The phase's full suite belongs to REPLAN, or an explicit user request; duration is not the trigger for selecting groups.
- Store knowledge: decisions and failed approaches.
- Report — two lines, then the 4-part handoff (§5.8), then
TASK COMPLETED.
Long task? After a verified part the agent may call codehero_extract_context to compress old messages; the SPEC FILE survives compression and is re-read right after. After any compaction — the Claude CLI's or Codex's own, CodeHero's inside a run, or a new round built from CodeHero's summary — the agent gets the same rule (4.65.9): the summary and the SPEC FILE STATUS are its state, it never re-reads everything, and a gap is looked up only where it lives — its own ticket's history (codehero_search_tickets with its id), the code (semantic search, the code map, grep), the decisions — and a guide only by the SECTION its next step needs (codehero_get_guide(name, section=…)). The platform also compacts automatically when the conversation grows past its thresholds, and shows a visible compaction message in the ticket. This is why P6 (memory on disk) is a principle and not a suggestion: everything the next step needs must already be in .specs/ or the knowledge base.
Since 5.0.0, a ticket agent may fold its own large tool results, calls or messages with codehero_fold and recover needed details with codehero_unfold when folding_enabled permits it. Images are not folded: on API models a screenshot is seen once and then removed from the context automatically (only the agent's description of it stays). API models apply a fold on their next request; Claude print mode, Codex and Grok Build on their next rebuilt run; interactive Claude when its session is rebuilt. Required model reasoning is preserved between runs by the platform. This is ticket-agent memory management; assistants do not configure or operate it for projects, and it is not a reason to copy core instructions into overrides.
5.4 Two memories
SPEC FILE (.specs/NNN-name.md) | KNOWLEDGE BASE (graph) | |
|---|---|---|
| Scope | This task | The whole project, forever |
| Content | GOAL · APPROACH · FILES & CONTRACTS · DATA FLOW · RISKS · ACCEPTANCE · OPEN QUESTIONS · STATUS (live: ✔ done · ▶ doing · ☐ pending · NEXT:) | Nodes: decision, failed_approach, pattern, bug, service, component, class, method, file, library, api_endpoint, config, spec, milestone. Edges: uses, depends_on, fixed_by, calls, failed_for |
| Written when | Before coding, after every part, at the end | The user says "remember"; a command failed then worked (💡 TEACHABLE MOMENT); a non-obvious choice between approaches; architecture designed |
| Read by | The agent after compaction ("if you feel lost, re-read the SPEC FILE first"), the VERIFY ticket, the next ticket | Every ticket at start; the hint system (🚨 known dead ends for a file about to be edited) |
| You read it in | Project Files / File Explorer | codehero_knowledge_list / codehero_knowledge_search from the AI Assistant, and the knowledge snapshot at the top of each ticket's system prompt |
Every failed_approach must have a failed_for edge to the component it hurt (component name = file basename without extension). The next time any ticket edits that file, it sees the dead end. Teach your trainees to check the graph after a run: a project with zero decision nodes after ten tickets is a project whose agents are not following §7 — a context problem, not a model problem. With semantic search on, storing knowledge first lists similar existing nodes, so the agent updates that node instead of adding a duplicate.
5.5 The verification recipe (global §9) — what "evidence" concretely means
- Syntax checks:
php -l,python3 -m py_compile,node --check,tidy. - Browser recipe on the PREVIEW URL:
goto→ exercise the key actions →console_logs(must be 0 errors) →network_logs(no unexpected network response >=400; an intentional application-level 401/403/422 passes only with the corresponding authorized positive control and an explicit expected-result record; a proxy/WAF refusal is not evidence of application authorization) →PageAssert(no console errors, no broken images, key elements visible) →LogTailonnginx-errorandphp-fpm-8.3. - If the project has login: test the logged-in state (UI path and API/CSRF path) AND the refusals with a positive control (
guides/testing.md); the ticket that delivers login creates the test user. - Deliveries need proof: an email, webhook or export is "sent" only with a receipt, a log line, an outbox row or a test inbox. Otherwise "attempted, unverified" or BLOCKED.
- Expected results come from outside the code: the request, the acceptance list, the user. "The function returns 42 and my test expects 42 because the function returns it" proves nothing.
- Every interactive element carries a
data-testid({action}-btn,{field}-input,nav-{page}, …) so that VERIFY tickets on other providers can find it.
Preview-URL rules the agent must not "work around": a 403 on the bare root means the project folder is missing from the URL (per-project auth, expected); a 400 on plain http:// means the scheme is wrong (it is HTTPS). Neither is a bug; both mean "fix the URL and try the same shape again". Never php -S, never another port, never localhost instead of 127.0.0.1.
5.6 The debugging protocol (global §8 + guides/debugging.md)
Snapshot → reproduce once → collect evidence in order (browser console, network ≥ 400, nginx-error, php-fpm, mysql-error) → locate the first point where reality differs from expectation along request → handler → logic → storage → response → page → one hypothesis → one targeted check → fix the root cause → verify (re-run the reproduction, then the full recipe). Maximum five hypotheses; after five: restore the snapshot if things got worse, re-read the SPEC FILE, optionally open a HELPER ticket on another provider, then simplify to the smallest version that works and add pieces back one at a time.
Rules that catch most real incidents: never run the same failing check twice hoping for a different result (that is the loop the hook detects); change one thing at a time; never weaken the WAF, auth, CSRF or validation to pass — bisect the payload and fix the request; a check that was green and is now red is a regression and jumps the queue; "200 but wrong behaviour" is a logic bug in the agent's own code, not the tool; and if the agent can explain why the code behaves as it does but not what the correct behaviour is, that is a missing business rule → stop and ask.
The symptom table in §8 of the global context (blank PHP page → php -l + php-fpm log; 404 on assets → absolute URL; login "works" but logged out → session write/read; form submits, nothing saved → name= mismatch; POST returns 403/406 while the page loads → WAF rule, bisect the payload) is the first thing to teach a trainee who will read transcripts: most "stuck" runs are one of these.
5.7 When the agent stops to ask — and how you answer
The agent asks only for business rules (P3), destructive actions (H7), missing credentials, or the "should I create the tickets?" gate in PLAN MODE. The format is fixed (global §4.1): one to three lines of what it understood and decided, then numbered questions with options and a recommendation, answerable as "1A, 2B, 3 yes". Before asking you, it should have filtered the questions through a HELPER ticket on another provider (P4) and told you in one line what the helper settled.
Your side of the protocol:
- Read the ticket's last message in the Ticket Detail page (or the Telegram notification).
- Answer every numbered question in one reply, in the same numbering. Do not answer technical questions the agent should have decided itself — tell it to decide ("2: your call, record it in the SPEC FILE").
- If the question is a business rule you do not know, get it from the client and record it in the specification's Decision Log too; the package is the source of truth, not the chat.
- Send. The ticket reopens; the agent writes the answer into the SPEC FILE and stores lasting rules in the knowledge base; it must never ask an answered question again. An answer that changes or adds a requirement follows
guides/update.md: one row in the change ledger.specs/000-changes.md(the log every ticket reads first), the active specs, contracts, tests and knowledge updated, and an information-only notice to every unfinished ticket it touches — you never have to repeat the change to each ticket.
If the same question keeps coming back across tickets, the answer is not on disk: check the knowledge base and the project description, and fix that rather than answering again.
5.8 The report: two lines, then four parts
Every finished ticket ends with a report written for you and read by the auto-reviewer. It starts with two lines in English:
NEEDS THE USER: yes — <what>orNEEDS THE USER: no— yes means the next tickets must wait for you: a critical question, a destructive-action doubt, an approval, a failed or blocked part that later tickets build on.OPEN ISSUES AND DOUBTS: <numbered list>ornone— a part that failed, could not be verified, is blocked, or a result the agent is not sure of. Never hidden to get closed (that is faking a check), never invented (empty hedging holds the plan for nothing).
Then four parts, in this order:
- What works now — with the evidence (which test ran, which URL loaded, which screenshot).
- What is waiting for the user — blocked parts with the exact ask (credentials, decisions), one consolidated ask per service.
- What was decided on your behalf — technical choices worth knowing plus every SAFE DEFAULT, each reversible with one line.
- What stays open — known limits, deferred parts, what the next ticket must know.
The self-check before the report. The agent first asks itself: can the reviewer close me and let the run go on? Everything done or recorded (a change it made and wrote down, a bug it fixed, a note for the next ticket) is not an open issue — it goes to parts 3/4. What needs you is yes. A technical doubt is solved before the report: another approach, then ONE helper. So NEEDS THE USER: no always comes with OPEN ISSUES AND DOUBTS: none. A report that says no but lists issues, or has no two lines at all, is sent back by the auto-reviewer once (a 📨 SYSTEM (auto-reviewer) message that says what is wrong) instead of being held for you; a second contradictory report waits for you.
Part 3 is where you spend your attention: each safe default is a business assumption you can overturn with one sentence. Part 2 tells you what to chase from the client. A report without evidence in part 1 is a report to distrust — check the SPEC FILE acceptance list and the screenshot. A report that ends with a polite question ("Should I also…?") means the agent needs you — the guides forbid it precisely because it stops the plan.
5.9 Verification and the repair loop — one verifier owns the episode
- [VERIFY] ticket (different provider family,
senior+ balanced, basic for a trivial/simple parent, pro only for a very critical parent; apply live provider and ledger restrictions —parent_sequence/parent_ticket_id= the builder;guides/verify-fix.mdpre-loaded): walks the parent's acceptance list, runs the recipe and the ticket's own/affected test groups, writes its own negative tests, writes only its own SPEC FILE and test files. Findings are numbered with steps, expected and observed; style preferences are not findings. A group verify names several parents (one ticket after the last of them). - No findings →
VERIFY: PASS · cycle 1on the parent's SPEC FILE, reportNEEDS THE USER: no. The reviewer closes it; the plan goes on. - Findings → only after every check of every parent is done, the verifier creates all the fixes of the cycle together:
[FIX] <parent title> (#<parent id>, cycle 1, k/m) — <the finding>, one per finding or per small group of findings in the same place (at most 5 a cycle — a fixer gets one specific problem, which fits its small context) — the original builder's provider, and role and think mode by the fix ladder (cycle 1 = the builder's own, cycle 2 = one think step up, cycle 3 = senior + pro), at the verifier's ownsequence_order. Several fixes run in PARALLEL when their files are separate (each with anOWNS:line the platform enforces) and SERIALLY (depends_onthe previous fix) when a file is shared. It writesVERIFY: FAIL · cycle 1 · … · fix #<id>on the parent's SPEC FILE, and parks once:⏸ WAITING-FOR-TICKET #<fix id>(⏸ WAITING-FOR-ALL-TICKETS #<id>, #<id>for several). A parked verifier keeps its sequence unfinished, so the fix runs at once and everything behind waits. - The fix fixes only the listed findings, each with a repeatable test that fails before and passes after; a finding it disagrees with is
DISPUTEDwith a proof. When done it writesFIX: done · cycle 1on the parent's SPEC FILE and replies to the verifier (codehero_update_ticket(ticket_id=<verifier>, reply="FIX done — cycle 1 — fix #<id>")) — the reply wakes the verifier. It never creates a verify ticket. - The verifier wakes (cycle 2), re-checks only the findings (plus the acceptance items they touch and the affected parent groups and the verifier's relevant negative checks), and either writes
VERIFY: PASS · cycle 2and reports, or opens cycle 2's fix and parks again. - Circuit breaker: the same part failed three cycles, the same acceptance item failed twice in a row, or builder and verifier disagreed twice on a finding → the verifier stops, writes
CIRCUIT BREAKERon the record, reportsNEEDS THE USER: yeswith both views and the ways out — (a) one more fix cycle, one step higher; (b) a direct repair: you raise the verifier to master + ultra, it repairs only those findings, and a[PEER]of the other provider family re-checks them and gives the PASS; (c) accept or change the criterion (a business decision, also a row in the change ledger); (d) park the part for a later phase — and stays open until you decide (your decision is recorded asUSER DECISIONand a fresh count starts).
The cycle record lives on disk in the parent's SPEC FILE (VERIFY: / FIX: lines, append-only; the last VERIFY: line decides), because every fix is a new agent with an empty memory and the verifier itself may be restarted. When you see a [FIX] appear at the verifier's sequence, do nothing; it is the loop working. When you see the same part fail a third time, expect the breaker and prepare to choose one of its ways out (step 6).
5.10 Helper tickets and the walkie-talkie
Any ticket may open a [HELPER] — on another provider when one is active, otherwise on its own provider, normally senior + balanced, never weaker than the opener; master only on explicit user request — when it is truly stuck (step 8 of debugging), when two approaches failed and it cannot choose, when one design decision blocks everything behind it, or when questions are about to go to the user (the AI-before-human filter). Rules (guides/helper.md): helpers never write files and never create tickets; the ticket that opens a helper closes it (status="closed") before its own TASK COMPLETED; one helper per ticket, carrying all its doubts together. After three exchanges, the owning agent decides a technical issue from the available evidence and records the reasoning. A business decision, scope change, missing input or unresolved required result goes to the user with both views and the concrete decision needed; do not manufacture agreement or a business default. A helper can find an answer that exists in the material and judge a technical trade-off; it can never invent a business fact.
The messaging protocol is simple and the platform does the delivery. codehero_update_ticket(ticket_id=<other numeric id>, reply="...") sends; the platform signs it (📨 FROM TICKET #<id> (<number> · <title>)), so a message without a signature is from a human. A working ticket receives it at its next step — through its own mid-run check, inside the next MCP tool result, or (Claude CLI modes) through a PostToolUse hook — within seconds. Park on one ticket with ⏸ WAITING-FOR-TICKET #<id> (<number> · <title>) — its reply will wake me. For a set whose results are all needed, use ⏸ WAITING-FOR-ALL-TICKETS #<id>, #<id> (<number> · <title>; ...) — all replies will wake me; wake once after all reply or end. Do not use the single-ticket marker with a comma-list of IDs. A ticket that ends its turn with a message still unread is re-opened at once by the daemon. A parked ticket whose awaited ticket(s) ended without replying is woken by a watchdog with a 📨 SYSTEM note, so nothing waits forever.
The platform watches the waiting, in both directions (it records which ticket opened which: created_by_ticket_id). A ticket opened by another — a peer, a helper, a worker, a verifier's fix — that ends its turn without answering its creator is reported to the creator with its final report and "if it has not given you an answer, ask it again — something went wrong", and the creator is woken. When a ticket ends its turn and some ticket is parked waiting for it, that waiter gets a 📨 SYSTEM (waiting-check) note and wakes to ask again (at most twice, then it is left for you) — two tickets waiting for each other can no longer freeze a run. Closed tickets are never woken. A lead of workers parks with ⏸ WAITING-FOR-ALL-TICKETS and is woken once, when the whole set is in.
Information-only messages. codehero_update_ticket(ticket_id=…, reply=…, wake=false) delivers a notice marked ℹ️ FOR YOUR INFORMATION that wakes nobody: a waiting ticket reads it when it wakes for its own reason. A ticket that recorded a change of requirement tells the unfinished tickets this way (guides/update.md).
In the ticket list this looks like: a build ticket in progress, a [HELPER] or [PEER] ticket on another provider with the same sequence number, the two exchanging numbered findings, then the helper closed by its initiator before the initiator says TASK COMPLETED. An open helper left behind after its initiator finished is the initiator's mistake — and it holds every later sequence.
5.11 The replan ticket
The [REPLAN] ticket ends every phase — also the only phase of a small project, where it is the final check. It builds nothing: it reads the baseline plus the change ledger (.specs/000-changes.md), looks at the real project (code, SHOW CREATE TABLE, the pages on the preview URL, the FULL bash .tests/run.sh — the phase's one full run, started first and read alongside) rather than at reports, and writes a comparison table both ways — every due requirement → where it lives and what proves it; everything built → which requirement asked for it — with aligned / missing / wrong / not asked for / unknown / not yet due. Then one of four decisions: ALIGNED → plan the next phase (same rules: contracts, value order, dry run, about ten review rounds, and ALWAYS the peer check); REPAIR NEEDED → a phase of repair tickets (+ their [VERIFY]) ending with a new [REPLAN] — each repair sized like any build (one focused run, ≤ ~12 acceptance items, ≤ ~15 files; a repair that must look at the whole project, such as an inventory of every table or log, is split by area) — no new features until a replan says aligned, and a circuit breaker after three repair rounds on the same requirement; NEEDS THE USER → one batch of questions and stop; BLOCKED → say what is missing. The baseline, ledger and current decisions remain authoritative. Use the planning guide's bounded cross-check for unrecorded owner changes, with scoped ticket search and targeted messages; do not reread whole conversations or silently change the baseline. It does not ask for approval again — the approved plan contained it — unless the scope must change. The last replan of a project is the final check.
5.12 Operator's controls
| Control | Where | Effect |
|---|---|---|
| Send Message | Ticket Detail → message box, or Telegram | Reopens the ticket (if awaiting) and continues the same conversation |
| Pause | ⏸ next to Stop, or /pause [note] | The agent finishes only the step it is doing, stops the processes it started, writes where it is in its SPEC FILE STATUS and parks with NEEDS THE USER: yes — paused; /resume, «συνέχισε» or any message continues it |
| Stop (kill switch) | ⏹ Stop button or /stop | Stops immediately; ticket parks in awaiting_input (reason stopped) and waits for your correction |
| Retry / Reopen | Ticket actions | Returns a failed or finished ticket to open |
| Start now / Force next | Ticket actions or codehero_start_ticket | Forced start: runs the ticket NOW on an extra slot, ignoring its sequence, dependencies, parent and the slot limit; the flag stays (an observer ticket restarts after every reply). A sub-ticket whose parent never ran starts the parent; otherwise the ticket itself — a parked or finished parent is never re-opened |
| Skip | Ticket actions | Marks it skipped — satisfies dependencies |
| Close | Ticket actions or codehero_update_ticket(status="closed") | Sets it to done (there is no separate closed status) |
| Change role / provider / think mode | Ticket edit or codehero_update_ticket | Applies to the next run |
| Restore a snapshot | Git Manager / Backup | Rolls the project files back; an in-place restore first takes a Safety copy of the current state |
| Permission banner | Ticket Detail (semi-autonomous / supervised) | Allow, Deny, or "Approve all similar" |
5.13 Reading a run like an operator — a checklist
For every finished ticket:
- ☐ The report starts with
NEEDS THE USER:andOPEN ISSUES AND DOUBTS:, has the four parts, and part 1 cites evidence you can open (a screenshot, a URL, a test name). - ☐ The SPEC FILE's ACCEPTANCE list is walked; every item is pass or BLOCKED with a reason; nothing was deleted to look green.
- ☐
.specs/STATUS shows the final position;NEXT:is empty or points at the next ticket. - ☐ The knowledge graph gained the decisions and dead ends the ticket mentions.
- ☐ No helper or peer ticket was left open.
- ☐ The snapshot of the final state exists (
backup_log). - ☐ If the ticket asked something: the question is a business rule, not a technical choice; it came in one batch; a helper filtered it first.
- ☐ If a VERIFY ticket produced findings: one
[FIX]per finding (or small same-place group, at most 5) exists at the verifier's sequence (parallel ones withOWNS:lines, serial ones withdepends_on), the verifier is parked on them, and no later sequence started.
Exercises — Module 5
- Create a throwaway project by hand (a project and one build ticket: one PHP page with a form that stores a row). Run it in supervised mode and approve each call. Write down every tool the agent used and which layer of the context told it to use that tool.
- Run the same ticket in autonomous mode. Compare the transcript: find the SPEC FILE creation, the snapshot calls, the verification recipe, the knowledge store, the 4-part report. Mark any step it skipped and cite the global section it violated.
- Deliberately create a ticket whose description omits a business rule (e.g., "apply the discount" without saying how). Observe the stop-and-ask. Answer it in the "1A, 2B" format and watch the reopen. Then check that the answer landed in the SPEC FILE and the knowledge base.
- Create a
[VERIFY]ticket by hand for exercise 1's ticket (different provider family, senior, balanced,parent_ticket_id= that ticket). Read its findings. If it produced a[FIX], check its provider, sequence and the verifier's parking marker against §5.9; watch the verifier wake and re-check. - Trigger the loop detector on purpose (a ticket told to "keep running the failing test until it passes" on a test that cannot pass). Find the hook's message in the transcript and the moment the agent changed approach or stopped.
- Explain to a colleague, using the lifecycle diagram, why a serial plan with one ticket in
awaiting_inputshows all later tickets as "waiting", and why that is correct.
PART VI — CUSTOMIZING THE BRAIN
Module 6 — Building your own logic with the global context and the project context
6.1 The layers, where they live, and who reads them
| Layer | Source file (edit here) | Installed copies | Read by | Scope |
|---|---|---|---|---|
| Global context core | config/global-context.md | /etc/codehero/global-context.md (what the daemon reads on every run) and /opt/codehero/config/global-context.md (the context-defaults API) | The executing agent — loaded from the installed file on every run since 4.66.2 (never copied into a project) | Every project |
| Guides | config/guides/*.md | /opt/codehero/config/guides/ (served by the MCP tool codehero_get_guide; never copied per project, so an edit reaches every ticket at its next call) | The executing agent, on demand by trigger; pre-loaded by the daemon for [PLAN] [REPLAN] [VERIFY] [FIX] [HELPER] [PEER] tickets | Every project |
| Stack sections | config/contexts/<stack>.md | /opt/codehero/config/contexts/<stack>.md | The executing agent — the sections of the project's project_stack, loaded on every run | Every project of that stack |
| User project overrides | — (DB: projects.global_context, projects.project_context, projects.context) | Nothing is copied since 4.66.2: the fields hold only the user's own additions, and reach the agent only while additional_context_enabled is on (later wins: global < app < notes) | The executing agent, as USER PROJECT OVERRIDES, above the platform's defaults | This project only |
| Project description | UI: Project Settings (projects.description) | — | The executing agent | Short mandate, boundaries and run summary; the complete package belongs in PLAN, not projects.context |
| Ticket | UI or MCP (tickets.description, tickets.context) | — | The executing agent | This task |
| Knowledge base | The agents themselves (and you, by telling a ticket or the AI Assistant to "remember" something) | DB graph | Every ticket at start, plus the hint system | This project, evolving |
| Assistant templates | config/assistant-{general,planner,progress,help}.md | /etc/codehero/assistant-*.md | The in-app assistant modes | The assistant, not the tickets |
Four facts decide how a change propagates:
- Since 4.66.2, the installed core and the stack sections selected by
project_stackload on every run; they are never copied into a project.global_context,project_contextandcontextcontain only the user's explicitly requested additions, in the user's words. Do not put the core, a stack section, a guide, a template, an automatically generated project analysis or the specification in these fields. The specification belongs in the planning ticket. - The fields reach agents only when
additional_context_enabledis on. New projects start on; projects present at the 4.66.2 upgrade start off. Overrides apply above platform defaults, in order global < app < notes. - Before clearing legacy content or enabling overrides, read the existing fields, distinguish installed copies from customer additions, show exactly what will change, and obtain the user's confirmation.
clear_context_fields=trueclears global and app context according to the tool schema; do not assume it preserves customer text or clears notes. Preserve confirmed customer additions. There is no refresh-global-context action.codehero_get_context_defaultsis read-only; never copy its result into a project. - Placeholders are resolved on the global context only. Write
{PROJECTS_PORT}and{PROJECT_FOLDER}there; never a literal port. The per-language files carry no placeholders (they use{web_path}only as a name in prose).
Deployment of a context change on a server:
# global: source → installed defaults AND the daemon/assistant copy
sudo cp /home/claude/codehero/config/global-context.md /opt/codehero/config/global-context.md
sudo cp /home/claude/codehero/config/global-context.md /etc/codehero/global-context.md
# per-language: source → installed defaults
sudo cp /home/claude/codehero/config/contexts/php.md /opt/codehero/config/contexts/php.md
# guides: source → installed (read by codehero_get_guide)
sudo cp /home/claude/codehero/config/guides/*.md /opt/codehero/config/guides/
# assistant templates
sudo cp /home/claude/codehero/config/assistant-planner.md /etc/codehero/assistant-planner.md
Installed copies are overwritten by setup.sh / upgrade.sh; keep your customizations in the source tree (or a fork) and re-apply after upgrades. upgrade.sh also replaces /etc/codehero/heroagent.conf (the previous one is kept as heroagent.conf.bak.<date>). While an upgrade runs (5.0.2), from after its backup until its database, settings and services steps are done, no ticket starts; running tickets go on, and waiting ones start right after.
6.2 Which layer for which rule
| Kind of rule | Put it in | Not in |
|---|---|---|
| The method: how to plan, build, verify, ask, report; hard rules; debugging; knowledge; verification doctrine | Global context | A ticket (it would apply to one task only) |
| Stack idioms: the canonical bootstrap, the one way to do sessions/DB/CSRF/uploads in this language, the "silent mistakes" of the language | Language context | Global (it would bloat every project) |
Company-wide conventions that apply to every stack (documentation files, naming, accessibility floor, a required CHANGELOG.md) | Global context, CORE Section 11 and Section 5's record-update step | Language contexts (you would repeat it 16 times) |
| Project description | projects.description | Short mandate, boundaries and run summary; never the complete specification or an override copy |
| Existing-project facts | Project analysis/map and concise project knowledge nodes | Verified structure, conventions and traps; no automatic writes to customer overrides |
| User's explicit persistent additions | global_context / project_context / context, gated by additional_context_enabled | The user's words only, after confirming the requested change |
| Business specification | Complete package in the planning ticket, then the immutable baseline and change ledger maintained by the ticket agent | Other tickets cite authoritative requirements/contracts; knowledge nodes are references and decisions, not a replacement baseline |
| One task's objective, owned files, definition of done | Ticket description | Anywhere else |
A rule in the wrong layer is the most common customization mistake: a client's VAT formula in the global context leaks into every other client's project; a method rule in a ticket is forgotten by the next ticket.
6.3 How the global context is written — and why
The current global context (v6.2: a core plus fifteen on-demand guides, loaded by section; the supplied v6.2 core is 47,535 UTF-8 bytes; guide sizes vary by installed version and should be measured, not copied into a standing rule) is written in simple English so that every model, big or small, can follow it. Since 4.66.0 the core also carries the navigation rules for huge projects (find before you read — the code map, scoped search, a document's headings, long outputs into a .tmp/ log) and the rule that every change the user asks for updates every record that states the old behavior; procedures live in guide SECTIONS that the platform loads or the agent opens. Its conventions are not style; they are what makes weak models comply. Keep them when you add or change rules:
| Convention | Why it works |
|---|---|
| A READ-THIS-FIRST section with a glossary and the six rules in Read this first | Small models weight the beginning of the prompt most; the glossary defines every capitalized term once |
| Numbered hard rules (H1–H10), each one paragraph, each with the failure it prevents | A rule with a number can be cited, checked in a review, and referenced from other sections ("Rule H2") |
| Sections that work on their own, cross-referenced by number ("see Section 8") | After compaction the model may only remember a section number; each section must be usable alone |
| IF … THEN … prose and "Never / Always" only for hard rules | Conditionals are executed; adjectives ("try to be careful") are ignored |
| Tables: symptom → most likely cause → first check | The model matches the symptom it sees and gets a concrete first action |
Examples in real values (WHERE id=? vs WHERE id=$id; .specs/001-login-page.md) | Abstract rules are misapplied; concrete examples are copied correctly |
Placeholders ({PROJECTS_PORT}, {PROJECT_FOLDER} — the two the platform substitutes; <web_path> for values the agent fills in) instead of literal values | A hardcoded port in the context is wrong on the next installation |
| Tool names matched by suffix, "a missing lookup tool is not an error" (a missing creation or verification tool is BLOCKED, never skipped) | Runtimes prefix tool names differently; the model must not stop because a name differs |
| Evidence phrasing ("Done = a test ran, a page loaded, a row exists") | Defines "done" operationally so it cannot be satisfied by text |
| Per-language contexts defer to the global ("loads AFTER the Global Context — all global rules still apply"; "per Global Section 11") | No duplication, no contradiction, smaller prompts |
Size matters. The supplied v6.2 core is 47,535 UTF-8 bytes and is sent with every ticket; a guide is paid only by the tickets that need it; guide sizes vary by installed version and should be measured, not copied into a standing rule. Every paragraph you add to the core is paid on every ticket of every project: a rule for a recognizable situation belongs in a guide, with a trigger row in core Section 2 — never in the core. Run python3 tests/context/check_global_context.py after every edit (references, trigger table, tokens, tables).
6.4 The rule for changing rules
Every hard rule in the global context names the incident it prevents (H2: processes are killed when the turn ends; H3: hand-inserted rows to pass a test; H6: two tickets editing the same file). A rule added "in case" a model might do something has a cost on every ticket and no evidence it helps; and a defensive rule for a hypothetical failure often makes the model over-cautious about the real work. When a trainee proposes a context change, ask for the transcript that shows the failure. No transcript → no change.
The same applies to removing a rule: find the incident it prevents (git history and the CHANGELOG record most of them) before deleting.
6.5 Worked customization 1 — a company convention in the global context
Observed failure: three projects delivered without any change log; the client's IT could not tell what a ticket had changed.
Change: in CORE Section 11, add CHANGELOG.md to the list, and in Section 5's record-update step add one line: "Append one line to CHANGELOG.md: ticket number · date · what changed." Two sentences, in the two sections where the model already looks for documentation duties. Not a new hard rule (a missing changelog is not a safety failure), not a new section.
Test (§6.10): a probe project on the weakest active model; after one ticket, CHANGELOG.md exists with one line.
6.6 Worked customization 2 — a stack variant (Laravel instead of plain PHP)
The PHP context prescribes plain PHP with PDO and a canonical includes/config.php. A client's team maintains Laravel projects and wants CodeHero to follow their conventions.
Two ways, and you must know both:
- Per project (no platform change). Create the project with its stack (
project_stack=["php", "mysql"]) and put ONLY the difference inproject_context, in the team's words — e.g. «This is a Laravel project: artisan commands,routes/web.php, Eloquent + migrations, Blade layouts,php artisan test; ignore the plain-PHP bootstrap and page pattern». The agent reads it as a USER PROJECT OVERRIDE, above the PHP section. Never paste a copy of the PHP section or the core there: since 4.66.2 those load from the installed files on every run, and a copy is refused. - A new stack file for every future project. Add
config/contexts/laravel.md. Note that the stack-to-file mapping is code (context_mapinscripts/mcp_server.pyand the matching map inweb/app.py), so a newtech_stackvalue needs a small developer change in both maps plus the UI option; an unmapped stack silently falls back tophp. Until the map is extended, use the per-project route.
Whichever route, the file must keep the header line that states it loads after the global context and defers to it, and it must not restate global rules (relative paths, security, libraries) — reference "Global Section 11" instead.
6.7 Worked customization 3 — the project context of an imported legacy project
For an imported project, run codehero_analyze_project and record verified structure and conventions in its map and project knowledge. Put the user's requested change and accepted existing behavior into the planning handoff; preserve the baseline under case D. Write a persistent override only if the user explicitly asks to retain that rule, in their words, after showing the proposed field change. Do not promote an agent's inferred architecture or test recipe into user overrides.
6.8 Worked customization 4 — an API-only project
An HTTP API follows GUIDE: verification.md and GUIDE: testing.md: real requests through the prescribed preview route, persistence/response readback, authorization and validation refusals with positive controls, bounded logs and the affected test groups. An API with no UI does not need a new Browser flow. Native/non-HTTP products follow GUIDE: native.md for the applicable checks.
Put project-specific endpoints, expected results and actual test commands in ticket acceptance and authoritative contracts. Do not write a replacement platform verification procedure into user context fields. A missing or different verification tool is handled by the installed guides, not by an invented api context or core Section 15.
6.9 Worked customization 5 — client business rules
Wrong: adding "VAT is 24% and applies to net, rounded half-up" to the global context.
Right: keep the business rule and worked example in the unchanged specification carried by PLAN, then its baseline/change ledger and authoritative contract. The planning ticket records the decision in project knowledge and gives each affected ticket its requirement/acceptance references. The project description contains only a short mandate.
6.10 Testing a context change — the protocol
- Diff and size.
diffagainst the previous version; check the file size change. A change that adds more than a few hundred bytes needs a reason. - Keep the version header. The global context's first line names its version; bump it and add one line to the note under it saying what changed and which failure it fixes.
- Deploy to the installed paths (§6.1). No restart needed.
- Test both a new and an existing disposable project. Confirm the next run loads the new installed instruction file; user context fields remain empty or retain only the customer's additions. Check the resolved preview URL in the actual assembled prompt without exposing credentials.
- Run a probe ticket twice: once on your strongest provider, once on the weakest model you actually use for
junior_developer. The rule must survive the weak one; if only the strong model follows it, rewrite it (shorter, IF/THEN, an example in real values). - Inspect only the specific instruction section needed to confirm loading. Use a redacted or bounded non-secret view of the assembled prompt; never print or attach its database/service credentials, protected paths' values or the complete prompt. Record the instruction source/version and presence once, without credential content.
- Read the transcript for the behaviour, not the words: did the agent do the thing (the file exists, the check ran), or did it say it would?
- Installed instruction changes reach existing projects on their next run. Do not refresh or paste core/stack text into project fields. Test
additional_context_enabledseparately with a small explicitly authorized user override, preserving preexisting customer text. - Record the change in the repository's CHANGELOG with the incident it fixes.
6.11 Anti-patterns (each one seen in a real run)
| Anti-pattern | What happens | Fix |
|---|---|---|
Contradicting a hard rule from a lower layer ("in this project, you may use git directly") | The model follows whichever it read last, unpredictably | Never contradict H1–H10; change the global if the rule is wrong for everyone |
Literal port or IP in a context (https://127.0.0.1:9867/…, 10.0.3.5) | Wrong on the next installation; container agents try to reach the IP | Placeholders in the global; localhost:<port> from the services block |
| The word "container" in a ticket or project context | The agent starts running lxc/docker commands and breaks | Omit container names, internal container IPs and host-side entry commands from ticket instructions; retain the truthful environment contract and obey the supplied execution context. A container SETUP may close approved service gaps through GUIDE: services.md; host system installation remains an operator input. |
| A rule with no example ("use good security practices") | Ignored by small models, over-interpreted by large ones | One concrete example in real values, one negative example |
| A preventive rule for a failure nobody observed | Costs tokens on every ticket; often makes the agent hesitant on the real work | §6.4: no transcript, no rule |
| Duplicating global rules in a language context | Drift: the two copies diverge after the next global edit | Cross-reference by section number |
think_mode: ultra as a project default | Every trivial ticket burns the maximum thinking budget | balanced default; senior + balanced for normal chain work; documented escalation only |
Referencing a tool that does not exist in this runtime (Screenshot as a built-in) | The model stops or invents | Use the MCP tool names; the global already says "match by suffix; a missing tool is not an error" |
| Business rules in the global context | They leak into every other client's project | Keep the business rule and worked example in the unchanged specification carried by PLAN, then its baseline/change ledger and authoritative contract. The planning ticket records the decision in project knowledge and gives each affected ticket its requirement/acceptance references. The project description contains only a short mandate. |
| A ticket that says "as we discussed" | The executing agent was not in the discussion | Self-contained ticket (Module 4 §4.8) |
6.12 Customizing the planner and the assistants
The same discipline applies to config/assistant-planner.md and the other assistant templates: they are read per session, they are concatenated with the global context (except help), and they carry hard rules at the top. Typical legitimate customizations: a company default strategy (eco), a house rule for provider families in verification, extra preview columns, a different default execution mode for a training installation. Illegitimate: removing the preview-and-confirm gate, allowing inactive providers, making parallel the default. Each of those undoes a principle of Module 1.
Exercises — Module 6
- Take the customization of §6.5 and apply it to your training installation following the §6.10 protocol end to end. Attach: the diff, a redacted excerpt of only the changed instruction section, containing no credentials, the transcript line where the agent writes
CHANGELOG.md. - Write a per-project context for a Node/Express project that must use an existing company middleware package for auth. Show which global sections you cross-reference instead of restating.
- Inspect a legacy project's disabled override fields. Identify old installed copies and genuine customer additions. Propose and confirm a cleanup that preserves those additions; demonstrate installed-file loading and the override switch without copying defaults into the fields.
- A trainee proposes adding "Always double-check your work before finishing" to the global context. Argue for or against using §6.3 and §6.4, then propose a version that would actually change behaviour (hint: it already exists — find it).
- Write a rule for the global context that would have prevented this observed failure: "The agent reported an email as sent; the SMTP credentials were placeholders; nothing was sent." Then find the sentence in the v6.2 core that already covers it and compare wording.
PART VII — REACHING A WORKING RESULT
Module 7 — Delivery discipline: from the first ticket to a verified, documented product
7.1 What "working result" means in ADF
Not "the code is written". A working result is: the agreed scope runs on the preview URL (and later on the production domain), every acceptance criterion has evidence linked to it, every business rule was confirmed by the client and is stored where the next ticket finds it, the blocked parts are listed with their exact asks, and the documentation the client agreed to exists in their language. The framework gets you there by ordering the work so that the riskiest unknowns are resolved first and the evidence accumulates as you go.
7.2 The opening sequence: setup → access gate → core slice
| Ticket | Purpose | Proof it produces |
|---|---|---|
| Application setup | PLAN records architecture and decisions in project knowledge itself. The first SETUP ticket checks capabilities and application/service readiness; create a separate discovery probe only when the approved scope actually requires one. Follow with the thinnest useful confirmed flow, not a fixed quota of foundation tickets. | Schema applied, seed rows counted, skeleton page loads with 0 errors |
| Access gate | The thinnest slice through the real path: login → one protected page → on the preview URL (and, for production deliveries, through the real domain/proxy once it exists) | Screenshot of the logged-in page; PageAssert green; logs clean |
| Core slice | The product's purpose end to end (e-shop: product page → cart → checkout; RepairFlow: create job → change status → deliver) | The acceptance scenarios of the main process pass, with negative tests from the VERIFY ticket |
Only after the core slice is verified do secondary features start (wishlists, branding, dark theme, extra reports). If a client pushes for the logo first, show them this table: the logo cannot fail; the checkout can.
7.3 Milestones and the replan cadence
The Spec Builder proposes value-ordered outcomes and optional candidate cards. The planning ticket sizes and schedules the actual phases on the installation; counts are estimates, not quotas. Each planned phase ends in REPLAN. Verification follows risk, size, approved pace and provider eligibility; the package does not prescribe a separate verification ticket after every contract or feature.
7.4 Contracts before code
Write each shared contract once in its authoritative numbered file before creating its consumers. Consumer tickets name exact sections/versions and their owned SPEC FILEs; concise excerpts are labeled references, not independent definitions. The planning ticket creates contract files and knowledge decisions itself. Separate contract/revalidation tickets are not an automatic chain. Update the current contract and every affected record under the change process, preserving history and invalidating affected evidence.
7.5 Evidence and the acceptance manifest
Every acceptance criterion in the package ends with evidence: requirement version, code revision, test ID, environment. The Evidence column of the requirements register is filled only from real test output — never from a ticket's prose. In CodeHero terms: the VERIFY ticket's report, the screenshots (codehero_screenshot), the PageAssert results and the test-runner output are the evidence; the SPEC FILE's ACCEPTANCE list is where the agent records pass / fail / BLOCKED per item.
Two honesty rules the trainer must insist on: a BLOCKED item is visible and never counted as pass; a passive security scan's clean result records what was scanned, not "no problems exist".
7.6 Day-0, touchpoints, and how to keep the client out of the build loop
Before the run: collect the day-0 pack (Module 2 §2.12). During the run: owned inputs and the approval/contact gates defined in §2.12. Everything else is your job as operator: answer technical questions the agent should have decided (tell it to decide), chase the client only for genuine business decisions, and keep the specification's Decision Log in sync with every answer you relay. A run that stops daily with business questions has an incomplete specification; a run that stops daily with technical questions has a context problem (Module 6); a run that never stops but delivers wrong behaviour has a verification problem (Module 5 §5.9).
7.7 Circuit breakers — when the framework stops itself
| Breaker | Trigger | What you do |
|---|---|---|
| Verify/fix loop | Same part failed three fix→verify cycles; same acceptance item failed twice; builder and verifier disagreed twice | Read both views (the verifier's record lines and the fix ticket); choose one of the verifier's ways out — one more cycle, a direct repair by the verifier (raise it to master + ultra) confirmed by a [PEER] of the other family, accept / change the criterion, or park the part; reply to the parked verifier |
| Replan repair loop | The same requirement still not aligned after three repair rounds | Read the replan's comparison table and the repair tickets; decide whether the baseline or the code is wrong; reply to the replan |
| Debugging | Five failed hypotheses (after a helper was consulted) | Read the SPEC FILE's hypotheses; often the missing piece is a business rule, not a bug |
| Loop detector | Identical actions repeated | The hook already nudged the agent; if it hard-stopped, read the last tool calls, fix the ticket text or the environment, retry |
| Helper dialogue | Three exchanges without agreement | After three exchanges, the owning agent decides a technical issue from the available evidence and records the reasoning. A business decision, scope change, missing input or unresolved required result goes to the user with both views and the concrete decision needed; do not manufacture agreement or a business default. |
| Fallback | Ticket #0 cannot provide the runtime | The fallback changes an agreed capability → requirements change with the client, one line per affected requirement |
| Watchdog | Long unproductive run | Ticket marked stuck; read, correct, retry |
The breakers are not failures of the framework; they are the framework refusing to burn money on a problem that needs a human.
7.8 Documentation deliverables
Always, in the client's language: a user manual per role, an administrator guide, an operations/hosting guide (install, upgrade, backup, restore, monitoring), API documentation when an API exists, and a Decisions document listing everything decided for the client. Inside the project the agent also maintains technologies.md, map.md and the .specs/ files. The ticket that completes a role's flow writes that role's help. The last build drafts handover material; the final check completes docs/acceptance.md and docs/handover.md with real evidence. Do not create standalone documentation tickets merely to fill a template.
7.9 From preview to production
The preview URL is where the agents work. Going live is an operator task, done with the platform's tools and documented in the User Guide:
| Step | Where | Notes |
|---|---|---|
| Domain and SSL | Project → Production Deployment; Settings → Domains | Let's Encrypt or custom certificates; the production config is generated per project |
| Web application firewall | WAF setup (see the WAF guide) | Keep it on; the agents are trained to bisect payloads, never to weaken it |
| Backups and restore drill | Project → Backup & Restore; container snapshots | The specification asked for a restore drill executed once — do it before go-live, not after |
| PHP settings | Project → PHP Settings | Development tuning (errors visible, opcache revalidate) vs production values |
| Secrets | Project → 🔐 Secrets (the project's .secrets/, or the host secrets folder for more protection), never in code | Real SMTP, payment and API credentials replace the day-0 placeholders here, each key with its kind; kept out of git, ZIP backups and exports; the secrets filter keeps protected values from the AI provider, and agents use them by path |
| Security gate | Applicable CodeHero security episode and its recorded verdict; external pentest only if requested or required by policy | An agreed external test stays external-pending until evidenced, and blocks go-live only when the customer's confirmed policy/contract requires it. Apply the approved demo exceptions without claiming production readiness. |
7.10 The operator's daily checklist
- ☐ Tickets in
awaiting_input: reason? question → answer in one batch; permission → allow/deny; completed (strict) → review the report and close; stopped → correct and retry. - ☐ Tickets in
failedpast retries orstuck: read the last messages, fix the cause (ticket text, environment, credentials), retry. - ☐ Helpers and peers left open by finished tickets: close and note.
- ☐ Count completed failed repair cycles in the verifier's append-only record, not FIX ticket count. The initial finding is not a failed repair. Stop after the same part fails three completed repair cycles, the same acceptance item fails two repairs in a row, or two disputes on one finding, as GUIDE: verify-fix.md specifies.
- ☐ The replan ticket of the phase: read its plan before it runs if you want scope changes.
- ☐ Knowledge base growth: decisions and dead ends are being stored (a flat graph after many tickets = context problem).
- ☐ Snapshots exist for each finished ticket; the latest restores cleanly (test it once per milestone).
- ☐ Day-0 items still missing: chase the client; BLOCKED items depend on them.
7.11 A catalogue of real failure patterns and what they mean
Every item below happened in a real run. Learn to recognize them from the transcript.
| What you see | What it means | Where the fix belongs |
|---|---|---|
| The agent claims a page works; the screenshot shows a 500 | A tool hid the error (blank body, stale log); the agent trusted text | Verification recipe (LogTail, php -l); newer tool versions surface the error automatically |
| The agent "forgot" the plan mid-ticket and rebuilt something | Context compaction without a current SPEC FILE, or a model window smaller than the configured limit (silent truncation) | Check the provider's real context window vs the configured limit; enforce §6 (SPEC FILE current after every part) |
| Ticket ends its turn "to wait for the build" and everything dies | H2: processes are killed at turn end; run_in_background is now denied by the hook | Ticket text should not ask for background runs; ProcessManager for services |
| A ticket asks "which framework should I use?" | Type-1 technical question the agent should decide | Answer "your call, record it"; if frequent, the context is unclear about the default stack |
Two parallel tickets both edited header.php | Parallel approved without the ownership analysis, or ownership lists missing from the descriptions | Serialize; H6; ownership table in the plan |
Ticket text mentions codehero-12 or 10.0.3.x | Infrastructure leaked into the ticket | Omit container names, internal container IPs and host-side entry commands from ticket instructions; retain the truthful environment contract and obey the supplied execution context. A container SETUP may close approved service gaps through GUIDE: services.md; host system installation remains an operator input. |
| The verifier "fixed" the code | The ticket title lost its [VERIFY] prefix, so the verify-fix guide was not pre-loaded | Keep the prefix; the guide says "you only CHECK" |
A finished helper ticket still open | Initiator forgot to close it | Close; it is in the initiator's checklist |
A ticket stays awaiting_input for days and nothing behind it moves | It asked you something (NEEDS THE USER: yes) or waits for another ticket; a later sequence never starts until it is done | Read the awaiting reason and resolve the actual question/permission/failure. Close only completed, evidenced work; never close an unanswered blocker to make later tickets run. |
| Every ticket burns the maximum thinking budget | ultra set as project default | balanced default; ultra per ticket |
| Weak model loops on an easy PHP task | Tools hid a PHP 500; loop detector saw A/B alternation | Verification recipe first; the hook now catches cycles, not only identical repeats |
| Reviewer closed a ticket that actually asked a question | Strict/relaxed confusion, or the question was buried under "TASK COMPLETED" | The reviewer now treats a flagged problem as ERROR; teach the agent's ask format (question first, marker last) |
Exercises — Module 7
- Take the RepairFlow plan of Module 4. For each of the first five tickets write the proof it produces (a sentence naming the artefact you would open to check it).
- Write the day-0 pack for RepairFlow in the client's language, and the four-reason contact list as you would send it to the owner.
- Simulate a breaker: a VERIFY ticket reports "deadline computed as +15 days", the fix ticket replies "the spec says 14 business days" (DISPUTED), the verifier re-checks and disagrees again. Write the message you send to the parked verifier, and the line you add to the Decision Log.
- Assign each RepairFlow role's documentation to the ticket that delivers its flow, and identify who drafts and who verifies the final handover.
- Pick three rows of the failure catalogue and find the exact sentence in the global context (or the planner) that exists because of them.
PART VIII — CAPSTONE
Module 8 — The capstone project and the assessment
8.1 The assignment
In pairs (one plays the client, one the developer; then swap), deliver a small internal tool end to end within one working day:
- Interview the client with the Spec Builder (Module 2). Deliver a Ready for active-scope construction package — its active requirement IDs and readiness evidence stated, not assumed — with at most one non-critical Assumed item. The tool must have: two roles, one entity with at least three states and history, one business rule with a number (a deadline, a limit or a formula), one notification, one export or printout.
- Justify the stack (Module 3): the one-line decision, the environment block, and the answer to "why not a container?" (or "why a container?").
- Plan it in IMPORT MODE (Module 4). Before confirming, produce a written review of the preview: three changes you made and why.
- Run phase 1 (Module 5) in relaxed autonomous mode. Answer every question the run raises within the "1A, 2B" format. Keep the Decision Log in sync.
- Customize one thing (Module 6) that the run showed was needed — with the transcript that proves the need, the diff, the §6.10 test.
- Deliver (Module 7): the core slice verified on the preview URL by a VERIFY ticket on a different provider family; the 4-part handoff for the client; the documentation for delivered flows exists, and acceptance/handover record the actual evidence and owned gaps; the day-0 items listed.
8.2 The rubric
| Area | Pass | Distinction |
|---|---|---|
| Interview | Every stage covered or consciously defaulted; four statuses used; critical items never Assumed; Stage P preview done | Client's own numbers appear in every business rule's example; dependency register has verification statuses; spreadsheet intake applied |
| Stack | Correct default (PHP/MySQL unless a trigger fires); justification cites a requirement ID | Fallback stack reasoning correct; build vs runtime vs serving declared separately |
| Plan | Serial, probe → knowledge → setup → access gate → core slice; roles and think modes by ticket kind and difficulty (§4.4); VERIFY tickets on a different family; the plan agreed with a peer; descriptions follow the five-part recipe | A parallel group offered and correctly analysed, or correctly refused with the ownership reason |
| Run | Every question answered in one batch; no technical question answered by the human; helpers closed; snapshots exist | A breaker occurred and was arbitrated correctly; a safe default was overturned via the report's part 3 |
| Customization | Observed failure → rule → deployed → tested on a weak model → transcript proves behaviour | The rule is in the right layer, cross-references the global, and adds under 300 bytes |
| Delivery | Core slice acceptance list all pass or BLOCKED with reason; 4-part handoff; documentation for delivered flows exists, and acceptance/handover record the actual evidence and owned gaps | Restore drill performed; production steps listed; the client can read the handoff without you |
8.3 Self-assessment quiz
Answer without looking; then check against the referenced sections.
- Name the two kinds of unknowns the agent meets, and who decides each. (Global §4)
- What does the agent do when a CRITICAL question has no answer and the run is autonomous? (Global §4.1,
guides/asking.md) - Which ticket statuses satisfy a dependency? Does
awaiting_input? Doestimeout? (Module 5 §5.1) - Give the three settings every VERIFY ticket must have, where its fix ticket goes, and one thing it must never do. (
guides/verify-fix.md) - What is the shipped default of
MAX_PARALLEL_TICKETS_PER_PROJECT, and what does that mean for a plan where two tickets share asequence_order? (Module 4 §4.6) - Why does the Spec Builder never name a provider or a model? (Planning Guide §1.2, §7.5)
- Which four things does the
codehero_environmentblock declare separately, and which one alone decidescontainer_required? (Module 3 §3.6) - Where does a client's VAT rule belong, and where does it not belong? (Module 6 §6.2)
- What are the four parts of the handoff report, and which part contains the safe defaults? (Global §5 step 10)
- A ticket's last message is
⏸ WAITING-FOR-TICKET #418. Ticket 418 is still running. What does the auto-reviewer do? (Module 5 §5.1) - Name three "danger files" the ownership analysis checks by name. (
guides/planning.md§2) - Which file does the agent re-read first when it feels lost after compaction? (Global §6)
- What is the difference between a SAFE DEFAULT and a guessed business rule? (Global §4.1,
guides/asking.md) - Why must ticket instructions omit container names/internal IPs while retaining truthful deployment and execution-context facts? Explain the approved SETUP service-gap exception.
- A trainee wants to add a rule "always be careful with money". What do you ask for first? (Module 6 §6.4)
- A build ticket at sequence 3 is left
awaiting_inputby the reviewer. Can a ticket at sequence 4 start? Can a forced ticket at sequence 9? (Module 4 §4.6) - Which two lines open every agent report, and what does the reviewer do with each? (Module 5 §5.8)
8.4 Certification checklist
A developer is ready to run client projects unsupervised when they can:
- ☐ run a Spec Builder interview and review its package with the Module 2 checklist;
- ☐ state the stack decision and its justification for any of the eight mini-cases without notes;
- ☐ read a planner preview and find the three most common defects (wrong verify provider, visual work on a text-only provider, missing dependency);
- ☐ answer an agent's question batch correctly (business only, one batch, Decision Log updated);
- ☐ recognize the twelve failure patterns of Module 7 from a transcript;
- ☐ change a context rule following the §6.10 protocol and show the transcript that proves it worked;
- ☐ explain the twelve principles to a client in plain language.
APPENDICES
Appendix A — Quick reference cards
A.1 Ticket fields
| Field | Values | Default |
|---|---|---|
sequence_order | Integer; distinct ascending for serial, same value for approved parallel | Optional in schema; planning policy supplies it explicitly |
depends_on | bulk call: 1-indexed positions of the same call, earlier only · single create: existing ticket ids or ticket numbers | none |
parent_sequence / parent_ticket_id | earlier position / existing ticket id | none |
ai_model | master_developer · senior_developer · junior_developer | project default |
provider | an active provider | project default |
model | a model the ticket's provider lists (codehero_get_model_table) | the role's default model |
think_mode | off · fast · basic · balanced · pro · ultra | Normally balanced; follow ticket-kind policy |
execution_mode | autonomous · semi-autonomous · supervised | Always pass the approved execution_mode explicitly. |
deps_include_awaiting | 1 relaxed (the auto-reviewer closes clean tickets) · 0 strict (you close each) | Always pass the approved deps_include_awaiting explicitly: true relaxed, false strict. |
ticket_type | feature · task · bug · debug · rnd · improvement · docs | task |
priority | low · medium · high · critical | medium |
is_forced | 1 = forced start (Start Now / Force Next / codehero_start_ticket): starts now, ignores sequence, dependencies, parent and slots | 0 |
created_by_ticket_id | set by the platform when a ticket agent creates the ticket (peer, helper, worker, fix): its creator is told if it ends without replying | none |
The is_forced and created_by_ticket_id rows describe stored fields; they are not create_ticket parameters.
A.2 Ticket statuses
open (eligible) · in_progress (agent running) · awaiting_input (parked: completed / question / error / permission / stopped / deps_ready) · done (also what "close" means — there is no closed status) · failed (retries exhausted) · stuck (watchdog) · timeout · skipped (counts as complete). In ordinary scheduling, a higher sequence starts only when every lower one is done or skipped.
A.3 Roles and think modes per ticket type
Size first: a small existing change uses one ordinary build ticket, plus verification when provider restrictions require it. A simple new build (about three screens or fewer, one user type, no login, money, integration or personal data) uses one build and one other-family VERIFY. Larger work uses the approved specification and one PLAN ticket; only that ticket designs and creates the work phases.
A small plan has up to about five work tickets, two review groups, a closing VERIFY and REPLAN, and a peer for applicable risky work. A real plan uses up to ten review groups, a peer and phases of about ten tickets ending in REPLAN. Fast pace uses fewer groups; ultra-fast is an explicitly requested demo with disclosed omissions. Counts are limits or estimates, not quotas. Provider rollout restrictions apply at every pace.
PLAN, REPLAN, PEER, VERIFY and HELPER normally use senior_developer + balanced; a peer/helper is never weaker than its opener. pro is for a very critical core or the documented failure escalation. Work is junior_developer by difficulty: trivial off, very simple fast, simple basic, moderate balanced; hard work is senior + balanced. master_developer is only on explicit request. ultra is never a project default and is not an automatic chain-ticket setting.
FIX cycle 1 uses the builder's role and think mode; cycle 2 goes up one think step; cycle 3 uses senior + pro, never below the builder. Security episodes use senior + pro; performance episodes use senior + balanced, with the specified critical-SLA exception. Release work is senior_developer + balanced (GUIDE: release.md). The planning ticket applies the current guides, pace exceptions, eligibility and user choices.
A.4 The agent's tools
Built-in: Read Write Edit MultiEdit Glob Grep Bash ProcessManager HttpRequest Browser PageAssert LogTail WebFetch GetCached. Platform (MCP): codehero_knowledge_search/store/list/delete · codehero_search_tickets · codehero_codebase_query (map on) · codehero_semantic_search (semantic search on) · codehero_git_operations · codehero_screenshot · codehero_extract_context · codehero_get_guide · codehero_get_ticket update_ticket (reply, status) create_ticket list_tickets bulk_create_tickets get_project_progress start_ticket · codehero_get_project get_providers_info · codehero_container_operations · codehero_codebase_status.
A.5 The global context, by section
Core: 0 Read this first (glossary, six rules) · 1 Language rule · 2 Guides: the trigger table · 3 Hard rules H1–H10 · 4 Decide alone vs ask (4.1 asking, safe defaults, blocked) · 5 The work loop (+ the light loop for a small change) · 6 The SPEC FILE · 7 Knowledge base · 8 When something fails · 9 Verification (9.1 nothing internal downloadable, 9.2 repeatable tests) · 10 Git backup · 11 Code rules · 12 Messages between tickets · 13 Environment & paths · 14 Final checklist. Guides: planning · verify-fix · asking · update · helper · debugging · frontend · database · build · testing · verification · coding · native · services · release.
A.6 Walkie-talkie
Send: codehero_update_ticket(ticket_id=<other numeric id>, reply="...") — the platform signs it 📨 FROM TICKET #<id>. Receive while running: 📨 INCOMING MESSAGE at the next step (own check, MCP result, or CLI hook). Park on one ticket with ⏸ WAITING-FOR-TICKET #<id> (<number> · <title>) — its reply will wake me + TASK COMPLETED. For a set whose results are all needed, use ⏸ WAITING-FOR-ALL-TICKETS #<id>, #<id> (<number> · <title>; ...) — all replies will wake me; wake once after all reply or end. Do not use the single-ticket marker with a comma-list of IDs. An awaited ticket that ends without replying triggers a 📨 SYSTEM wake-up. Ended with a message unread → re-opened at once. Close a helper you opened: codehero_update_ticket(ticket_id=<helper>, status="closed"). A ticket you opened that ends without answering → its report + "ask it again". Parked for a ticket that is now waiting too → 📨 SYSTEM (waiting-check). Information only: reply=…, wake=false (wakes nobody).
Appendix B — File map
| Purpose | Path |
|---|---|
| Global context (source / installed defaults / daemon+assistant copy) | config/global-context.md / /opt/codehero/config/global-context.md / /etc/codehero/global-context.md |
| Language contexts | config/contexts/*.md → /opt/codehero/config/contexts/ |
Guides (on demand, codehero_get_guide) | config/guides/*.md → /opt/codehero/config/guides/ |
Repeatable-test runner (installed as .tests/run.sh in every project) | libs/tests/run.sh → /opt/codehero/libs/tests/run.sh |
| Walkie-talkie hook (Claude CLI modes) | scripts/message_hook.py |
| Context updates | Installed instructions load on every run; refresh-global-context actions were removed |
| Context checkers | tests/context/check_global_context.py · tests/context/check_test_runner.py |
| Spec Builder knowledge file | docs/CODEHERO_PLANNING_GUIDE.md (served at /docs/CODEHERO_PLANNING_GUIDE.md) |
| Assistant templates | config/assistant-*.md → /etc/codehero/assistant-*.md |
| Provider ↔ role model map, think budgets, sub-agent roles | heroagent/heroagent.conf (synced to /opt/codehero/heroagent/ and /etc/codehero/) |
| Provider API keys | /etc/codehero/api_keys.conf |
| System settings (ports, parallelism, cooldowns, context thresholds) | /etc/codehero/system.conf |
| Daemon / MCP server / permission hook | scripts/claude-daemon.py · scripts/mcp_server.py · scripts/permission_hook.py |
| Agent and tools | heroagent/heroagent.py · heroagent/tools/ · heroagent/providers/ |
| Per-ticket assembled prompt and conversation (only while the run lasts; never in a backup) | <work_path>/.heroagent/context_<ticket>.tmp · <work_path>/.heroagent/conversation_<ticket>.json |
| Project SPEC FILES and docs | <work_path>/.specs/*.md · technologies.md · map.md |
| Web projects / app projects | /var/www/projects/<slug> · /opt/apps/<slug> |
| Local libraries | /opt/codehero/libs/ |
| Logs | journalctl -u codehero-daemon · /var/log/codehero/daemon.log · /var/log/codehero/web.log |
Appendix C — Reading list (in order)
config/global-context.md— read it twice; it is the framework. Thenconfig/guides/planning.md,verify-fix.md,helper.md,asking.md— the situations.docs/CODEHERO_PLANNING_GUIDE.md— Parts 1, 2, 3 and 7 first; Parts 4–6 as reference.config/assistant-planner.md— short; read it before your first import.config/contexts/php.md— the reference language context; then the context of your stack.- User Guide chapters 8 (Execution Modes), 9 (Sequencing), 11 (Lifecycle), 13–16 (providers, roles, think mode, vision), 31 (Containers), 32 (Production).
docs/SMARTCONTEXT.md— how compaction works and why the SPEC FILE exists.CHANGELOG.md— the incident history behind the rules.- The presentation The Domain Expert's Software Factory — the same method told to the client's side; useful before Module 2's interview exercise.
CodeHero Developer Training v1.10 — reviewed against CodeHero PRO 5.0.2, Global Context v6.2 and Spec Builder 1.28, 2026-10-15. Current framework files take precedence over this course.
Questions people ask
All the articlesAm I tied to one AI company?
No. CodeHero works with many AI companies at once and with models on your own hardware. You can change company or model at any time — the project, its rules and its history stay. Read the article
Do my passwords and keys reach the AI company?
No. Passwords and keys you store as secrets are used by your application, but their values are never sent to the AI service. Read the article
Why do several AIs work on the same job?
Because one AI does not catch its own blind spots. In CodeHero one model builds and a model from a different company checks; problems go back for repair and are checked again. Read the article
How does CodeHero compare with other AI coding tools?
It is a different kind of thing. Coding tools help a person who writes code. CodeHero does the whole job — asks, plans, builds, checks, hosts and maintains — for the person who knows the business. Read the article
If CodeHero writes the code, what is my role?
You become the advisor: you decide the business rules, approve the plan and accept the result. CodeHero is the developer that asks, builds, checks and maintains. Read the article
How does the AI keep its memory on long jobs?
With memory folding: when the AI has finished with a long result it keeps a short note of what matters and puts the rest away — it can open it again at any time. So it works much longer without losing the thread. Read the article
How does the AI avoid forgetting or getting confused on a big project?
The factory gives it structure: smart tickets with one clear job each, a change ledger of every decision, a map of the code and search by meaning. The AI reads what it needs instead of guessing — which also saves a lot of cost. Read the article
Why do you call it a factory and not a tool?
Because it runs the whole production line on its own — planning, building, independent checking, repair, delivery and maintenance — with stations, rules and records, like a factory. A tool waits for a person to use it. Read the article
How can this change the world of applications?
When the person who knows the work can get software made, checked, hosted and maintained without a development team, software can be made for every business and every need — not only for those that can afford a team. Read the article
What does CodeHero mean for developers?
Less repetitive work and fewer late nights. The factory takes the routine building, checking and fixing; developers decide the architecture, review what matters and handle the hard problems. Read the article
Why does CodeHero host the applications too?
Because building and running belong together. The application runs where it was built, with its domain, secure connection, backups and recovery — and every later change returns to the same factory. No separate hosting panel to learn. Read the article
What technology do the applications use?
Always open, widely used technologies — PHP and MySQL first, and others such as Node, Python or .NET when the job needs them. Your application is never locked into a proprietary platform. Read the article
Why use AI subscriptions instead of paying per use?
Because in our own measurements, for heavy daily work, a subscription has cost up to about 40 times less than paying per use for the same work. CodeHero runs the subscription AI tools (Claude Code, Codex, Grok Build) as workers in the factory. Read the article
What happens to the knowledge about my project?
It is built up and kept inside your installation: decisions, rules, changes and their reasons, next to the code. A new person or a new AI continues from there — the knowledge does not leave with them. Read the article
Can small local AI models do real work?
Inside the factory, yes — more than on their own. Small, clear tickets, a checklist for finishing, tool help and a stronger model that checks the result let small models on your own hardware do much of the building. Read the article