Skip to content

t1k:cocos:playable:pipeline

FieldValue
Moduleplayable
Version2.14.4
Effortmedium
Tools—

Keywords: board, build job, client project, deliverable, git repo, jenkins, log tasks, module, plane, playable pipeline, provision repo, task tree, tracking, work item

/t1k:cocos:playable:pipeline
<report-or-breakdown> [--client <name>] [--playable <name>] [--no-jenkins] [--provision-repo] [--dry-run]

Cocos Playable — Plane + Jenkins Pipeline

Section titled “Cocos Playable — Plane + Jenkins Pipeline”

One playable becomes one Plane module under its client’s project, holding the whole task tree, plus one Jenkins job that builds it. This skill wires those two together from a source document that already exists — an agreed task breakdown, or a t1k:cocos:playable:preproduction estimate report.

Orchestrator only. Every Plane lifecycle mechanic — binding, state resolution by group, guarded writes, the 4-hour leaf cap, degrade-never-block — is owned by core’s skills/t1k-plane/references/workflow-enforcement.md and skills/t1k-plane/references/binding.md. Every Jenkins config.xml mechanic is owned by skills/t1k-jenkins-job/SKILL.md. This skill cites them and adds only the three things neither can know: the studio hierarchy convention, the required-task set for a playable, and the hand-off between the two systems.

IntentPath
”Log this estimate report to Plane”Workflow steps 1-4, then --no-jenkins
”Set up the full pipeline for this playable”Workflow, all steps
”Does this module have everything it needs?”Step 4 alone — see task-template.md
”Just the build job”Skip to step 5, or call t1k:jenkins-job directly
”Create the actual git repo for this playable”Step 6 — repo-provisioning.md. Playable already has a repo? Skip step 6
”Why is the title format like that?”hierarchy-contract.md
NeedCheckIf missing
Plane MCPmcp__plane__* tools loaded~/.claude/skills/t1k-mcp-management/scripts/install-plane.sh — prompts for the key with hidden input, so the user runs it, then restart Claude Code
Jenkins credsJENKINS_URL, JENKINS_USER, JENKINS_TOKEN in envt1k:jenkins-job § Setup. Never pass as argv, never echo
A source documentAn estimate report, or an agreed breakdown in-conversationRun t1k:cocos:playable:preproduction first — do not invent a task list
Repo provisioning (optional step 6)gh + git on PATH, gh auth status okrepo-provisioning.md — parent-dir prompt required first run

Plane absent is not fatal — core’s degrade rule applies unchanged: warn once and continue. A Jenkins job created with no Plane tree is still a valid partial outcome; say so explicitly rather than reporting success.

Delegation — the main session orchestrates, it does not do the work

Section titled “Delegation — the main session orchestrates, it does not do the work”

This skill’s inputs are large (a 350-line estimate report) and its writes are numerous (30+ work items, a Jenkins config.xml). Reading and performing all of that inline burns the main session’s context on material it never needs again. Default to delegating every step below that is marked fork; keep inline only what genuinely needs the conversation.

StepWhereWhy
1 BindinlineOne status call plus a judgment about the project. Cheap.
2 Read the source documentfork → ExploreThe report is the single biggest context cost in the skill. Return the § 9 line-item table as JSON, not prose, and never the report body.
3a Derive the treefork → ExploreSplitting rows to the 4h cap and reconciling against the report total is deterministic arithmetic over step 2’s JSON.
3b The ONE confirmationinline, alwaysCore requires the user see the whole tree before any write. A fork cannot ask.
3c Write the treefork → t1k-fullstack-developerBulk API writes. See the MCP warning below — the fork must drive Plane’s REST API, not mcp__plane__*.
4 Required-task checkfork → ExploreA set comparison against task-template.md. Read-only.
5 Jenkinsfork → t1k-fullstack-developerjenkins-job.cjs uses fetch, not MCP, so it works in a fork unchanged. Except the Discord thread ID — ask for that inline, before spawning.
6 Provision repo (optional)inline for the parent-dir prompt and any conflict/existing-repo stop; the run/plan call itself may be forkedPreflight, the parent-dir choice and merge-conflict handling are unresolved-decision points; the git/gh calls are deterministic.
7 Link backinlineOne comment and one URL.

Two separate savings, and they are not the same. Forking always protects the main session’s context. Whether the fork also runs on a cheap model depends on transparent routing, and the two floors below mean several obvious choices are not cheap. Do not promise a cost saving you have not checked against t1k-config-mr.json.

  • Explore is a read-only built-in with no spawn tool → routed via defaultBuiltInModel. This is the genuinely cheap lane, and it is why steps 2, 3a and 4 are shaped as read-and-return-JSON.
  • t1k-fullstack-developer is floored by DEVELOPER_SUFFIX_FLOOR (/-developer$/) and by declaring write tools, so it passes through to Anthropic at full rate. It still keeps the writes and their output out of the main session — that is the whole benefit; there is no model saving.

Explicit mr-delegate.sh is not needed here: the Task interceptor is the primary path and fires on an ordinary Task spawn. Reach for the t1k-model-router-delegate skill (ships with theonekit-model-router, not this kit) only to force a specific provider/model or to debug a routing decision.

workspace cocos <- the engine
project <Client> <- the CLIENT (publisher / partner)
module <Playable> <- the PLAYABLE (the deliverable)
work item <Client> | <Playable> | <task>
work item <Client> | <Playable> | <task>

This is core’s documented deliverable convention (binding.md § “What each hierarchy level means”), under which the module binding is REQUIRED, not optional — a repo bound to the project alone is a mis-binding, because every item then lands on the whole client’s board with nothing identifying which playable it belongs to.

The Client | Playable | Task title is a studio deviation from core’s [Discipline][Kind] Title taxonomy. It is deliberate, it is recorded, and it has a cost. Read hierarchy-contract.md before changing it.

Phase parents carry the prefix too — <Client> | <Playable> | First Build, not a bare First Build. Both spellings exist on the board today; the prefixed one is the convention this skill composes.

The separator changed from brackets to pipes on 2026-08-22. This skill used to compose [Client][Playable] Task; the live board never did. A board now holds three forms — pipe items, legacy [Client][Playable] items from the old composer, and unprefixed items. applyTo: "created-only" means none is ever renamed. Do not “fix” the old ones.

Steps 2, 3a, 3c, 4 and 5 are forked by default — see Delegation for which agent and why. Doing them inline is the exception, and worth a sentence saying why.

  1. Bind the repo. node $HOME/.claude/scripts/t1k-plane-binding.cjs status. Unbound → run core’s binding.md § “Repo → project” resolution. Two Cocos-specific notes:

    • Score projects against the client name, not the repo name. A repo called blast-fest scores near-zero against a project called Rollic, and that is the convention working, not a missing project. Never create a project to fix a low score — the client already exists.
    • The module is the playable. Missing → creating one is the right guarded write far more often than creating a project.
  2. Read the source document — fork to Explore; return the § 9 table as JSON, never the report body. An estimate report’s line-item table (preproduction § “Estimate — full line-item breakdown”) is the tree, already carrying per-row hours. A conversation breakdown is the tree as agreed. Never synthesise tasks that appear in neither. Mapping rules: report-ingest.md.

  3. Build the work-item tree — 3a derive and 3c write are forked; the confirmation between them is not. Core owns this entirely — workflow-enforcement.md § Stage 1 and § “Decomposition”. Do not reimplement the 4-hour leaf cap, the parent-carries-no-estimate rule, the get_me() assignment, or the one-confirmed-batch presentation. Compose each title with:

    Terminal window
    node $HOME/.claude/skills/t1k-cocos-playable-pipeline/scripts/pipeline-title.cjs compose \
    --client '<project name>' --playable '<module name>' --title '<task>'

    Pass the module name exactly as the board has it — compose() derives the playable segment itself, stripping a leading <client> | where a board uses one and passing a bare name through. Both live shapes therefore work unchanged; hierarchy-contract.md § “Why pipes” records the measured distribution. Single-quote every argument: <task> is report-derived text, and inside double quotes a title containing $(…) or a backtick would be executed by the shell.

    Core’s t1k-plane-taxonomy.cjs compose is still called — for its labels output only. The title it returns is discarded. See hierarchy-contract.md.

  4. Verify the required-task set — fork to Explore. Compare the module’s work items against task-template.md: the five-item phase skeleton, then the build packages under First Build. Only 2/2 rows count as missing — 1/2 rows are surfaced as consider, never as a gap. Report them; propose, never auto-create — the same rule core applies to work items applies here.

  5. Create the Jenkins job — fork; jenkins-job.cjs needs no MCP. Hand off to t1k:jenkins-job with the folder, the template job, and the playable name. Two of its rules bind hardest here:

    • Always ask for the Discord thread ID — inline, BEFORE spawning the fork. A fork cannot ask, and a routed hop has no user to ask even if it tried. Never inherit one from the template, from a previous playable, or from earlier in this conversation.
    • Smoke one job, verify it off the server, then continue — a 200 on createItem does not prove the config landed.
  6. Provision the repo — OPTIONAL, off by default; skip it whenever the playable already has a repo. scripts/provision-repo.cjs plan|run --playable '<name>' --parent-dir '<dir>' creates <org>/<Name>PLA from PlayableAdsTemplate with real main+develop history, runs SetupProject.bat on Windows, commits the result. Ask for (and persist) the parent dir; never auto-resolve a conflict or existing-repo hit. repo-provisioning.md.

  7. Link back. create_work_item_comment on the module’s parent work item with the Jenkins job URL, and hand the user a clickable Plane link built with t1k-plane-binding.cjs url --work-item <uuid> — no Plane tool returns a URL, and a bare ROLLIC-289 is not clickable.

  • A routed fork has NO MCP servers — so a fork cannot call mcp__plane__* at all. mr-delegate.sh launches the hop with --strict-mcp-config --mcp-config '{"mcpServers":{}}' (verified in the shipped script, not inferred from docs), which strips every server including Plane and Jenkins. A brief that says “create the work items with create_work_item” therefore fails inside a routed hop while working perfectly when you test it inline. Drive Plane from a fork through its REST API — POST {base}/api/v1/workspaces/{slug}/projects/{id}/issues/ with an x-api-key header, credentials read from the plane entry of ~/.claude.json. Jenkins is already safe: jenkins-job.cjs uses fetch.
  • Prefer one REST script over N MCP calls even inline. A 33-item tree is 33 create_work_item round-trips, plus one estimate call each. As a single Node script it is one Bash call, it can dry-run, it can reconcile the leaf total against the report before writing anything, and it can read every value back afterwards. That shape is also the only shape a fork can run.
  • Plane’s estimate endpoint is PUT .../issues/{id}/workload-estimate/. Not POST (405), not /estimates/ (404). Measured 2026-08-22. The hours reads back as null with a rollup on any parent — that is correct, not a failed write: parents derive from the sub-tree.
  • PLANE_WORKSPACE_SLUG may hold a full URL rather than a slug. On at least one machine it is https://plane.the1studio.org/cocos/. The MCP server normalises it internally, so the misconfiguration is invisible through the tools and only bites a script that builds the API path itself. Take the last non-empty path segment rather than using the value raw.
  • titleFormat cannot be configured to do this. Core’s t1k-plane-taxonomy.cjs throws on any titleFormat other than {discipline}{kind} {title}, because its parse() is the pinned exact inverse of its compose(). Setting planeWorkflow.taxonomy.titleFormat to a scope format breaks every Plane skill in the session, not just this one. The prefix is composed by this skill’s own script for exactly that reason.
  • Never append [3D][Feature] after the scope to “get both”. Core’s parse() reads tokens only at the start of the string, so Rollic | Blast Fest | [3D] X returns kind:null, discipline:null — the scope prefix blinds core to the taxonomy tokens that follow. The pipe change did not fix this; it is a scope-first problem, not a bracket problem. Measured, with the full table, in hierarchy-contract.md. Kind and discipline belong in labels.
  • Turning taxonomy.enabled: false to get the title you want also kills the labels. Stage 1 steps (a), (b), (c) and (e) are all skipped together. Labels are the only thing left carrying kind/discipline once the prefix is gone — keep the taxonomy enabled and discard only its title.
  • parse no longer needs core’s config, and no longer returns vocabularyChecked. Under the old bracket form [Client][Playable] and [Discipline][Kind] were structurally identical, so parse had to load core’s vocabulary to tell them apart and flag a degraded read when it could not. Pipes cannot collide with bracket tokens, so that whole path is deleted. If you find code reading vocabularyChecked, it predates 2026-08-22.
  • applyTo: "created-only" still holds. An item this skill matched is never renamed into the scope convention. An inconsistent board is a smaller failure than renaming a teammate’s item.
  • A low project score is the convention, not an error. See step 1.
  • The estimate report’s hours are per line item, not per leaf. A 6-hour row is an undecomposed leaf under core’s cap — split it before writing any estimate, never write the 6.
  • Jenkins Job/Create and Job/Delete are separate permissions. You may be unable to delete a job you just made. Never create a scratch job to try something out.
  • Estimate-report tasks and required-template tasks overlap but are not the same set. The report covers what was quoted; the template covers what every playable ships. Reconcile both, and report anything present in one and absent from the other.
  • Step 6 is optional and off by default — a playable on an existing repo never runs it. When it does: the clone dir MUST be <parent>/<Name>PLA exactly (SetupProject.bat reads its own folder name); an existing target repo or a develop merge conflict is a hard stop; non-Windows skips setup.

Binding a Cocos playable repo to its Plane client-project + playable-module, turning an existing breakdown or estimate report into the module’s work-item tree under the studio title convention, checking that tree against the required-task set, creating the playable’s Jenkins job, and linking the two. Not for: producing the breakdown itself (t1k:cocos:playable:preproduction), Plane lifecycle mechanics (t1k:plane), Jenkins config.xml mechanics (t1k:jenkins-job), triggering or watching builds, or any per-phase state transition during the cook (core’s Stage 2 already owns it).

  • skills/t1k-plane/references/workflow-enforcement.md — the enforced lifecycle (SSOT)
  • skills/t1k-plane/references/binding.md — the deliverable convention this skill instantiates
  • skills/t1k-plane/references/taxonomy.md — the title convention this skill deviates from
  • skills/t1k-jenkins-job/SKILL.md — the job mechanics step 5 delegates to
  • repo-provisioning.md — step 6 mechanics, SetupProject.bat details
  • t1k:cocos:playable:preproduction — produces the estimate report step 2 ingests
  • rules/plane-workitem-workflow.md (core, auto-loaded) — why any of this is mandatory