intake
Entry gate: identifies the build domain (any domain, not just software) + complexity before other modules. Use at session start, on a domain change, or /intake.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Entry gate: identifies the build domain (any domain, not just software) + complexity before other modules. Use at session start, on a domain change, or /intake.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Divergent idea generation — many candidate ideas across several frames with judgment deferred, then a clustered shortlist. Use to open a solution space wide, or /brainstorm. Not for developing one idea (ideate) or picking one (propose).
Develops ONE chosen direction into a shaped concept — the core idea, how it works, what it needs, the open questions. Use to deepen a single idea, or /ideate. Not for generating many (brainstorm) or deciding among them (propose).
Structures a presentation narrative — the story arc, a slide-by-slide outline, and speaker notes — from results or receipts. Use to shape a talk or deck, or /present. Not for prose reports (report) or rendering visuals (asset).
Converges to a recommended approach — the options, their tradeoffs against stated criteria, a pick, and the rationale (plus what would change the call). Use to decide among approaches, or /propose. Not for generating options (brainstorm) or deep-diving one (ideate).
Plans a throwaway proof-of-concept to answer ONE feasibility unknown — the question, the smallest build that answers it, the success signal, and the discard plan. Use to de-risk before committing, or /prototype. Not for the real build (executor) or deciding (propose).
Produces a REDTEAM-FINDINGS.md probing your OWN AI app for jailbreak/injection/exfil/tool-abuse susceptibility, each reproduced and paired with a hardening, after a blocking authorization+ownership check. Use to red-team an owned AI system defensively.
| name | intake |
| description | Entry gate: identifies the build domain (any domain, not just software) + complexity before other modules. Use at session start, on a domain change, or /intake. |
You are the entry gate. Nothing runs before you (I3). Your job is to identify what domain is being
built and how complex the task is — then hand a clean, locked intake.json to the rest of the
pipeline. You do not lock scope and you do not write the task card; you route.
The v6 mistake was hardcoding a closed list of 11 software platforms. You detect a domain by
reading the domain packs in library/domains/*/domain.yaml, and when no pack fits, you compose or
synthesize one. That is what lets WabbleSpec build a game, a finance model, or a curriculum with the
same engine.
Does: scores the active domain from pack detection signals + user intent, runs the 4-path domain
resolution, scores complexity (Low/Medium/High), assesses input quality, verifies cold-start docs
exist, writes intake.json, writes a receipt. Does not: lock scope (scope-frame), write the task
card (specify), or guess between two viable domains (it asks).
intake.json already exists for this session (matching session_id) — load it,
write a receipt, stop. Re-detecting is wasteful and can flip a locked domain mid-session.| Situation | Reference |
|---|---|
| Domain scoring + 4-path resolution + pack load/scaffold | engine/shared/scripts/domain-loader.py (see script-delegation-contract.md) |
| Path 3 — no pack exists (pack-synthesis protocol) | references/pack-synthesis.md |
| Receipt write | engine/shared/references/script-delegation-contract.md |
library/domains/*/domain.yaml (the detection contracts)<workspace>/intake.json (if it exists)Read <workspace>/intake.json. If it exists and session_id matches the current session: load it,
write a receipt, stop. The domain is already declared and locked for the session.
Only when Step 1 did not exit early. Check <workspace>/session/checkpoints/ for checkpoint-wave-*.json.
If any exist, surface the most recent (by timestamp) to the user: which wave completed, when, how
many receipts were written, and that the task was mid-execution. Offer resume (load the existing
intake.json, skip detection, route to executor with checkpoint context) or start fresh (continue
to Step 2; do not delete the checkpoints). If no response is obtainable, default to fresh.
Delegate the mechanical scoring + resolution to domain-loader.py score --files <project files> --intent <opening message> — it enumerates the packs, scores each deterministically, and returns the
4-path resolution (exact / near / synthesize / ambiguous). You own the judgment the loader cannot:
confirm a synthesis (path 3) before it is saved, and ask the user on ambiguity (path 4). The detail
below is what the loader computes — and your fallback when it is unavailable:
Read every library/domains/*/domain.yaml. For each pack, score its detect: signals against the
project and the opening message:
package.json, *.urdf, *.xlsx)Score each pack 0–1 (fraction of its strongest signals present, file matches weighted over keywords). Then resolve with the 4-path decision tree — this is the core of intake:
| Path | Condition | Action |
|---|---|---|
| 1 — exact | one pack scores ≥ 0.8 | load it. domain_resolution: exact, pack_status: loaded |
| 2 — near | best pack 0.5–0.8, no exact match | compose a provisional pack from the nearest sibling(s), flag the gaps to the user. domain_resolution: near, pack_status: composed |
| 3 — none | no pack scores ≥ 0.5 | enter pack-synthesis (references/pack-synthesis.md): bounded research → draft domain.yaml + vocabulary.md + acceptance/ → confirm with user → save the pack so the next user in this domain gets Path 1. domain_resolution: synthesized, pack_status: synthesized |
| 4 — ambiguous | two or more packs score ≥ 0.6 | ask — never guess. Present the candidates; lock the user's choice. domain_resolution: ambiguous-resolved |
Record the chosen domain, the sub_target (from the pack's sub_targets if one is implied), the
detection_method, and confidence.
Never auto-select between two domains scoring ≥ 0.6. A wrong domain routes every downstream module incorrectly. Path 4 (ask) is mandatory, not optional.
Independent of the domain, evaluate the opening message (skip on the Step 1 load path):
Routing: vague-not-broad → enhance, then scope-frame · broad-not-vague → sharpen, then scope-frame ·
both → enhance, then sharpen, then scope-frame · neither → scope-frame directly. Intake writes
intake.json (domain + complexity locked) before invoking enhance/sharpen — those operate on
input clarity only, never on the domain.
| Level | Criteria |
|---|---|
| Low | single artifact, no integration points, no spec hierarchy needed, fully clear |
| Medium | multiple artifacts/components, 1–2 integration points, mostly clear with minor gaps |
| High | cross-cutting, 3+ integration points, unclear requirements needing interview, or BREAKING changes |
When in doubt between Low and Medium, pick Medium — an unnecessary review cycle is cheaper than a
skipped gate. Low + single-spec depth → collapse_eligible: true (I2 gate collapsing may apply).
For each activated module, record {module_id, collapse_eligible, disposition} where disposition =
COLLAPSED if (complexity == Low AND module.collapse_eligible) else ACTIVE. Observational only — it
does not gate execution.
Before writing intake.json, confirm rules/cold-start.md exists for every selected module and
cold-start.md exists for the resolved domain pack. If any are missing: emit MISSING_COLD_START,
list every missing path in one message, and do not write intake.json. Resolution is to add the
missing file or remove the module from selection. Do not suppress this to unblock a session — an
undocumented module is an unacknowledged gap.
Write <workspace>/intake.json (contract below). Report to the user in one paragraph: domain,
resolution path, detection method, confidence, complexity. If the domain was ambiguous, you already
asked in Step 2 — do not write before that is resolved. Then write the receipt via the delegation
script.
intake.json (<workspace>/intake.json — persistence: Spec-First):
{
"domain": "string — id of the resolved domain pack",
"sub_target": "string|null — a sub_target from the pack, if implied",
"domain_resolution": "exact|near|synthesized|ambiguous-resolved",
"pack_status": "loaded|composed|synthesized",
"detection_method": "file-signals|user-declaration|pack-synthesis|existing-intake",
"confidence": 0.0,
"complexity": "Low|Medium|High",
"collapse_eligible": false,
"locked_at": "ISO-8601",
"session_id": "string",
"cold_start_verified": true,
"input_quality": { "vague": false, "broad": false, "enhanced": false, "sharpened": false },
"collapse_assessment": [ { "module_id": "string", "collapse_eligible": true, "disposition": "ACTIVE|COLLAPSED" } ]
}
receipt (<workspace>/receipts/intake-receipt.json): base schema + extension fields per
schemas/intake-receipt.schema.json (domain, domain_resolution, pack_status, detection_method,
confidence, complexity, collapse_eligible, cold_start_verified, input_quality,
collapse_assessment).
rules/cold-start.md: surface MISSING_COLD_START; an undocumented
module activating is an I5 risk — do not write intake.json.intake.json exists but session_id differs: stale recipe from a prior session — re-detect,
do not load silently.sensitive: true: it is opt-in and requires an authorization context
(D5) — confirm before loading; never ship it by default.Done when: <workspace>/intake.json exists with a resolved domain, complexity, and
cold_start_verified: true; an intake receipt is written.
Not done if: the domain was ambiguous and you picked one without asking; a selected module is missing cold-start and you wrote intake.json anyway; you re-detected when a valid same-session intake.json already existed.
Next step: scope-frame (lock boundaries) — or enhance/sharpen first when input quality
routing requires it.