{"slug": "fcop-grew-a-project-tree", "title": "FCoP Grew a Project Tree", "summary": "FCoP, a multi-agent collaboration protocol, unexpectedly revealed a project tree structure during a workflow test with the CodeFlowMu system. The test, which used a simple Grid Runner mini-game as a probe, exposed that FCoP can express product evolution beyond task flow management. This structural change emerged when a second phase task referenced the first, creating a hierarchical task tree.", "body_md": "**Subtitle: How a Mini-Game Task Revealed Product Evolution Inside a Multi-Agent Workflow**\n\nAuthor: FCoP Maintainer · 2026-06-14\n\nNote: Some screenshots are from the Chinese CodeFlowMu console. They are included as workflow evidence; the key protocol signals are the task IDs, lifecycle states, and FCoP fields explained in the captions.\n\nI originally wanted the PM in CodeFlowMu to coordinate DEV, OPS, and QA around a small local mini-game.\n\nThe game turned out not to be the important part.\n\nThe task tree was.\n\nDuring one failed archive attempt, FCoP exposed something that had not yet been formally written into the protocol: **a project tree**.\n\nThis article is not really about the Grid Runner game itself. It is about a structural change that appeared while debugging a multi-agent workflow: FCoP was designed to manage task flow. In this run, it started to express product evolution.\n\n**FCoP** is a multi-agent collaboration protocol. Its core idea is simple: agents should not only “talk” in chat. Their work must land as files. Tasks, reports, review records, and lifecycle transitions all live inside the project directory, so that anyone can later inspect what happened, who did what, and whether the work was actually closed.\n\n**CodeFlowMu** is an AI collaboration workflow system built on top of FCoP. As ADMIN, I use a Web console to assign work to PM. PM then decomposes the work for DEV, OPS, and QA. The console makes the workflow easier to operate, but the real ledger still lives on disk: `TASK-*.md`\n\n, `REPORT-*.md`\n\n, and the lifecycle folders under `fcop/_lifecycle/`\n\n.\n\nThis test was not meant to build a large product. It was meant to check whether multiple roles could complete a full collaboration loop around a small target:\n\n```\nADMIN creates task → PM decomposes → DEV/OPS/QA execute → REPORT → review → archive\n```\n\nSo I chose a very small probe: **Grid Runner**.\n\nGrid Runner is a local HTML / CSS / JavaScript mini-game. The player moves on a grid, collects coins, avoids monsters, and reaches an exit. The rules are simple, but the task is still rich enough for DEV to implement, OPS to verify the local runtime path, and QA to actually play and score it.\n\n*Figure 1. The small game used as the workflow probe. The game itself was intentionally simple; the real test was whether PM, DEV, OPS, and QA could complete the FCoP loop around it.*\n\nOn June 13, I assigned the first task to PM through the console:\n\n```\nTASK-20260613-020\nGrid Runner v0.1\nthread_key: panel-task-020\n```\n\nPM followed the normal workflow and assigned work to DEV, OPS, and QA. After the reports came back, task 020 entered `done`\n\n.\n\nAt this point, everything looked ordinary. Nobody mentioned a “project tree.” Nobody mentioned “phase tasks.” It looked like a single completed task line.\n\nAfter the first version was accepted, the product did not stop.\n\nI assigned a second task to PM:\n\n```\nTASK-20260614-004\nGrid Runner Phase 2: product upgrade\nreferences:\n  - TASK-20260613-020\nthread_key: panel-task-020\n```\n\nThe goal of 004 was to turn the demo into a more product-like lightweight game: a main menu, five levels, power-ups, local progress storage, a result screen, and visual effects.\n\nPM then decomposed it:\n\n```\n005 DEV  Implement Phase 2\n006 OPS  Verify file:// execution\n007 QA   Playtest and accept\n008 DEV  Fix the missing magnet tile in level 4\n009 OPS  Re-check the fix\n```\n\nAt the time, I only saw this as “the next segment on the same line.” Task 020 was already complete; task 004 was the follow-up upgrade. My mental model was still a single-task model: **once 020 is done, it should be archivable.**\n\nIn the console, under `panel-task-020`\n\n, the structure was already visible: ADMIN-to-PM tasks 020 and 004 above, and PM-to-team execution tasks below. The tree was already on screen. I just had not yet read it as a tree.\n\n*Figure 2. CodeFlowMu console view. The UI is in Chinese, but the important protocol markers are the task IDs, panel-task-020, report_missing, and lifecycle states.*\n\nOn the morning of June 14, I clicked “Archive” on task 020 in the CodeFlowMu console.\n\nTask 020 was the initial Grid Runner version. DEV, OPS, and QA had all reported back. PM had already submitted a summary. The console showed it as completed. I expected it to move into `_lifecycle/archive/`\n\n.\n\nBut the archive did not go through.\n\nThe core message was: there were still open child tasks. At the protocol level, this was `CHILD_TASKS_OPEN`\n\n.\n\nI asked PM in the ADMIN ↔ PM chat:\n\nDo the child tasks of this one overlap with 004? Wasn’t 004 opened as a separate new task?\n\nMy confusion was concrete: 004 was clearly a later Phase 2 task. Why should it block the archive of 020?\n\nPM answered: this was not an ID collision. It was a parent-child relationship. Task 020 still had Phase 2 task 004 underneath it. Task 004 had then produced 005, 006, and 007; the QA path further led to 008 and 009. The lower tasks had to be closed before 020 could be archived.\n\nThen PM drew a text tree in the chat:\n\n```\n020  Grid Runner initial version\n└── 004  Phase 2\n    ├── 005–007  implementation, ops check, playtest\n    └── 008–009  bug fix and re-check\n```\n\n*Figure 3. PM explained the failed archive by drawing the task relation as a tree: 020 as the root, 004 as Phase 2, and 005–009 as execution / fix tasks.*\n\nThat was the first moment I saw the “project tree.”\n\nIt did not come from a protocol spec. It did not come from a dedicated UI prompt. It came from PM trying to explain why 020 could not be archived, by drawing the relationship that already existed on disk.\n\n*Figure 4. The archive attempt was blocked because child tasks were still open. This is where the single-task view broke down and the project-tree view became necessary.*\n\nAt that point, the meaning changed:\n\n```\n020 was no longer just the Grid Runner v0.1 task.\n020 had become the project root of the Grid Runner product line.\n\n004 was not an independent new project.\n004 was Phase 2 under 020.\n```\n\nSo `CHILD_TASKS_OPEN`\n\nwas not wrong.\n\nFrom a single-task view, 020 was complete. From a project-tree view, the Phase 2 branch below 020 had not yet closed. A phase can be complete while the whole project tree is not yet ready to archive.\n\nThis was not an AI agent inventing a new project management method.\n\nWhat actually mattered were several rules that already existed:\n\n```\nthread_key       tracks the same collaboration thread\nreferences       marks which delivery a task continues from\nparent           expresses parent-child relation\nREPORT           requires roles to write back results\nCHILD_TASKS_OPEN prevents a parent from being archived while children are open\n```\n\nAdd one ordinary behavior: after the first version was accepted, ADMIN assigned Phase 2, and PM decomposed it under the same collaboration thread.\n\nNobody had designed a “project tree” button. Nobody started by saying “we are building an Epic / Milestone hierarchy.” But those rules stacked together, and the disk began to express this structure:\n\n```\nProject Root → Phase → Execution Task → Fix Task → Archive\n```\n\nIn the actual Grid Runner run, it looked like this:\n\n```\nTASK-20260613-020  Grid Runner v0.1 / project root\n└── TASK-20260614-004  Phase 2 product upgrade\n    ├── TASK-20260614-005  DEV implementation\n    ├── TASK-20260614-006  OPS verification\n    ├── TASK-20260614-007  QA playtest\n    ├── TASK-20260614-008  DEV fix\n    └── TASK-20260614-009  OPS re-check\n```\n\nThis is what I call **controlled emergence**.\n\nIt is “emergence” because the project tree was not hard-coded in advance.\n\nIt is “controlled” because it was not random. It was constrained by the file protocol, task references, PM decomposition, and archive guards.\n\nThe rules were small. The original intention was narrow. But once a real project continued across versions, the structure appeared.\n\nAfter I recognized the tree in chat, I manually ran EVAL from the CodeFlowMu console.\n\nThis EVAL is not a formal audit, and it does not replace the FCoP ledger. It is an internal collaboration-state scan. It reads TASK files, REPORT files, and frontmatter under `_lifecycle/`\n\n, then writes suspected structures into `GAP-*-panel-scan.md`\n\nunder `fcop/internal/eval/`\n\n.\n\nThe scan reported `project_tree_emergence`\n\n:\n\n```\nRoot task: TASK-20260613-020\nPhase task: TASK-20260614-004\nExecution tasks: TASK-20260614-005, 006, 007, 008\nPattern: main task -> phase task -> execution task\nValue: FCoP has emerged product-evolution tree and project-management capability from task-flow management\n```\n\nThis means the tree was not only an explanation PM drew in chat. The file relationships themselves were readable by a program.\n\nStill, EVAL should be treated as heuristic cross-checking. Sometimes it also identifies smaller local fix chains as subtrees, such as `004 → 007 → 008`\n\nor `004 → 008 → 009`\n\n. Those local readings are useful, but they do not replace the canonical reading: **020 is the project root of the Grid Runner product line, and 004 is Phase 2 under it.**\n\n*Figure 5. EVAL also detected local project-tree slices. This supported the observation, but the canonical reading remains 020 → 004 → 005/006/007/008.*\n\nSo the external story should still be grounded in TASK / REPORT / archive paths. EVAL only shows that the human intuition and the programmatic scan aligned.\n\nMy confusion did not come from a protocol error.\n\nThe opposite is closer to the truth: the protocol was protecting consistency. Since open child tasks remained below the parent, the parent could not be archived.\n\nThe real issue was that the console still mainly presented the workflow as a flat task lifecycle. It had not yet exposed the Project / Phase / Execution layer.\n\nAs a result, the same screen could mix several states:\n\n```\ndone              this delivery of 020 was completed\nreport_missing    some child path was still missing a report\nCHILD_TASKS_OPEN  the root still had open children\n```\n\nEach state made sense on its own. But together, they looked contradictory to ADMIN: if the task is done, why can it not be archived?\n\nOnce the project-tree view appears, the contradiction disappears:\n\n```\nphase complete ≠ project tree closed\ntask done ≠ root node archivable\n```\n\nThis is not protocol debt. It is product-expression debt.\n\nCodeFlowMu should add three things next:\n\n`CHILD_TASKS_OPEN`\n\n; it should list which Phase and which child task are still open.ADMIN’s real intent was simple: **020 had been accepted; continue with a Phase 2 product upgrade.**\n\nBut PM made a “project-manager-like” structural choice during execution: Phase 2 was kept inside the same `panel-task-020`\n\nthread, and the disk formed a ** 020 → 004 product-evolution tree**.\n\n**That is the emergence point.** It was not simply that ADMIN phrased the request incorrectly, nor that PM wrote a wrong field. Product intent and lifecycle representation overlapped in the same collaboration thread, and the tree shape grew out of that overlap.\n\nThis was not a simple mistake. It was two layers of truth stacked together:\n\n| Layer | Judgment |\n|---|---|\n| Product semantics | ✅ Reasonable. 004 really was Grid Runner Phase 2, continuing from 020. |\n| Lifecycle semantics | ⚠️ Risky. If 004 enters the same thread / parent relationship before 020 is fully archived, 020 can be blocked by `CHILD_TASKS_OPEN` . |\n| Protocol capability | ✅ Emergent. FCoP grew a structure from “task flow” into “project root → phase → execution line.” |\n| Console expression | ❌ Insufficient. The console still presented a single-task lifecycle, so users saw `done` , `report_missing` , and `child_open` mixed together. |\n\nGrid Runner itself was just a mini-game. **The structure produced by the collaboration was more important than the game.**\n\nOriginally, FCoP only had a task flow:\n\n```\nADMIN → PM → DEV/OPS/QA → REPORT → REVIEW → DONE\n```\n\nBut this Grid Runner run produced another shape:\n\n```\nProject Root → Phase → Execution Tasks → Fix Line → Final Close\n```\n\nThe tree on disk looked like this, consistent with the ASCII tree PM drew in chat:\n\n```\nTASK-20260613-020  Grid Runner v0.1 / static-game milestone\n└── TASK-20260614-004  Phase 2 product upgrade\n    ├── 005 DEV\n    ├── 006 OPS\n    ├── 007 QA\n    ├── 008 DEV fix\n    └── 009 OPS fix\n```\n\nThis matches the internal EVAL observation: it identified `020→004→005/006/007/008`\n\nas a “main task → phase task → execution task” project tree, and judged the value as: FCoP emerged product-evolution tree and project-management capability from task-flow management.\n\n**The final reading should be consistent across the article, archive behavior, and future spec:**\n\n`thread_key`\n\nis the same, and `references`\n\n/ `parent`\n\nrelationships are valid.`done/`\n\ndoes not mean the whole tree can be archived`CHILD_TASKS_OPEN`\n\nis reasonable. It is not a console bug. It is the protocol protecting tree consistency.The valuable discoveries are:\n\n`done`\n\nstate to whole-tree archive, everything happened inside the same collaboration thread.`parent`\n\n, `thread_key`\n\n, and `references`\n\nalready carry project-tree semantics`done`\n\n, `report_missing`\n\n, and `child_open`\n\ncan appear together and confuse the user. The tree exists in files; the UI has not caught up.In one sentence: this was controlled emergence. Grid Runner grew from a normal task flow into a product-iteration tree. **020 is the project root, and 004 is Phase 2, not a separate project.** Nobody added a new button for this. Existing protocol rules, real execution, and archive constraints stacked together. The shape became readable, auditable, and blockable. That is the life of a protocol.\n\nI will remember this Grid Runner two-line run as a case of **controlled emergence** in FCoP.\n\nThe core was **not** that AI invented project management.\n\nIt was this combination:\n\n```\nparent\nthread_key\nreferences\nPM Phase planning\nCHILD_TASKS_OPEN\n```\n\nTogether, these rules naturally formed a project tree.\n\nSo FCoP should not avoid this phenomenon. It should absorb it.\n\n**In one sentence: FCoP grew a project tree; now the protocol needs to write it down.**\n\nThis section keeps only **links and key excerpts**. The full source files are not pasted here, to avoid turning the article into a log dump. Primary TASK / EVAL originals from the CodeFlowMu dogfood run are catalogued in the [evidence archive](https://github.com/joinwell52-AI/FCoP/blob/main/essays/from-mini-game-to-project-tree-evidence/INDEX.md); figures in this essay live under [ essays/assets/](https://github.com/joinwell52-AI/FCoP/tree/main/essays/assets).\n\n| Evidence | Reference | Why it matters |\n|---|---|---|\n| Original task |\n`TASK-20260613-020` |\n\n`thread_key: panel-task-020`\n\n.`TASK-20260614-004`\n\n`references: TASK-20260613-020`\n\n, same thread.`GAP-20260614-004-panel-scan`\n\n`project_tree_emergence`\n\n.The key fields can be compressed into four lines:\n\n```\nTASK-20260613-020: thread_key = panel-task-020\nTASK-20260614-004: references = TASK-20260613-020\nEVAL: project_tree_emergence\nArchive guard: CHILD_TASKS_OPEN\n```\n\nThe internal EVAL scan identified the Grid Runner line as a project tree:\n\n```\nTASK-20260613-020  Grid Runner v0.1 / project root\n└── TASK-20260614-004  Phase 2 product upgrade\n    ├── TASK-20260614-005  DEV execution\n    ├── TASK-20260614-006  OPS verification\n    ├── TASK-20260614-007  QA playtest\n    └── TASK-20260614-008  DEV fix\n```\n\nIts canonical reading was:\n\n```\n020 → 004 → 005 / 006 / 007 / 008\n```\n\nIn other words: **main task → phase task → execution task**.\n\nEVAL also detected smaller local fix chains, such as:\n\n```\n004 → 007 → 008\n004 → 008 → 009\n```\n\nThose local observations are useful, but they do not replace the main-line interpretation: **020 is the project root of the Grid Runner product line, and 004 is Phase 2 under 020.**\n\nThe table below explains the FCoP terms used in this article without requiring readers to know Chinese.\n\n| Term | Meaning in this article | Protocol marker |\n|---|---|---|\n| Collaboration thread | A continuous line of work that keeps related tasks together. In this case, Grid Runner stayed under the same thread. |\n`thread_key` , here `panel-task-020`\n|\n| Continues from | A task explicitly builds on an earlier task or delivery. Phase 2 continued from the v0.1 task. | `references` |\n| Parent task | A task that owns or contains lower-level tasks. A parent should not be archived while its children are still open. | `parent` |\n| Open child tasks | Lower-level tasks are still not fully closed. This is why the archive attempt was blocked. | `CHILD_TASKS_OPEN` |\n| Internal EVAL scan | A CodeFlowMu internal scan that reads TASK / REPORT files and detects possible workflow structures. It is supporting evidence, not the formal ledger. | `GAP-*-panel-scan.md` |\n| Project-tree emergence | The observed pattern where FCoP task flow began to express a product structure: project root → phase → execution → fix. | `project_tree_emergence` |", "url": "https://wpnews.pro/news/fcop-grew-a-project-tree", "canonical_source": "https://dev.to/joinwell52/fcop-grew-a-project-tree-1oo", "published_at": "2026-06-15 02:17:57+00:00", "updated_at": "2026-06-15 02:40:42.561802+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "machine-learning"], "entities": ["FCoP", "CodeFlowMu", "Grid Runner", "PM", "DEV", "OPS", "QA"], "alternates": {"html": "https://wpnews.pro/news/fcop-grew-a-project-tree", "markdown": "https://wpnews.pro/news/fcop-grew-a-project-tree.md", "text": "https://wpnews.pro/news/fcop-grew-a-project-tree.txt", "jsonld": "https://wpnews.pro/news/fcop-grew-a-project-tree.jsonld"}}