CodeHero Developer Training — The Autonomous Development Framework (ADF)

Version 1.0 · September 2026 · For CodeHero PRO 4.48 and later

Source: ADF_TRAINING_GUIDE.md · 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:

  1. extract requirements from a client and turn them into a specification package;
  2. plan a CodeHero project (tickets, roles, providers, execution settings);
  3. operate the run (read reports, answer questions, unblock tickets, verify results);
  4. 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.

ModuleTitleYou will be able to
1The frameworkExplain the ADF principles and the CodeHero pipeline
2Extracting knowledge from the clientRun a Spec Builder interview and produce a specification package
3Choosing the stackDecide PHP vs Node vs Python vs .NET, host vs container, with a written reason
4PlanningTurn a package into a serial ticket plan with roles, providers and verification
5ExecutionRead what the agent does, why it stops, and how to answer it
6Customizing the brainChange global and project contexts safely, and prove the change works
7Reaching a working resultDrive a project from first ticket to a verified, documented delivery
8CapstoneDo 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).

FileWhat it is
config/global-context.mdThe global context v6.1 core: the rules every agent gets on every ticket
config/guides/*.mdThe ten on-demand guides of the global context (planning, verify-fix, asking, helper, debugging, frontend, database, build, testing, native): 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>.mdPer-language project contexts (php, node, python, html, react, dotnet, go, java, kotlin, swift, flutter, capacitor, presentation, reporting, api, hybrid)
docs/CODEHERO_PLANNING_GUIDE.mdThe Spec Builder knowledge file (v1.9): how to interview a client and produce a specification package
config/assistant-planner.mdThe 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.mdThe other in-app assistant modes
docs/USER_GUIDE.mdThe 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

An autonomous development framework is a set of rules, roles and checkpoints that lets AI agents deliver working software without a human in the build loop, while guaranteeing that every business decision comes from a human, every claim of success comes with evidence, and every failure is visible.

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:

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.

#PrincipleIn one lineWhere it lives
P1The agent is the only engineerNobody helps during the build. The agent understands, plans, builds, tests, documents.Global §0
P2Evidence, 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
P3Never guess a business ruleTechnical choices are the agent's job; business rules (money, permissions, workflows, statuses, edge cases) come only from the client.Global §4
P4AI before humanBefore 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
P5Safe defaults, and BLOCKED is never PASSWhen no answer can come, pick the option that cannot hurt anyone (deny access, keep history, notify, fail closed) and record it. Missing credentials make a part BLOCKED, never "done".Global §4.1, guides/asking.md
P6Memory on diskContext compaction is assumed. Anything not written to the SPEC FILE or the KNOWLEDGE BASE is treated as if it never happened.Global §6, §7
P7Serial by defaultOne 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
P8Core slice firstThe 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)
P9Verify without buildingA 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
P10Never invent factsNo invented config keys, model names, API abilities, credentials or test results. Unknown → probe it, read the real docs, or mark it BLOCKED.Global H8
P11Root cause, never symptom; never weaken protectionDebugging follows a fixed protocol; the WAF, auth, CSRF and validation stay on; a regression jumps the queue.Global H3, §8
P12Self-contained tickets on a "normal server"Every ticket text carries objective, owned files, contracts, environment facts (localhost only) and a definition of done. The agent never hears the word "container".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, one question at a time, 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  (different provider, master + ultra)
      │
      ▼
 HANDOFF REPORT → operator → client   (works+evidence · waiting on you · decided for you · open)

Three "brains" take part, and it matters which one you are talking to:

BrainWhereKnowledge it readsIts job
Spec BuilderOutside CodeHero: a claude.ai or ChatGPT project with the Planning Guide uploaded as knowledgedocs/CODEHERO_PLANNING_GUIDE.mdInterview the client, decide all technical matters, run 50 review rounds, output the package. Names roles and think modes, never providers.
In-app plannerCodeHero → AI Assistant → Plan with AIconfig/assistant-planner.md + the global contextWrite 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 agentSpawned by the daemon for each ticket (HeroAgent for API providers; Claude Code or Codex 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 + conversationBuild, 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.

PartService / fileWhat it does
Web appcodehero-web (Flask + SocketIO; nginx on port 9453)UI, REST API, live console, terminal, AI Assistant sessions
Daemoncodehero-daemon (scripts/claude-daemon.py)Picks the next ticket per project, assembles the prompt, spawns the agent, watches it, reviews the outcome, retries, snapshots
AgentHeroAgent (heroagent/heroagent.py) or a CLI providerThe tool loop: model call → tool calls → results → repeat until TASK COMPLETED
MCP serverscripts/mcp_server.pyThe codehero_* tools the agent (and the assistant) call: projects, tickets, knowledge graph, git snapshots, containers, screenshots, context extraction
Permission hookscripts/permission_hook.pyThe single choke point every tool call passes through: execution-mode policy, path protection, container routing, loop detection
DatabaseMySQL claude_knowledge (database/schema.sql)projects, tickets, ticket_dependencies, conversation_messages, conversation_extractions, knowledge_nodes, knowledge_edges, project_services, …
Preview proxynginx on port 9867Serves every project at https://127.0.0.1:9867/<project-folder>/ — the only URL the agent may test on
ContainersLXC + 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):

  1. === CURRENT WORKING PROJECT === — project id, name, ticket id; the isolation stamp ("pass project_id=<id> to every codehero_* tool").
  2. A knowledge-graph snapshot — the most relevant nodes of the project's knowledge base.
  3. === PROJECT GLOBAL CONTEXT === — the project's stored copy of the global context, placeholders resolved.
  4. === PROJECT CONTEXT === — the project's stored copy of the language/stack context.
  5. === PROJECT DESCRIPTION === and === PROJECT INFO === — the description and the free "additional notes" field of the project.
  6. === RUNTIME ENVIRONMENT === — pinned runtime versions ("already installed — do NOT reinstall").
  7. === SERVER PORTS === — the concrete preview URL.
  8. === PROJECT SERVICES === — databases, caches and web apps with localhost:<port> and credentials ("already installed and running").
  9. Container execution rules and the container app-deployment guide (container projects only).
  10. 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>").

Two consequences you will use constantly:

1.7 Glossary you must know before Module 2

TermMeaning
TicketOne 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.
Rolemaster_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 modeoff / basic / balanced / ultra — extended-thinking budget. ultra is reserved for planning, replan, verification, peer review, helpers and explicit user choice.
Provideranthropic, openai, gemini, grok, deepseek, glm, openrouter, ollama, vllm (plus generic OpenAI-compatible slots). Only active providers (valid credentials) may be planned.
Execution modeautonomous (no prompts), semi-autonomous (auto-approves safe operations, asks for risky ones, blocks dangerous ones), supervised (asks before every write/edit/command).
Relaxed / strictdeps_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 BASEThe project's knowledge graph (codehero_knowledge_search / codehero_knowledge_store): decisions, failed approaches, components, endpoints, patterns.
SNAPSHOTA git backup taken by codehero_git_operations (backup_snapshot); automatic at ticket start and after each verified part.
PREVIEW URLhttps://127.0.0.1:{PROJECTS_PORT}/{PROJECT_FOLDER}/ — the only place the agent may test a web page.
VERIFY ticketA ticket that only checks another ticket's work. Different provider, master_developer, ultra. Never edits code.
HELPER ticketA parallel ticket on another provider that only advises by messages. Opened and closed by the ticket that needs it.
Walkie-talkieTicket-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 (⏸ WAITING-FOR-TICKET #id, several ids allowed) is woken by it, and a ticket that ends its turn with a message still unread is re-opened at once.
TASK COMPLETEDThe completion marker. The agent may say it only when the work is finished and the output was checked.

Exercises — Module 1

  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.)
  2. 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.
  3. On your training installation, open Settings and list the active providers. Mark which ones have vision. Keep this list; every plan in Modules 4 and 8 must respect it.
  4. 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

  1. Create a project in claude.ai (or a ChatGPT project). Upload docs/CODEHERO_PLANNING_GUIDE.md as project knowledge.
  2. Set the project instruction to exactly: "You are the CodeHero Spec Builder. Follow the file CODEHERO_PLANNING_GUIDE.md exactly."
  3. 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:

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:

StatusMeaningWho resolves it
ConfirmedThe client said it, or a source document shows it
AssumedA reasonable business assumption that still needs confirmationThe client, at the preview or the final confirmation
TechnicalThe Spec Builder's own choice, with a reason; never asked of the clientThe developer may override with a recorded reason
OpenA missing element that affects the buildMust 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:

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?

StageWhat must be known afterwardsTypical count
0 SetupWhat to organize, existing documents, a name, who will maintain it2–3
1 Company and purposeThe business, the pain, who suffers, success in six months, internal vs external users, countries, what must never happen5–7
2 The work itselfThe "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 data10–15
3 People and rightsUser types, what each sees and changes, who may delete/approve/export (critical), scoping by branch/team, admin area, concurrency, external logins, audit6–10
4 Notifications, reports, integrationsWhen someone must be told, channels people actually read, reports, exports, scheduled emails, automatic data exchange5–8
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 budget5
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."1 loop
5 Speed, scale, real time, mobileHow fast others must see a change, alarms where seconds matter, sensors, where it is used, offline, store app vs website, camera/GPS/push, growth6–9
6 Look, feel and brandLogo and colors, feel, references, theme, languages, units, accessibility5–8
7 Security, compliance, hostingPersonal data, 2FA, session length, security testing, where it runs, domain and SMTP, audit proof, backup tolerance, confirmed monthly cost6–9
8 Priorities and go-liveThe one part that must be ready first, the MVP/Optional/Later split, data import, first administrator, training, deadline, "anything you were afraid to ask?"5–7

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 saidBecameStatus / 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, TechnicianConfirmed / user
Column H in the sheet is =D2+14Business rule: deadline = received date + 14 daysConfirmed / document (the assistant restated it and the client said yes)
"Red cells are the ones we are late on."Rule: a job past its deadline and not ready is overdue; overdue jobs are highlighted and the manager is notified dailyConfirmed / user (highlight) + Assumed / agent (daily email)
"Only I give discounts."Permission: discount requires the Owner roleOpen — 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 portalLater
"Sometimes two technicians work on the same job."Job has one responsible technician and optional helpers; history keeps who did whatAssumed / 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 sTechnical / agent
"We have a website on a normal hosting company, nobody technical in-house."Hosting: standard PHP/MySQL web hosting, no in-house supportConfirmed / user → drives the stack (Module 3)
"Budget: as little as possible per month."Monthly cost target: hosting onlyConfirmed / user

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 spreadsheetBecomes
Each sheet or repeated blockA candidate entity, named in the client's words
Each columnA typed field (text, number, date, money, choice list, person, reference, file, formula)
Each formulaA business rule, restated in words and confirmed with the client's own numbers
Colors, comments, manual marksWorkflow 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 columnsPermissions
Duplicates, blanks, inconsistent spellingsData-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 statusVerification status
confirmed / assumed / technical / openpending / verified / failed / mock_only

A dependency that an active function needs must be verified before the feature tickets that depend on it start. Until then the package stays a Draft, and a Draft may go to CodeHero only for probe tickets (environment checks, integration probes). 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 The 50 review rounds

Once the complete first version of the specification exists, the Spec Builder runs 50 sequential review-and-fix rounds and a final consistency check. Each round examines the whole current specification from one perspective (main process end to end · every rule has a number and an example · what must never happen · late, duplicate, out-of-order data · time zones · permissions matrix · external users see only theirs · backups and one restore drill · audit fields · hosting capabilities verified · milestone order builds the main value first · each ticket has a demonstrable definition of done · …), tries concrete examples in the client's own numbers, fixes what the agreed requirements allow, and records one row in Appendix E.

What you must know as the reviewer of the package:

The executing agent later runs the same discipline on its plan (guides/planning.md step 12: about twenty review rounds for a real project, eight for a small one). Same idea, two levels: the spec is attacked before the plan exists; the plan is attacked before the tickets exist.

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:

PartWhy it matters downstream
Header block with the codehero_environment blockTells the planner whether a container is needed, who provisions it, which services, the database, real-time mode, build tooling, who serves the built files, and the fallback stack
2 CodeHero run settingsRoles and think modes per ticket type, serial execution, replan and revalidation cadence, circuit breakers
4 Access gateThe thin end-to-end slice through the real hosting before any feature
7 Business rulesNumbered, with worked examples and expected results — the agent's only source of business truth
17 Milestones and ticket planValue order, ticket text rules, requirement IDs per ticket
18 Contracts, day-0 inputs, touchpointsWhat the client must provide before the run, and the only four reasons CodeHero will contact them during it
Appendix FOpen items, assumptions to confirm, technical decisions — the first thing the client reads
Appendix G / HRequirements 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:

Ticket typerolethink_mode
Planning, replan, contracts, architecture, securitymaster_developerultra
Independent revalidation (verifies only)master_developer (different provider if available)ultra
Feature implementationsenior_developerbalanced
Repetitive work (locale files, CRUD from a contract, docs formatting)junior_developerbasic
Tests and fixturessenior_developerbalanced

2.11 Draft vs Ready to build

StateConditionWhat CodeHero may do with it
Draft for confirmationContains Assumed or Open items; open items listed at the top, never hiddenProbe and setup tickets only; feature tickets that depend on open items wait
Ready to buildCritical open items of the agreed scope — and of the dependencies that scope needs — are closed; non-critical assumptions may remain and are listedThe full plan

Moving a critical open item to Later requires the client's agreement; it is never done silently to reach Ready to build.

2.12 The day-0 pack and the four contact reasons

Before the run, the client provides the day-0 pack: domain, hosting access, SMTP account, logo files, the spreadsheet, first administrator details — and, if the container is created manually, the container with its access details. During the run, CodeHero contacts the client for exactly four reasons:

  1. external credentials or accounts for a specific gate;
  2. a fix loop that reached its limit;
  3. a fallback that would change an agreed requirement;
  4. discovery of a new critical business ambiguity that cannot be resolved from the confirmed requirements.

Ordinary business assumptions are confirmed before the run (Stage P, final confirmation), never during it. If your run keeps stopping with business questions, the interview was incomplete — fix the package, not the tickets.

2.13 Handing the package to CodeHero

The package is pasted (or attached) into the in-app Plan with AI planner, which recognizes it by its markers (codehero_environment: block, run settings, registers, ticket plan with roles and think modes) and switches to IMPORT MODE: it asks only for missing authorizations and day-0 owners, shows a preview, and creates the project plus ONE planning ticket that carries the package verbatim. 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. Day-0 inputs and open items go to the operator, never into ticket descriptions.

2.14 Developer's review checklist for a package

Before you import a package, check:

Exercises — Module 2

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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 fifty rounds 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:

ReasonWhat it means for the client
Ease of installation and maintenanceRuns on any cPanel/Plesk hosting; no process manager, no daemon, no container to operate
Lowest running costShared hosting money, not VPS money; no in-house support needed
Fit with CodeHero's own strengthsThe 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 defaultPlain .js plus local libraries copied from /opt/codehero/libs/ (Tailwind, Alpine, Vue, FontAwesome) — instant, offline, no npm
Interpreted = servedOn 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

ConditionMove toWhy
WebSockets are required by an acceptance criterion (alarms in seconds, live boards, multi-user editing)T-NODE (T-NET / T-PY when the environment fits)Web hosting cannot keep sockets open; CodeHero policy is never to stretch PHP to cover them
Permanent workers or continuous server-side processing (device/sensor streams, jobs that exceed cron limits, media processing)T-NODE / T-PYWorker processes beyond limited-duration cron
Statistics, forecasting, machine learning, scientific librariesT-PYEcosystem
The client asks for a technology, or already runs and maintains one that meets the requirementsThat stackMaintainability and fit beat preference
Microsoft environment (Entra ID, SQL Server, Windows servers, a .NET team) when it fits their operationsT-NETFit with their operations
A native mobile app is neededSwift / 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 none of the triggers applies, the spec says so explicitly: "PHP/MySQL chosen; runs on standard web hosting; no container required."

3.4 The archetypes (what the signals usually mean)

IDArchetypeTypical signalsDefault stackContainer?
A1Static siteBrochure, no login, contact formHTML/CSS/JS + PHP mailerNo
A2Content site with forms and adminPages, catalog, submissions, small adminT-PHP, Alpine + TailwindNo
A3Internal tool / spreadsheet replacement"Our Excel", records, roles, reports, importsT-PHP; Vue only when the screens justify itNo
A4Multi-tenant SaaSMany companies, per-company settings, billingT-PHP (Laravel) for most; T-NODE when §3.3 requiresNo / Yes
A5Real-time monitoring / operationsDevices, alarms, seconds matter, live screensT-NODE (T-NET/T-PY when the environment fits)Yes
A6Integration hub / API productConnecting systems, webhooks, transformationsT-PHP when request- or schedule-based; T-NODE/T-PY when continuousNo / Yes
A7Customer / supplier portalExternal logins, documents, statusesT-PHPNo
A8Mobile companion appField staff, camera/barcode/GPS, pushT-PHP REST API + web app wrapped with CapacitorRuntime as the backend
A9Native mobile appHardware/OS integration, offline-heavySwift / Kotlin + backend by the rulesPer backend
A10Data / analytics toolHeavy calculations, forecasts, large importsT-PY + MySQLYes

3.5 The ladders: pick the lowest rung that satisfies the answers

Real-time ladder (from Stage 5 answers):

  1. On refresh — content sites.
  2. Polling every 15–60 s — most internal tools; any hosting; T-PHP.
  3. Polling every 5 s + in-app badge — operational tools where a minute is too slow; still T-PHP.
  4. Server-sent events — one-way live feeds; T-PHP where the provider supports it and it is verified; otherwise a container.
  5. WebSockets with a durable event stream — alarms, live boards, multi-user editing; container stack. Pattern: events from a database outbox with cursor, replay on reconnect, heartbeat with visible disconnection, receipts.

Mobile ladder:

  1. Responsive web app — every product gets it.
  2. Installable web app (PWA) — home-screen icon, offline read-only cache, web push.
  3. 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).
  4. React Native / Expo — only if the client's team is React-based and asks.
  5. 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), built inside CodeHero and committed as static files, so a PHP host never needs Node.

3.6 Runtime vs build tooling vs serving — three separate declarations

The single most common confusion. The codehero_environment block separates them on purpose:

QuestionFieldRule
What must be running on the server?container_required, services, long_running_processesAnything beyond PHP + MySQL at runtime (Node, Python, .NET, Redis, workers, WebSockets) → container_required: true
What is needed only to build artifacts?build.web (none / tailwind-cli / vite), build.android, build.ios, build_containerNever 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:

SituationBuild workspace
Container projectAnywhere inside the container; only the served output matters
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/.

Container projects. CodeHero creates an LXC container per project (codehero-<project_id>) from a manifest of services — the default manifest offers nginx, PHP 8.3, MySQL 8.0, Python 3.12, Node 20 and Redis 7, and the Container Isolation chapter of the User Guide lists the full catalogue of languages, databases and service options. Services declared at creation are provisioned before any ticket runs; the agent's commands are routed inside the container transparently; the agent sees services at localhost:<port> in its PROJECT SERVICES block and must believe it is on a normal server.

This is why the Planning Guide and the planner both say: no ticket installs PHP, Node, MySQL, Redis or a web server, and no ticket configures nginx. The first real ticket sets up the application (folders, config, schema), and a setup ticket in a container verifies the provisioned services and configures application-level pieces. A plan with an "install Node.js" ticket is a plan that misunderstood the platform.

3.8 Project type and paths

Outputproject_typePathRule
Any project with web pages / HTML output — regardless of languagewebweb_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 HTMLappapp_path: /opt/apps/<slug>

tech_stack selects the project context file: php, python, node, html, java, dotnet, go, react (also used for React Native), flutter, kotlin, swift, presentation, reporting; project types capacitor, native_android, dotnet, presentation, reporting also map. Anything unmapped falls back to php. 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

codehero_environment:
  container_required: false          # runtime beyond PHP + MySQL? → true
  container_provisioning: none       # none | codehero (platform creates it WITH the services) | manual (client created it; access = day-0 input)
  services: [php-fpm, mysql]         # runtime services the environment must provide
  database: mysql                    # mysql by default; postgresql | sqlserver only with a recorded reason
  long_running_processes: none       # e.g. [api, workers, websocket-gateway]
  scheduled_jobs: cron-every-minute  # or worker-queue; state max duration, overlap lock, retries, interruption behaviour
  realtime: polling-30s              # none | polling-Ns | sse (verified on provider) | websocket
  build:
    web: tailwind-cli                #   none | tailwind-cli | vite
    android: none                    #   none | capacitor | native
    ios: none
    ios_path: none                   #   macos-xcode | external-service (named)
    signing: none
    test_devices: none
  build_container: none              # none | node | node+android | node+ios
  served_by: php-host-static-files   # php-host-static-files | nginx-static | app-server
  fallback_stack: none               # for any non-PHP choice: the T-PHP design to fall back to, valid only if the same acceptance criteria still pass

container_provisioning: codehero is the normal choice: the in-app assistant creates the container with the declared services before the planning ticket exists. manual means the client operates their own environment; then the container and its access details are a day-0 input, and the setup ticket only verifies and configures.

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."

codehero_environment:
  container_required: false
  container_provisioning: none
  services: [php-fpm, mysql]
  database: mysql
  long_running_processes: none
  scheduled_jobs: cron-every-minute   # overdue check: max 50 s per run, overlap lock, 3 retries, safe to interrupt
  realtime: polling-60s
  build: {web: tailwind-cli, android: none, ios: none, ios_path: none, signing: none, test_devices: none}
  build_container: none
  served_by: php-host-static-files
  fallback_stack: none

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."

codehero_environment:
  container_required: true
  container_provisioning: codehero      # CodeHero provisions node, mysql, redis, nginx at creation
  services: [node, mysql, redis, nginx]
  database: mysql
  long_running_processes: [api, workers, websocket-gateway]
  scheduled_jobs: worker-queue
  realtime: websocket
  build: {web: vite, android: none, ios: none, ios_path: none, signing: none, test_devices: none}
  build_container: node
  served_by: nginx-static
  fallback_stack: T-PHP with polling-5s   # only valid if A07 still passes — it will not, so this is a requirements change

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 saysDecisionWhy
1"A website for our law firm with a contact form and a news page the secretary updates."A2 · T-PHP · no containerContent + small admin; no trigger
2"We want a REST API for our mobile app; 200 field workers upload photos of deliveries."A8 · T-PHP REST API + Capacitor app · no container for the backendA REST API and a mobile backend are not reasons to leave PHP; store accounts are day-0 inputs
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 · containerContinuous 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 · container · SQL Server with a recorded reasonFit 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 · container · MySQLScientific 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 containerExternal 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 choiceThe 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 containerPolling 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.

"A07 requires alert delivery within 2 s over a persistent connection; standard PHP hosting cannot hold WebSockets; T-NODE in a container with Redis-backed outbox."

A justification that names a preference ("Node is more modern") instead of a requirement is not a justification. Send it back.

Exercises — Module 3

  1. For each of the eight mini-cases, write the codehero_environment block. Compare with a colleague; every difference must be explainable by a requirement.
  2. 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?
  3. 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."
  4. 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.
  5. 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).

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 decides the depth. A small change or fix on an existing project is not a plan at all — the assistant creates one ordinary build ticket and the agent runs the light loop of the global context. A small project (one phase, up to about eight tickets, no accounts, no money) gets PLAN-lite: eight review rounds, a peer check only when there is login or money, no [REPLAN]. A real project gets about twenty rounds, the peer check, and phases of about ten tickets.

4.2 The assistant's rules that matter to you

  1. MCP tools only. Project, environment and the planning ticket are created with codehero_create_project, codehero_container_operations and codehero_bulk_create_tickets (with one ticket) — never with SQL, curl or the UI on the assistant's behalf.
  2. codehero_get_providers_info first. 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.
  3. Only active providers, for the project default and for the planning ticket.
  4. Exactly one ticket. Even a package with a complete ticket plan produces one planning ticket; the cards stay candidates.
  5. Preview → explicit confirmation → create. Settings, specification summary, day-0 inputs, run settings, then "yes / ok / ναι / προχώρα". "Do what you think" delegates decisions, not the preview.
  6. 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.
  7. Environment is not ticket work — containers and services are created before the planning ticket; tickets install no runtimes; ticket text says localhost:<port> and never a container name or an internal IP.
  8. What you set, it passes. Flow, execution mode, strategy, parallel and plan approval appear in the preview, in the run contract, and explicitly in the tool call (relaxed = deps_include_awaiting: true, strict = false).
  9. Language and voice mode, as everywhere.

4.3 Three modes

ModeTriggerWhat the assistant does
IMPORTThe 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
BUILDAnything else: a description, a spreadsheet, a documentActs as the Spec Builder: one focused question at a time, 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 anything is created), project think mode balanced. ultra is never a project default; the planning ticket itself runs master_developer + ultra on the smartest 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.

Role by complexity and strategy (the planning ticket's table; the Spec Builder's table in Module 2 covers packages that state roles):

Complexityecobalancedperformance
Trivial (docs, typos, config)juniorjuniorjunior
Simple (static pages, boilerplate)juniorjuniorsenior
Moderate (features with logic, APIs)juniorseniorsenior
Complex (multi-file, refactor)seniorseniormaster
Critical (architecture, auth, security, setup/foundation)seniormastermaster

Think mode ladder: off/basic for trivial and simple work; balanced for standard features; ultra never for a build ticket on the planner's own initiative — and always for [PLAN], [REPLAN], [VERIFY], [PEER] and [HELPER] tickets.

Provider assignment (never the Spec Builder's job):

4.5 Translating the environment contract into a project

Contract saysAssistant 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.
platform-container (legacy: container_required: true, container_provisioning: codehero)Create the project, then the container with codehero_container_operations declaring the listed services (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 hostA day-0 input with its owner — never a ticket.
Run contractWritten 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 itemsA ## DAY-0 INPUTS AND OPEN ITEMS section of the planning ticket; the planner turns them into BLOCKED asks at the step that needs them and never asks a known open item again.
Draft / open itemsThe planning ticket creates only what the open items allow; feature tickets wait.

4.6 The ticket fields and what the scheduler does with them

FieldMeaningBlocks execution?
sequence_orderOrdering. 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_onExplicit 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_sequenceSub-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_modePer-ticket settings; omitted → inherit from the project
deps_include_awaitingThe flow: 1 relaxed (default) · 0 strict — see §4.9
is_forcedForced 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, priorityfeature / task / bug …; low / medium / high / criticalPriority only orders eligible tickets

How the daemon picks the next ticket per project: the lowest sequence number that still has an unfinished ticket → among the tickets of that number: status open (or new/pending) → retry cooldown elapsed → every dependency done/skipped → parent done/skipped → forced first, then creation time → as many as the free slots allow. Nothing of a higher number is even considered.

Titles are triggers. [PLAN], [REPLAN], [VERIFY], [FIX], [HELPER], [PEER] 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; parallel as an offer; the file-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.

When some tickets are truly independent (different pages, different API folders, different components, different test files, different migration files), the planner may offer a group: "Tickets 4, 5, 6 touch different files and could run together — parallel? (yes/no)". Only an explicit yes turns it on (a request that already asked for parallel counts as yes). Then the analysis is mandatory:

  1. 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).
  2. 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.
  3. Zero overlap is required. Any overlap → serialize (depends_on + different sequence_order), split the ownership, or merge into one ticket.
  4. Show the ownership table in the preview. Maximum 5 tickets per group. In any doubt → serial.

Two 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; and the [FIX] tickets a verifier creates at its own sequence while it parks and waits for them (§5.9).

4.8 The ticket description recipe (every ticket, both modes)

The executing agent sees only the ticket text plus the project context. A description that assumes the reader was in the planning conversation is a description that will be misread. Five parts:

  1. Objective — what to build, concretely, and the requirement IDs it serves.
  2. Where — the files and folders this ticket owns.
  3. Contracts — endpoints, table and column names, response shapes, shared formulas that other tickets rely on. Shared things are written before either side is built (P6, guides/planning.md step 5: contracts first).
  4. Environment facts — services at localhost:<port>, credential placeholders, the preview URL shape. Never a container name or an internal IP; never the word "container".
  5. Definition of done — how the agent verifies: what to run, which page to load, what the expected output is. Testable sentences, not adjectives.

Three text rules from the Planning Guide, worth repeating because they are the ones most often broken by hand-written tickets: self-contained, localhost only, application, not infrastructure.

4.9 Execution mode and flow

Execution modeBehaviourUse when
autonomous (default)No permission prompts; the permission hook still enforces path protection and loop detectionTrusted work, the normal ADF run
semi-autonomousAuto-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 projectProjects that need guardrails; approvals can be generalized with "Approve all similar"
supervisedAsks before every write, edit and commandSensitive projects; learning how the agent works
Flowdeps_include_awaitingWhat changes
relaxed (default)1When 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
strict0The 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: <mode> · Flow: <relaxed → deps_include_awaiting: true | strict → false> · Strategy: <…> · Parallel: <serial-only|allowed> · Plan approval: <autonomous|you approve the first stage>
• Planning ticket: <provider> · master_developer · ultra

📄 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 .specs/001-project-plan.md): 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"). With plan_approval: autonomous it creates the phase right away and reports NEEDS THE USER: no; with owner-approves-first-stage it asks "Should I create the tickets?" and waits.

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 plan: RepairFlow, phase 1

Assume the installation's active providers are anthropic (vision), deepseek (no vision), gemini (vision). The package is Ready to build. The plan table the planning ticket produced for phase 1 (its own [PLAN] ticket is not in the table):

⚙️ Settings:
• Project: RepairFlow (web, /var/www/projects/repairflow) — PHP 8.3 + MySQL, no container
• Providers: anthropic, deepseek, gemini · Strategy: balanced
• Execution: autonomous · Flow: relaxed
• Day-0 inputs: SMTP account for notifications (client) · first Owner account details

| #  | Ticket                                              | Seq | Provider  | Role   | Think    | Deps | Files                                   | Verify |
|----|-----------------------------------------------------|-----|-----------|--------|----------|------|-----------------------------------------|--------|
| 1  | Capability probe: runtimes, DB access, preview URL  | 1   | deepseek  | senior | basic    | -    | .specs/000-probe.md                     | -      |
| 2  | Knowledge foundation: store architecture + rules    | 2   | deepseek  | master | balanced | 1    | .specs/, knowledge base                 | -      |
| 3  | Application setup: bootstrap, schema, seed, header  | 3   | anthropic | master | balanced | 2    | includes/, database/, .env.example      | ✓      |
| 4  | [VERIFY] Application setup                          | 4   | gemini    | master | ultra    | 3    | (checks only)                           | -      |
| 5  | Access gate: login + empty job list on preview URL  | 5   | anthropic | senior | balanced | 3    | login.php, index.php, includes/auth.php | ✓      |
| 6  | [VERIFY] Access gate                                | 6   | gemini    | master | ultra    | 5    | (checks only)                           | -      |
| 7  | Core slice: create job → change status → deliver    | 7   | anthropic | senior | balanced | 5    | jobs/, includes/JobService.php          | ✓      |
| 8  | [VERIFY] Core slice (incl. negative tests)          | 8   | deepseek  | master | ultra    | 7    | (checks only)                           | -      |
| 9  | Overdue rule + daily notification (outbox, cron)    | 9   | deepseek  | senior | balanced | 7    | cron/overdue.php, includes/Mailer.php   | ✓      |
| 10 | [VERIFY] Overdue + notification                     | 10  | anthropic | master | ultra    | 9    | (checks only)                           | -      |
| 11 | [REPLAN] check phase 1 and plan phase 2             | 11  | anthropic | master | ultra    | 9    | .specs/, tickets                        | -      |

📊 anthropic=5, deepseek=4, gemini=2 · 💰 medium · ⚡ Flow: serial
Do you agree? (yes / no / changes)

Points to notice:

4.12 Two ticket descriptions from that plan

Ticket 3 — Application setup (master_developer, balanced):

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).
- database/seed.sql: one user per role (test passwords in .specs), 3 technicians, 5 customers.
- 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, master_developer, ultra, 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 `bash .tests/run.sh`. 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 ONE [FIX] ticket for the original builder at YOUR sequence_order (same provider
and role as ticket 3, no depends_on), park with ⏸ WAITING-FOR-TICKET #<fix id>, and re-check the
findings yourself when the fix replies (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

  1. 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.
  2. 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.
  3. 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.
  4. Explain, with the scheduler rules of §4.6, what happens to ticket 9 if ticket 7 ends in awaiting_input with a question. What must the operator do?
  5. 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:

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:

ToolUse it forPolicy
Read, Write, Edit, MultiEditFilesRead before edit; files over 500 lines: Grep first, then targeted Read
Glob, GrepFinding files and textInstead of find / grep via Bash
BashCommandsLast resort — prefer the dedicated tools; foreground only; run_in_background is denied
ProcessManagerLong-lived services (dev server, API)Instead of nohup … &; survives the turn
HttpRequestAPI calls, CSRF flowsInstead of curl; sessions persist
BrowserFunctional flows: goto, click, fill, wait_for, get_text, eval, console_logs, network_logsThe only way to test pages; sessions persist across calls
PageAssertStructured checks: visible, contrast, no console errors, no broken imagesWorks without vision
LogTailServer logs by named source (nginx-error, php-fpm-8.3, mysql-error, …)Instead of tail / journalctl (no sudo prompts)
WebFetchReading documentation pages
GetCachedRe-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 ten guides), 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.

The permission hook sits between the model and every tool call. It enforces the execution mode (Module 4 §4.9), path protection (H5: only {web_path}, {app_path} and /tmp), container routing, 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 (polling a ticket, a bare sleep) is exempt, so a parked dialogue is not mistaken for a loop. HeroAgent adds per-tool error counters (warn at three consecutive failures, break at five) and a cap of 1000 iterations per run.

Container projects. The agent's commands are routed inside the container by the platform (the crun wrapper). The agent does not know and must not be told; it works on "a normal server" where services are at localhost.

5.3 The work loop the agent follows (global §5)

  1. Understand the task (apply the language rule).
  2. Search the knowledge base — one broad query with the task title, one per component — then read the relevant code.
  3. 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, bash .tests/run.sh, snapshot, a five-line report. No plan mode, no rounds, no peer.)
  4. Build one small part.
  5. Verify that part (§5.5). Fails → debugging protocol (§5.6).
  6. Update the SPEC FILE, then snapshot. After every part, not only at the end.
  7. Parts remain → back to 4.
  8. Full test on the PREVIEW URL, then bash .tests/run.sh (ALL repeatable tests — the runner .tests/run.sh is installed by the platform in every project), then walk the ACCEPTANCE list item by item: pass, fail, or BLOCKED with the reason.
  9. Store knowledge: decisions and failed approaches.
  10. 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. 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.

5.4 Two memories

SPEC FILE (.specs/NNN-name.md)KNOWLEDGE BASE (graph)
ScopeThis taskThe whole project, forever
ContentGOAL · 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 whenBefore coding, after every part, at the endThe user says "remember"; a command failed then worked (💡 TEACHABLE MOMENT); a non-obvious choice between approaches; architecture designed
Read byThe agent after compaction ("if you feel lost, re-read the SPEC FILE first"), the VERIFY ticket, the next ticketEvery ticket at start; the hint system (🚨 known dead ends for a file about to be edited)
You read it inProject Files / File Explorercodehero_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.

5.5 The verification recipe (global §9) — what "evidence" concretely means

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:

  1. Read the ticket's last message in the Ticket Detail page (or the Telegram notification).
  2. 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").
  3. 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.
  4. 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.

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:

Then four parts, in this order:

  1. What works now — with the evidence (which test ran, which URL loaded, which screenshot).
  2. What is waiting for the user — blocked parts with the exact ask (credentials, decisions), one consolidated ask per service.
  3. What was decided on your behalf — technical choices worth knowing plus every SAFE DEFAULT, each reversible with one line.
  4. What stays open — known limits, deferred parts, what the next ticket must know.

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

  1. [VERIFY] ticket (different provider family, master, ultra, parent_sequence/parent_ticket_id = the builder; guides/verify-fix.md pre-loaded): walks the parent's acceptance list, runs the recipe and bash .tests/run.sh, 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).
  2. No findingsVERIFY: PASS · cycle 1 on the parent's SPEC FILE, report NEEDS THE USER: no. The reviewer closes it; the plan goes on.
  3. Findings → the verifier creates ONE [FIX] <parent title> (#<parent id>, cycle 1) per parent with findings — the original builder's provider and role, at the verifier's own sequence_order, with no depends_on — writes VERIFY: FAIL · cycle 1 · … · fix #<id> on the parent's SPEC FILE, and parks: ⏸ WAITING-FOR-TICKET #<fix id>. A parked verifier keeps its sequence unfinished, so the fix runs at once and everything behind waits.
  4. The fix fixes only the listed findings, each with a repeatable test that fails before and passes after; a finding it disagrees with is DISPUTED with a proof. When done it writes FIX: done · cycle 1 on 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.
  5. The verifier wakes (cycle 2), re-checks only the findings (plus the acceptance items they touch and the test suite), and either writes VERIFY: PASS · cycle 2 and reports, or opens cycle 2's fix and parks again.
  6. 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 BREAKER on the record, reports NEEDS THE USER: yes with both views, and stays open until you decide (your decision is recorded as USER DECISION and 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 arbitrate.

5.10 Helper tickets and the walkie-talkie

Any ticket may open a [HELPER] on another provider 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; at most two open at once, on different providers; three exchanges without agreement → both views go to you. 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. A parked ticket (⏸ WAITING-FOR-TICKET #<id>, several ids allowed: the first reply wakes it, it parks again for the rest) is woken by the reply. 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.

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 of a real project. 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, bash .tests/run.sh) 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, peer check); REPAIR NEEDED → a phase of repair tickets (+ their [VERIFY]) ending with a new [REPLAN], 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. It never edits the baseline to match the code. 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

ControlWhereEffect
Send MessageTicket Detail → message box, or TelegramReopens the ticket (if awaiting) and continues the same conversation
Stop (kill switch)Stop button or /stopPauses immediately; ticket parks in awaiting_input (reason stopped) and waits for your correction
Retry / ReopenTicket actionsReturns a failed or finished ticket to open
Start now / Force nextTicket actions or codehero_start_ticketForced 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)
SkipTicket actionsMarks it skipped — satisfies dependencies
CloseTicket actions or codehero_update_ticket(status="closed")Sets it to done (there is no separate closed status)
Change role / provider / think modeTicket edit or codehero_update_ticketApplies to the next run
Restore a snapshotGit Manager / BackupRolls the project files back
Permission bannerTicket Detail (semi-autonomous / supervised)Allow, Deny, or "Approve all similar"

5.13 Reading a run like an operator — a checklist

For every finished ticket:

Exercises — Module 5

  1. 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.
  2. 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.
  3. 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.
  4. Create a [VERIFY] ticket by hand for exercise 1's ticket (different provider, master, ultra, 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.
  5. 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.
  6. Explain to a colleague, using the lifecycle diagram, why a serial plan with one ticket in awaiting_input shows 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

LayerSource file (edit here)Installed copiesRead byScope
Global context coreconfig/global-context.md/opt/codehero/config/global-context.md (defaults for new projects and the context-defaults API) and /etc/codehero/global-context.md (the assistant's copy)The executing agent, as === PROJECT GLOBAL CONTEXT === (the project's stored copy)Every project
Guidesconfig/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] ticketsEvery project
Language / project contextconfig/contexts/<stack>.md/opt/codehero/config/contexts/<stack>.mdThe executing agent, as === PROJECT CONTEXT ===Every project of that stack
Per-project stored copies— (DB: projects.global_context, projects.project_context)Copied from the two files above at project creation, with {PROJECTS_PORT}, {ADMIN_PORT} and {PROJECT_FOLDER} resolvedThe executing agentThis project only
Project description and infoUI: Project Settings (projects.description, projects.context)The executing agent (PROJECT DESCRIPTION, PROJECT INFO)This project — the right home for the package's Mandate and run settings
TicketUI or MCP (tickets.description, tickets.context)The executing agentThis task
Knowledge baseThe agents themselves (and you, by telling a ticket or the AI Assistant to "remember" something)DB graphEvery ticket at start, plus the hint systemThis project, evolving
Assistant templatesconfig/assistant-{general,planner,progress,help}.md/etc/codehero/assistant-*.mdThe in-app assistant modesThe assistant, not the tickets

Three facts decide how a change propagates:

  1. New projects copy the current files at creation. Existing projects keep their stored copies until you open Project Settings → Context, edit, or load the defaults again. This is a feature (a project's rules do not change under a running plan) and a trap (you deploy a fix and old projects do not get it).
  2. .md files are read fresh: the daemon reads the project's stored copy per ticket; the planner reads its template per session; codehero_get_context_defaults reads the files per call. No service restart is needed for context changes — only the copy to the installed paths.
  3. 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.

6.2 Which layer for which rule

Kind of rulePut it inNot in
The method: how to plan, build, verify, ask, report; hard rules; debugging; knowledge; verification doctrineGlobal contextA 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 languageLanguage contextGlobal (it would bloat every project)
Company-wide conventions that apply to every stack (documentation files, naming, accessibility floor, a required CHANGELOG.md)Global context, §11 (code rules) or §13 ("Documentation you maintain")Language contexts (you would repeat it 16 times)
This project's facts: folder map, existing conventions of an imported codebase, test command, "do not touch" list, the client's Mandate and run settingsProject context (stored copy) and project descriptionGlobal
The client's business rules, formulas, permissions, worked examplesThe specification package → project description (Mandate) + knowledge base (decision / spec nodes) + each ticket's Contracts sectionGlobal or language context (they are not rules of the method)
One task's objective, owned files, definition of doneTicket descriptionAnywhere 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.1: a core of about 49 KB plus ten on-demand guides) is written in simple English so that every model, big or small, can follow it. Its conventions are not style; they are what makes weak models comply. Keep them when you add or change rules:

ConventionWhy it works
A READ-THIS-FIRST section with a glossary and the 11 most important rulesSmall 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 preventsA 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 rulesConditionals are executed; adjectives ("try to be careful") are ignored
Tables: symptom → most likely cause → first checkThe 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 valuesA 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 core is about 49 KB (roughly 12K tokens) and is sent with every ticket; a guide is paid only by the tickets that need it (planning 36 KB, verify-fix 10 KB, the others 2–16 KB). 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

Change a rule only for a failure you observed, and write the failure next to the rule.

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 §13 "Documentation you maintain", add CHANGELOG.md to the list, and in §5 step 9 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.9): 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:

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

An existing PHP application is imported in extend mode. Run codehero_analyze_project first (it builds the project map). Then write, in the project's stored project context, the facts the analysis cannot infer and the agent must not guess (P10):

## This project (imported 2026-09-15, extend mode)
- Framework: none. Front controller public/index.php → app/Router.php. Do not add a second router.
- DB access ONLY through app/Db.php (PDO, already ERRMODE_EXCEPTION). Never create another PDO.
- Sessions are started in app/bootstrap.php; do not call session_start() elsewhere.
- Tests: `vendor/bin/phpunit` (all green at import; a red test is a regression — Rule §8).
- Do NOT edit: vendor/, public/legacy/ (old reports still in use), app/Legacy/*.
- Naming: snake_case for DB, camelCase for PHP, kebab-case for URLs — keep it.
- Known trap: app/Mail.php sends synchronously; new mail goes through the outbox table (see knowledge base: decision "mail-outbox").

Store the same facts as knowledge nodes (component, config, decision) so the hint system shows them when the relevant files are edited. The project context tells the agent; the knowledge base reminds it at the moment it matters.

6.8 Worked customization 4 — an API-only project

The global verification recipe is browser-centred. For a project of type app with no HTML, the api context describes the architecture but the agent still needs an explicit verification recipe. Add to the project context:

## Verification for this API (replaces the Browser part of Global Section 9)
- Start the service with ProcessManager; health check: HttpRequest GET http://127.0.0.1:{PORT}/health → 200.
- For every endpoint in the SPEC FILE's CONTRACTS: HttpRequest the happy path AND one negative
  (missing auth → 401, invalid body → 422, other user's resource → 403).
- LogTail(path="{app_path}/logs/app.log", since="5m", level="error") must be empty.
- Run the test suite: `npm test` / `pytest` — 0 failures is the acceptance floor.
- Deliveries (webhooks, emails) need proof per Global Section 9.

You are not overriding the global; you are doing exactly what the global tells native projects to do in §15 ("replaces the Browser part of Section 9. Everything else still applies").

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: the rule lives in the specification's §7 with a worked example; the planner copies the Mandate into the project description; the knowledge-foundation ticket stores it as a decision node ("vat-rounding: 24% on net, round half-up to 2 decimals, per R017 example 3"); every ticket that touches money cites R017 in its Contracts section; the VERIFY ticket tests the example values. The agent finds the rule in three places at run time and never has to guess.

6.10 Testing a context change — the protocol

  1. Diff and size. diff against the previous version; check the file size change. A change that adds more than a few hundred bytes needs a reason.
  2. 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.
  3. Deploy to the installed paths (§6.1). No restart needed.
  4. Create a throwaway project so it receives the new stored copy. Check the copy in Project Settings → Context; check that placeholders were resolved (the preview URL shows the real port and folder).
  5. 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).
  6. Read the assembled prompt the agent actually received: the daemon writes it to <work_path>/.heroagent/context_<ticket_id>.tmp for the run. Confirm your text is there, in the section you expected, once.
  7. 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?
  8. Roll out to existing projects only where wanted: open each project's Context settings and load the defaults or paste the new text. Running plans keep their old copy until you do.
  9. 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-patternWhat happensFix
Contradicting a hard rule from a lower layer ("in this project, you may use git directly")The model follows whichever it read last, unpredictablyNever contradict H1–H8; 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 IPPlaceholders in the global; localhost:<port> from the services block
The word "container" in a ticket or project contextThe agent starts running lxc/docker commands and breaksDescribe services at localhost; the platform routes commands
A rule with no example ("use good security practices")Ignored by small models, over-interpreted by large onesOne concrete example in real values, one negative example
A preventive rule for a failure nobody observedCosts 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 contextDrift: the two copies diverge after the next global editCross-reference by section number
think_mode: ultra as a project defaultEvery trivial ticket burns the maximum thinking budgetbalanced default; ultra per ticket for verify/peer/helper
Referencing a tool that does not exist in this runtime (Screenshot as a built-in)The model stops or inventsUse the MCP tool names; the global already says "match by suffix; a missing tool is not an error"
Business rules in the global contextThey leak into every other client's projectSpecification → project description + knowledge base
A ticket that says "as we discussed"The executing agent was not in the discussionSelf-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

  1. Take the customization of §6.5 and apply it to your training installation following the §6.10 protocol end to end. Attach: the diff, the assembled prompt excerpt, the transcript line where the agent writes CHANGELOG.md.
  2. 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.
  3. Find, in your training installation's projects, one project whose stored global context is older than the current file. Explain how you know, and update it without disturbing a running ticket.
  4. 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).
  5. 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.1 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: probe → knowledge → access gate → core slice

TicketPurposeProof it produces
Capability probe (#0)Verify what this installation can actually do: runtimes and versions, DB access, the preview URL, the services block, build tooling declared in the environment blockA SPEC FILE with one line per capability: available / missing. Missing runtime → the run stops with the fallback question (Module 3 §3.9)
Knowledge foundation (#1)Fill the knowledge base with the architecture, the stack, conventions and every key decision from the package, so the graph describes the project from day onecodehero_knowledge_list shows the decisions; later tickets find them at step 2 of the work loop
Application setupFolders, config bootstrap, schema, seed, shared header/footer; in a container: verify the provisioned services and configure the application-level piecesSchema applied, seed rows counted, skeleton page loads with 0 errors
Access gateThe 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 sliceThe 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 sizes the project and sets the cadence (Planning Guide §7.1): S (10–25 tickets, replan after each milestone), M (25–80), L (80–250, batches of about ten). CodeHero executes phase by phase: the planning ticket creates the first phase (about ten tickets), and the [REPLAN] ticket that ends each phase plans the next. Early tickets change what late tickets need; a fifty-ticket plan created up front is a plan that will be wrong by ticket twenty.

Revalidation follows the same cadence: one revalidation per milestone for S; after each contract and each functional piece for M and L, plus a final full revalidation for L.

7.4 Contracts before code

Two tickets that each "decide" a shared thing will decide it differently (guides/planning.md step 5: shared contracts are written before the tickets that consume them). Before any ticket that consumes another's output is created, the shared contract — schema, endpoint, field names, response shape, formula — is written into both SPEC FILES and the knowledge base, and repeated in each ticket's Contracts section. The Planning Guide's chain is contract → revalidate → module: a contract ticket writes it, a revalidation checks it, the modules build against it. A changed contract makes the affected evidence stale; the tests are re-run.

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: the client is contacted only for the four reasons. 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

BreakerTriggerWhat you do
Verify/fix loopSame part failed three fix→verify cycles; same acceptance item failed twice; builder and verifier disagreed twiceRead both views (the verifier's record lines and the fix ticket); decide; reply to the parked verifier with the decision
Replan repair loopThe same requirement still not aligned after three repair roundsRead the replan's comparison table and the repair tickets; decide whether the baseline or the code is wrong; reply to the replan
DebuggingFive 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 detectorIdentical actions repeatedThe hook already nudged the agent; if it hard-stopped, read the last tool calls, fix the ticket text or the environment, retry
Helper dialogueThree exchanges without agreementBoth views come to you; arbitrate
FallbackTicket #0 cannot provide the runtimeThe fallback changes an agreed capability → requirements change with the client, one line per affected requirement
WatchdogLong unproductive runTicket 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. Plan documentation tickets as junior_developer / basic near the end of each milestone, not as an afterthought at the end of the project.

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:

StepWhereNotes
Domain and SSLProject → Production Deployment; Settings → DomainsLet's Encrypt or custom certificates; the production config is generated per project
Web application firewallWAF setup (see the WAF guide)Keep it on; the agents are trained to bisect payloads, never to weaken it
Backups and restore drillProject → Backup & Restore; container snapshotsThe specification asked for a restore drill executed once — do it before go-live, not after
PHP settingsProject → PHP SettingsDevelopment tuning (errors visible, opcache revalidate) vs production values
Secrets.env in the project root, never in codeReal SMTP, payment and API credentials replace the day-0 placeholders here
Security gateThe package's automated security tests + the external pentest itemThe external pentest is tracked as external-pending; it blocks go-live sign-off only if the client's policy requires it

7.10 The operator's daily checklist

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 seeWhat it meansWhere the fix belongs
The agent claims a page works; the screenshot shows a 500A tool hid the error (blank body, stale log); the agent trusted textVerification recipe (LogTail, php -l); newer tool versions surface the error automatically
The agent "forgot" the plan mid-ticket and rebuilt somethingContext 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 diesH2: processes are killed at turn end; run_in_background is now denied by the hookTicket 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 decideAnswer "your call, record it"; if frequent, the context is unclear about the default stack
Two parallel tickets both edited header.phpParallel approved without the ownership analysis, or ownership lists missing from the descriptionsSerialize; H6; ownership table in the plan
Ticket text mentions codehero-12 or 10.0.3.xInfrastructure leaked into the ticketRewrite with localhost; never the word "container"
The verifier "fixed" the codeThe ticket title lost its [VERIFY] prefix, so the verify-fix guide was not pre-loadedKeep the prefix; the guide says "you only CHECK"
A finished helper ticket still openInitiator forgot to close itClose; it is in the initiator's checklist
A ticket stays awaiting_input for days and nothing behind it movesIt asked you something (NEEDS THE USER: yes) or waits for another ticket; a later sequence never starts until it is doneDaily checklist; answer in one batch, or close it
Every ticket burns the maximum thinking budgetultra set as project defaultbalanced default; ultra per ticket
Weak model loops on an easy PHP taskTools hid a PHP 500; loop detector saw A/B alternationVerification recipe first; the hook now catches cycles, not only identical repeats
Reviewer closed a ticket that actually asked a questionStrict/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

  1. 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).
  2. 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.
  3. 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.
  4. Plan the documentation tickets for RepairFlow phase 2 (roles, think modes, sequence, dependencies).
  5. 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:

  1. Interview the client with the Spec Builder (Module 2). Deliver a Ready to build package 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.
  2. Justify the stack (Module 3): the one-line decision, the environment block, and the answer to "why not a container?" (or "why a container?").
  3. Plan it in IMPORT MODE (Module 4). Before confirming, produce a written review of the preview: three changes you made and why.
  4. 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.
  5. Customize one thing (Module 6) that the run showed was needed — with the transcript that proves the need, the diff, the §6.10 test.
  6. 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 tickets planned; the day-0 items listed.

8.2 The rubric

AreaPassDistinction
InterviewEvery stage covered or consciously defaulted; four statuses used; critical items never Assumed; Stage P preview doneClient's own numbers appear in every business rule's example; dependency register has verification statuses; spreadsheet intake applied
StackCorrect default (PHP/MySQL unless a trigger fires); justification cites a requirement IDFallback stack reasoning correct; build vs runtime vs serving declared separately
PlanSerial, probe → knowledge → setup → access gate → core slice; VERIFY tickets on a different family with master+ultra; descriptions follow the five-part recipeA parallel group offered and correctly analysed, or correctly refused with the ownership reason
RunEvery question answered in one batch; no technical question answered by the human; helpers closed; snapshots existA breaker occurred and was arbitrated correctly; a safe default was overturned via the report's part 3
CustomizationObserved failure → rule → deployed → tested on a weak model → transcript proves behaviourThe rule is in the right layer, cross-references the global, and adds under 300 bytes
DeliveryCore slice acceptance list all pass or BLOCKED with reason; 4-part handoff; documentation plannedRestore 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.

  1. Name the two kinds of unknowns the agent meets, and who decides each. (Global §4)
  2. What does the agent do when a CRITICAL question has no answer and the run is autonomous? (Global §4.1, guides/asking.md)
  3. Which ticket statuses satisfy a dependency? Does awaiting_input? Does timeout? (Module 5 §5.1)
  4. 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)
  5. What is the shipped default of MAX_PARALLEL_TICKETS_PER_PROJECT, and what does that mean for a plan where two tickets share a sequence_order? (Module 4 §4.6)
  6. Why does the Spec Builder never name a provider or a model? (Planning Guide §1.2, §7.5)
  7. Which four things does the codehero_environment block declare separately, and which one alone decides container_required? (Module 3 §3.6)
  8. Where does a client's VAT rule belong, and where does it not belong? (Module 6 §6.2)
  9. What are the four parts of the handoff report, and which part contains the safe defaults? (Global §5 step 10)
  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)
  11. Name three "danger files" the ownership analysis checks by name. (guides/planning.md §2)
  12. Which file does the agent re-read first when it feels lost after compaction? (Global §6)
  13. What is the difference between a SAFE DEFAULT and a guessed business rule? (Global §4.1, guides/asking.md)
  14. Why must ticket descriptions never contain the word "container"? (Planner rule 8)
  15. A trainee wants to add a rule "always be careful with money". What do you ask for first? (Module 6 §6.4)
  16. A build ticket at sequence 3 is left awaiting_input by the reviewer. Can a ticket at sequence 4 start? Can a forced ticket at sequence 9? (Module 4 §4.6)
  17. 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:


APPENDICES

Appendix A — Quick reference cards

A.1 Ticket fields

FieldValuesDefault
sequence_orderinteger; unique ascending = serial; same = parallel grouprequired
depends_onbulk call: 1-indexed positions of the same call, earlier only · single create: existing ticket ids or ticket numbersnone
parent_sequence / parent_ticket_idearlier position / existing ticket idnone
ai_modelmaster_developer · senior_developer · junior_developerproject default
provideran active providerproject default
think_modeoff · basic · balanced · ultraproject default (balanced)
execution_modeautonomous · semi-autonomous · supervisedproject default (autonomous)
deps_include_awaiting1 relaxed (the auto-reviewer closes clean tickets) · 0 strict (you close each)1
ticket_typefeature · task · bug · debug · rnd · improvement · docsfeature
prioritylow · medium · high · criticalmedium
is_forced1 = forced start (Start Now / Force Next / codehero_start_ticket): starts now, ignores sequence, dependencies, parent and slots0

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) · new / pending (rare). A higher sequence starts only when every lower one is done or skipped.

A.3 Roles and think modes per ticket type (Spec Builder table)

Ticket typerolethink_mode
Planning, replan, contracts, architecture, securitymaster_developerultra
Verification / peer review / helper / replanmaster_developer (different provider for verify, peer and helper)ultra
Feature implementationsenior_developerbalanced
Repetitive work, docs formattingjunior_developerbasic
Tests and fixturessenior_developerbalanced

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_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, 11 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 · helper · debugging · frontend · database · build · testing · native.

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: end the turn with ⏸ WAITING-FOR-TICKET #<id>[, #<id>] — its reply will wake me + TASK COMPLETED; a reply wakes you; 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").

Appendix B — File map

PurposePath
Global context (source / installed defaults / daemon+assistant copy)config/global-context.md / /opt/codehero/config/global-context.md / /etc/codehero/global-context.md
Language contextsconfig/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) · context refreshscripts/message_hook.py · scripts/refresh_global_context.py
Context checkerstests/context/check_global_context.py · tests/context/check_test_runner.py
Spec Builder knowledge filedocs/CODEHERO_PLANNING_GUIDE.md (served at /docs/CODEHERO_PLANNING_GUIDE.md)
Assistant templatesconfig/assistant-*.md/etc/codehero/assistant-*.md
Provider ↔ role model map, think budgets, sub-agent rolesheroagent/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 hookscripts/claude-daemon.py · scripts/mcp_server.py · scripts/permission_hook.py
Agent and toolsheroagent/heroagent.py · heroagent/tools/ · heroagent/providers/
Per-ticket assembled prompt and conversation<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/
Logsjournalctl -u codehero-daemon · /var/log/codehero/daemon.log · /var/log/codehero/web.log

Appendix C — Reading list (in order)

  1. config/global-context.md — read it twice; it is the framework. Then config/guides/planning.md, verify-fix.md, helper.md, asking.md — the situations.
  2. docs/CODEHERO_PLANNING_GUIDE.md — Parts 1, 2, 3 and 7 first; Parts 4–6 as reference.
  3. config/assistant-planner.md — short; read it before your first import.
  4. config/contexts/php.md — the reference language context; then the context of your stack.
  5. User Guide chapters 8 (Execution Modes), 9 (Sequencing), 11 (Lifecycle), 13–16 (providers, roles, think mode, vision), 31 (Containers), 32 (Production).
  6. docs/SMARTCONTEXT.md — how compaction works and why the SPEC FILE exists.
  7. CHANGELOG.md — the incident history behind the rules.
  8. 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.1 — for CodeHero PRO 4.49+ (Global Context v6.1). The framework files cited here are the source of truth; when this course and a framework file disagree, the framework file wins and this course needs an update.