diff --git a/skills/uipath-maestro-case/SKILL.md b/skills/uipath-maestro-case/SKILL.md index 6becfa1fb1..e55a89781e 100644 --- a/skills/uipath-maestro-case/SKILL.md +++ b/skills/uipath-maestro-case/SKILL.md @@ -30,10 +30,10 @@ When `sdd.md` is absent, **Phase 0** designs the case by best assumption from th 1. **Phase 0 best-assumption design when `sdd.md` absent.** Listen and ground, then decide every open field per the assumption playbook — inform, don't interrogate: every assumption, override, and resource decision is disclosed in the single confirmation's `Decisions I Made` table. The confirmation is a decision-first **Case Review** with exactly eight sections: Case Snapshot, Primary Journey, Other Paths Considered, SLA and Escalations, Rules and Outcomes, Resources and Integrations, Decisions I Made, and Review Flags. It names every stage and task with task type, activation/grouping, required status, routing/outcome, and SLA context; it deliberately omits the data contract, variables, and task inputs/outputs, which remain complete in `sdd.md`. It must be complete enough to approve the business behavior without opening `sdd.md`; do not defer a missing business decision by saying it will be in the document. This structured Case Review is the only valid plan-first approval surface for Phase 0; a generic "Build Plan" / "Approve this plan" checkpoint does not count, and a user "Yes" to that checkpoint is not a Build answer. Question budget: one clarifying call (only for an empty request, contradictory inputs, user-requested questions, or no source signal for other paths) plus ONE confirmation ([phase-0-interview.md § Confirm](references/phase-0-interview.md#confirm--the-single-checkpoint)). If `sdd.draft.md` exists and the user asks to finalize it, use the direct draft-resumption path in this skill: read the draft and SDD template, render the final `sdd.md` from the Case Management template, do not spawn subagents, do not preload planning/plugin references, and never delegate to `uipath-planner`. **Direct finalization repairs schema-required companion rules as row replacements, not extra routes: for an authored `user-selected-stage`, replace each eligible origin's existing `required-tasks-completed | exit-only | Yes` row with the single row `required-tasks-completed | wait-for-user | Yes`; never retain the old completion row or add a `Marks Stage Complete: No` duplicate.** `wait-for-user` exposes the picker; it does not add automatic event/SLA/decision routing. On a Build answer, render `sdd.md` from the in-memory model batched with the first build actions — the file MUST pass the template-conformance gate in `phase-0-interview.md`; a summary SDD is invalid even if `caseplan.json` later validates. Explicit sign-off requests add one approval prompt; design-only requests save `sdd.md` and stop; draft requests save `sdd.draft.md` and stop. When the prompt explicitly says to get/save a draft and stop, that request is already the save instruction: show the Case Review, write `sdd.draft.md`, and stop without asking for another approval. When the prompt explicitly asks to produce `sdd.md` plus `tasks/tasks.md` and stop before `caseplan.json`, use the bounded no-build fast path in `phase-0-interview.md`: after the Case Review, write the full-template `sdd.md`, create `tasks/`, write compact `tasks/tasks.md`, and stop; do not read planning/plugin references, tenant discovery sources, or the full SDD finalization checklist. Never overwrite an existing `sdd.md`. 2. **sdd.md is sole input post-Phase-0 — across sessions.** When user-provided, or in any later session, re-run, or staleness recovery (context compaction), trust `sdd.md` as written; the skill does not validate or gap-fill it. Within the session that just confirmed the design, the in-memory model that rendered `sdd.md` is the same content and drives the build directly ([phase-0-interview.md § Build start](references/phase-0-interview.md#build-start--sdd-written-alongside-the-build)) — do not re-read the just-written file. If a build-phase ambiguity arises, use AskUserQuestion — never infer silently. -3. **PHASE 1 HARD GATE — fresh registry before planning, pulled at most once per session.** Run `uip login status --output json`, then `uip maestro case registry pull`, before cache inspection, carryover reuse, resource resolution, or any Phase 1 artifact write — **same-session fast path:** when Phase 0's pull already succeeded in THIS session and `sdd.md` was just rendered from the confirmed in-memory model, reuse that cache and skip the re-pull. Any doubt runs the gate in full: user-provided SDD, cross-session resume, context compaction, a Phase 0 pull that failed or never ran, or missing cache files. **Plan-only exception:** if the user explicitly asks to stop at `sdd.md`/`sdd.draft.md`/`tasks.md` and not create `caseplan.json`, do not run tenant registry, connection, schema, or user-discovery commands; preserve concrete intended resource/system names, mark identities `resolve at build`, and report that resource wiring is deferred to the later build run. Trust the SDD as written; the pull refreshes the local discovery cache and does not validate or override the SDD. **Cache-state rule:** before a successful pull (this session), a missing cache directory/file is a failed refresh precondition — never a zero-match result. Only after a successful pull may an empty exact-name match set (or a still-absent type index) enter the normal empty-lookup flow. Login/pull failure → surface it and stop Phase 1. Discovery reads `~/.uip/case-resources/-index.json` directly because `registry search` has known gaps (esp. action-apps). Phase 0 pulls lazily only for build runs: the same login/pull chain starts in the background only when the case first shows tenant-bound work and a later build may need identities, followed by one light name-match pass — no schema discovery, no resource prompts; unclear items defer to this gate as `resolve at build`. See [references/registry-discovery.md](references/registry-discovery.md). +3. **PHASE 1 HARD GATE — fresh registry before planning, pulled at most once per session.** Run `uip login status --output json`, then `uip maestro case registry pull`, before cache inspection, carryover reuse, resource resolution, or any Phase 1 artifact write — **same-session fast path:** when Phase 0's pull already succeeded in THIS session and `sdd.md` was just rendered from the confirmed in-memory model, reuse that cache and skip the re-pull. Any doubt runs the gate in full: user-provided SDD, cross-session resume, context compaction, a Phase 0 pull that failed or never ran, or missing cache files. **Plan-only exception:** if the user explicitly asks to stop at `sdd.md`/`sdd.draft.md`/`tasks.md` and not create `caseplan.json`, do not run tenant registry, connection, schema, or user-discovery commands; preserve concrete intended resource/system names, mark identities `resolve at build`, and report that resource wiring is deferred to the later build run. Trust the SDD as written; the pull refreshes the local discovery cache and does not validate or override the SDD. **Cache-state rule:** before a successful pull (this session), a missing cache directory/file is a failed refresh precondition — never a zero-match result. Only after a successful pull may an empty exact-name match set (or a still-absent type index) enter the normal empty-lookup flow. Login/pull failure → surface it and stop Phase 1. Discovery reads `~/.uip/case-resources/-index.json` directly because `registry search` has known gaps (esp. action-apps) — but always as a **targeted lookup** (`cat ... | python3 -c "..."` filter per [registry-discovery.md](references/registry-discovery.md), or a bounded Read); NEVER load a whole index file into context. Full-index Reads bloat the context and tax every later turn's prompt-cache replay for the rest of the session. Phase 0 pulls lazily only for build runs: the same login/pull chain starts in the background only when the case first shows tenant-bound work and a later build may need identities, followed by one light name-match pass — no schema discovery, no resource prompts; unclear items defer to this gate as `resolve at build`. See [references/registry-discovery.md](references/registry-discovery.md). 4. **`--output json` on every parsed read.** 5. **Follow plugin per node type.** Open matching `planning.md` during planning + `impl-json.md` during execution. Never guess JSON shapes from memory. -6. **`tasks.md` declarative and lossless only.** No shell commands inside. Field names use plain identifiers (e.g., `type:`, `displayName:`, `lane:`), not CLI flag syntax. One T-entry per sdd.md declaration — every stage, task, trigger, condition, SLA rule, **variable, and argument** gets own T-number, even when value looks like default (`current-stage-entered`, `case-entered`, `exit-only`, `is-interrupting: false`, `runOnlyOnce: true`, `marks-stage-complete: true`). Never group, never silently omit. **An explicit stage/task entry or exit rule in a supplied or approved SDD is authoritative: planning and implementation preserve that exact rule and its selectors, even when a different rule would normally be inferred from task proximity or list order.** Preserve every stage/task/SLA `Design Rationale` and condition routing/activation rationale as `rationale:` on the matching T-entry; rationale is reviewer/audit context and never changes the executable JSON shape. Preserve every SDD Inputs row with its declared binding mode and value. A JSON object literal stays literal through both handoffs: record the exact JSON in `tasks.md`, then write either the native object or its JSON-encoded string to `input.value`; never add `=js:` or `=jsonString:` unless the SDD itself explicitly uses that prefix. Project every task/rule Outputs table row through the common grammar in [`plugins/variables/io-binding/planning.md`](references/plugins/variables/io-binding/planning.md#sdd-outputs-table-to-tasksmd-projection-mandatory), then preserve each resulting `outputs:` item **with its operator and both operands unchanged**. SDD Outputs rows require `->` or `=`; a bare `tasks.md` output is generated only from resolved-schema discovery and is never authored as an SDD row. SDD table placeholders such as a `—` Field are not operands and never appear in `tasks.md`. In particular, `greeting -> greeting` is NOT equivalent to schema-discovered bare `greeting`: the former extracts into the predeclared case variable and requires `originalVar`; the latter auto-mints a task-local output. Never simplify an equal-name `->` row. **When an sdd.md row's format is unrecognized, ambiguous, or cannot be categorized — invoke AskUserQuestion before skipping. Silent omission is forbidden.** Always regenerate from scratch (greenfield/planning only — brownfield targeted edits mutate in place and preserve IDs; see [references/brownfield.md](references/brownfield.md)). **Every §4.6 task T-entry carries its own `activation-mode:` and `entry-rule:` lines — a separate §4.7 `rule-type:` entry does not satisfy this.** **Every task T-entry heading quotes the task's display name** in the exact form `## T: Add task "" to ""` (e.g. `## T08: Add wait-for-timer task "First Step" to "Process"`) — an unquoted or reworded heading (e.g. `## T08: Task First Step`) breaks plan addressability and fails plan validators even when `caseplan.json` itself is correct. See [`references/planning.md` §4.0](references/planning.md) and the [Plan-shape gate](references/planning.md#step-5--finalize-tasksmd-auto-proceed-to-phase-2). +6. **`tasks.md` declarative and lossless only.** No shell commands inside. Field names use plain identifiers (e.g., `type:`, `displayName:`, `lane:`), not CLI flag syntax. One T-entry per sdd.md declaration — every stage, task, trigger, condition, SLA rule, **variable, and argument** gets own T-number, even when value looks like default (`current-stage-entered`, `case-entered`, `exit-only`, `is-interrupting: false`, `runOnlyOnce: true`, `marks-stage-complete: true`). Never group, never silently omit. **An explicit stage/task entry or exit rule in a supplied or approved SDD is authoritative: planning and implementation preserve that exact rule and its selectors, even when a different rule would normally be inferred from task proximity or list order.** Anchor every stage/task/SLA `Design Rationale` and condition routing/activation rationale on the matching T-entry as `rationale-ref: SDD §
` — `tasks.md` sits next to `sdd.md`, so the anchor is lossless; write `rationale:` prose only when the T-entry implements a choice whose rationale the SDD does not state. Rationale is reviewer/audit context and never changes the executable JSON shape. Preserve every SDD Inputs row with its declared binding mode and value. A JSON object literal stays literal through both handoffs: record the exact JSON in `tasks.md`, then write either the native object or its JSON-encoded string to `input.value`; never add `=js:` or `=jsonString:` unless the SDD itself explicitly uses that prefix. Project every task/rule Outputs table row through the common grammar in [`plugins/variables/io-binding/planning.md`](references/plugins/variables/io-binding/planning.md#sdd-outputs-table-to-tasksmd-projection-mandatory), then preserve each resulting `outputs:` item **with its operator and both operands unchanged**. SDD Outputs rows require `->` or `=`; a bare `tasks.md` output is generated only from resolved-schema discovery and is never authored as an SDD row. SDD table placeholders such as a `—` Field are not operands and never appear in `tasks.md`. In particular, `greeting -> greeting` is NOT equivalent to schema-discovered bare `greeting`: the former extracts into the predeclared case variable and requires `originalVar`; the latter auto-mints a task-local output. Never simplify an equal-name `->` row. **When an sdd.md row's format is unrecognized, ambiguous, or cannot be categorized — invoke AskUserQuestion before skipping. Silent omission is forbidden.** Always regenerate from scratch (greenfield/planning only — brownfield targeted edits mutate in place and preserve IDs; see [references/brownfield.md](references/brownfield.md)). **Every §4.6 task T-entry carries its own `activation-mode:` and `entry-rule:` lines — a separate §4.7 `rule-type:` entry does not satisfy this.** **Every task T-entry heading quotes the task's display name** in the exact form `## T: Add task "" to ""` (e.g. `## T08: Add wait-for-timer task "First Step" to "Process"`) — an unquoted or reworded heading (e.g. `## T08: Task First Step`) breaks plan addressability and fails plan validators even when `caseplan.json` itself is correct. See [`references/planning.md` §4.0](references/planning.md) and the [Plan-shape gate](references/planning.md#step-5--finalize-tasksmd-auto-proceed-to-phase-2). 7. **`tasks.md` gate — auto-approved by default, opt-in stop.** Phase 1 auto-proceeds into Phase 2 Prototyping with no AskUserQuestion sign-off; treat the plan as approved. **Stop after `tasks.md` only when the request explicitly asked for a plan-only / review-first run** (e.g. "just the plan", "Phase 1 only", "stop after tasks.md for review", "don't build the case yet") — then report the plan and do NOT proceed to Phase 2. Re-read `tasks.md` before executing. 8. **Unresolved resource → placeholder, never fabricate IDs.** Keep `` markers in `tasks.md`. Placeholder **task**: node with `type` + `displayName` + structural fields, `data: {}`; conditions still reference the TaskId. Placeholder **event trigger**: node with render fields + `data.uipath: { serviceType: "Intsvc.EventTrigger" }` only (no other `data.uipath` keys); `entry-points.json` entry appended. No trigger-edge is created (Rule 20). See [references/placeholder-tasks.md](references/placeholder-tasks.md) and [references/plugins/triggers/event/impl-json.md § Placeholder fallback](references/plugins/triggers/event/impl-json.md). 9. **Persist every registry resolution to `registry-resolved.json`** — one object per task with exact keys `stage`, `task`, `taskType`, `cacheFile`, `searchQuery`, `matches`, `selected`, and `rationale` (plus resolved I/O/review metadata when applicable). `stage` + `task` associate the audit entry to one SDD declaration; `cacheFile` is the basename actually searched; `matches` is the full exact-name match set from the cache refreshed in Rule 3, not a summary. Use the authoritative SDD fields as the search and selection contract; record `selected` from that match set, or `null` after a genuine empty lookup. @@ -239,7 +239,7 @@ Completion report + **HARD STOP** AskUserQuestion (Step 13): `Run debug session` - **Do NOT ship a summary `sdd.md`.** The written SDD must preserve the template's title, table of contents, Section 1/2/3/4 headings, case metadata/triggers/variables, one full stage block per stage, one full task block per task, personas/app views, and integrations. A valid `caseplan.json` does not prove the SDD followed the template. - **Do NOT plan only the primary flow.** Phase 0 must sweep for **Other Paths Considered** before confirmation: rework, rejection, withdrawal/cancellation, SLA escalation, external-system failure, manual override, optional side work, and alternate terminal outcomes. Model clear signals by assumption; ask one bounded question only when the source has no signal at all. - **Do NOT validate after each T-entry.** Intermediate states expected invalid. Run `validate` once at end of Phase 2 (informational) and once in Phase 4 (authoritative). -- **`tasks.md` (Phase 1) uses per-section batched Edit-append — NOT per-T-entry, NOT one mega-Write.** One Read + N Edit-appends per section (§4.2.1 vars, §4.3 triggers, §4.4 stages, §4.6 tasks, §4.7 conditions, §4.8 SLA). No re-Read between sibling Edits. **HARD CAP:** after §4.0a Step 1 Seed Write (<1KB header), single Write of whole `tasks.md` is FORBIDDEN regardless of size. Single Edit-append payload >30KB also FORBIDDEN — split per section even if cumulative payload exceeds 30KB. A 96KB tasks.md Write costs ~360s in one turn (20% of session); section-batched Edit-appends spread across ~7 turns of ~50s. TaskUpdate per T-entry preserves audit trail. Recovery on interruption: re-Read `tasks.md`, resume from next un-applied T-entry. See [planning.md § 4.0a](references/planning.md). +- **`tasks.md` (Phase 1) uses per-section batched Edit-append — NOT per-T-entry, NOT one mega-Write.** One Read + N Edit-appends per section (§4.2.1 vars, §4.3 triggers, §4.4 stages, §4.6 tasks, §4.7 conditions, §4.8 SLA). No re-Read between sibling Edits; sibling Edits MUST share one assistant turn when each payload stays ≤30KB — separate turns pay TTFT + cache replay for nothing. **HARD CAP:** after §4.0a Step 1 Seed Write (<1KB header), single Write of whole `tasks.md` is FORBIDDEN regardless of size. Single Edit-append payload >30KB also FORBIDDEN — split per section even if cumulative payload exceeds 30KB. A 96KB tasks.md Write costs ~360s in one turn (20% of session); section-batched Edit-appends spread across ~7 turns of ~50s. TaskUpdate per T-entry preserves audit trail. Recovery on interruption: re-Read `tasks.md`, resume from next un-applied T-entry. See [planning.md § 4.0a](references/planning.md). - **`caseplan.json` (Phase 2 + 3) uses per-section batched writes — NOT per-T-entry.** One Read at section entry + one validate at section end. Tool primitive scales with section size: **<10 T-entries** → N Edits (one per T-entry, no re-Read between siblings); **≥10 T-entries** → may use single whole-section Write covering the section's nodes array at once, AFTER composing complete section state in reasoning. Untouched siblings (other sections, root fields) MUST be preserved verbatim from the Read — drop nothing. TaskUpdate per T-entry preserves audit trail regardless of write granularity. CLI-gated sections (Phase 2 §4.6 non-connector `tasks describe`, Phase 3 §9.7 connector `case spec`) use gather-then-write. Recovery on interruption: re-Read both files, resume from next un-applied T-entry. Full contract in [case-editing-operations.md § Per-section batch write contract](references/case-editing-operations.md#per-section-batch-write-contract--canonical) and [implementation.md § Per-plugin execution](references/implementation.md). - **Do NOT emit standalone text-only assistant turns between tool calls.** Status/progress text MUST share its turn with the next `tool_use` (text block + tool_use block in the same assistant content array). Standalone narration turns each pay full inference latency + prompt cache replay (~5s + ~250K cache-read tokens per turn) for no incremental progress. Cap inline status to ≤1 sentence / ~20 tokens. Per-T-entry audit lives in TaskUpdate, NOT in narration. - **HARD TOKEN CAP on any single text block: 200 tokens, no exceptions outside the allow-list below.** Allow-listed text blocks (the once-per-run kickoff flow overview, hard-stop AskUserQuestion preambles, Phase 5/6 completion reports, `Publish for review` DesignerUrl print, post-validate result summaries) get a higher ceiling of **500 tokens** — never higher. A text block >200 tokens outside the allow-list, or >500 tokens inside it, is a planning monologue, regardless of content or framing. diff --git a/skills/uipath-maestro-case/references/planning.md b/skills/uipath-maestro-case/references/planning.md index 61a5d0a0ae..d0a25fcb40 100644 --- a/skills/uipath-maestro-case/references/planning.md +++ b/skills/uipath-maestro-case/references/planning.md @@ -90,7 +90,7 @@ Before resource resolution, seed TodoWrite with the items below to track Phase 1 For every task, trigger, and condition in the sdd.md: -If the plan-only / no-build exception is active, skip registry and schema discovery in this step and do not fan out through every plugin `planning.md`. Use the compact no-build shape below for the review plan: preserve SDD portable names, emit tenant identities as `resolve at build`, carry every rationale, and stop after `tasks/tasks.md`. The compact no-build plan is exempt from the normal section-batched planning workflow because it is a review artifact, not a build handoff: create `tasks/` if needed and write the complete concise `tasks/tasks.md` with one direct Write, then stop. The later build run owns authoritative resource resolution and regenerates any registry-derived fields before Phase 2. +If the plan-only / no-build exception is active, skip registry and schema discovery in this step and do not fan out through every plugin `planning.md`. The compact no-build T-entry shape and artifact contract are canonical in [phase-0-interview.md § Build start → No-build design + plan request](phase-0-interview.md#build-start--sdd-written-alongside-the-build) — read only that contract, not the full interview flow. Summary: each declaration still gets a T-number with review-oriented fields; preserve SDD portable names; emit tenant identities as `resolve at build`; carry every rationale; no registry-derived fields (`taskTypeId`, `connectionId`, resolved schemas, `inputs`/`outputs`) and no audit files. The compact plan is exempt from the normal section-batched planning workflow because it is a review artifact, not a build handoff: create `tasks/` if needed and write the complete concise `tasks/tasks.md` with one direct Write, then stop. The later build run owns authoritative resource resolution and regenerates any registry-derived fields before Phase 2. **Compact no-build T-entry shape:** each declaration still gets a T-number, but the fields are intentionally review-oriented: @@ -181,7 +181,7 @@ Every declaration in `sdd.md` must become a T-task in `tasks.md`. Mapping is 1-t - **Never filter** declarations on the grounds that the default rule-type, default field value, or "implicit behavior" would cover them. If `sdd.md` lists a task, stage, trigger, condition, SLA row, **variable, or argument**, `tasks.md` emits a T-task for it — regardless of rule-type (`current-stage-entered`, `case-entered`, `exit-only`, `required-tasks-completed`, etc.). - **Never merge** two sdd.md items into one T-task "because they're similar." - **Never drop** defaults-looking items (e.g., `is-interrupting: false`, `runOnlyOnce: true`, `marks-stage-complete: true`). The explicit declaration is the signal — honor it. -- **Never drop design rationale.** Copy each SDD stage/task/SLA `Design Rationale` into `rationale:` on its matching T-entry. Condition T-entries copy the rationale for the routing/activation choice they implement. Rationale is reviewer/audit context; the execution plugin ignores it when composing JSON. +- **Never drop design rationale.** Anchor each SDD stage/task/SLA `Design Rationale` on its matching T-entry as `rationale-ref: SDD §
` — tasks.md sits next to sdd.md, so the anchor is lossless. Write `rationale:` prose ONLY when the T-entry implements a choice whose rationale the SDD does not state (then the plan synthesizes it). Condition T-entries anchor the routing/activation rationale the same way. Rationale is reviewer/audit context; the execution plugin ignores it when composing JSON. - **When in doubt, emit.** It is always correct to create a T-task that mirrors an sdd.md row. It is never correct to silently omit one. - **When format is ambiguous or unrecognized, ASK — do not skip.** If a row exists but you cannot determine the right plugin, category, or T-entry shape (e.g., trigger "Initial Variable Mapping" uses an aggregate phrase instead of explicit per-field mappings; a variable's category — In / Out / Variable — is unclear; a task type does not match the closed enum), invoke **AskUserQuestion** with the row content + the specific ambiguity + bounded options. Silent omission is a defect. This obligation applies to every sdd.md declaration class above, including variables and arguments. @@ -210,14 +210,16 @@ Procedure: 1. **Seed.** Write `tasks.md` with a `## Inventory` placeholder section only. Single Write. 2. **Per section.** Sections are §4.2.1 vars → §4.3 triggers → §4.4 stages → §4.6 tasks → §4.7 conditions → §4.8 SLA. For each section: - **One Read** of `tasks.md` at section entry. - - **N Edit-appends** in sequence, one per T-entry in the section. Skip the re-Read between sibling Edits — Edit's tool result confirms applied state in context. + - **N Edit-appends**, one per T-entry in the section. **Batch multiple sibling Edits into the SAME assistant turn whenever each individual payload stays ≤30KB — this is a MUST, not a should.** Issuing sibling Edits one-per-turn when nothing blocks batching them wastes a full inference round-trip + prompt-cache replay per Edit for zero incremental progress; a 16-Edit section sent as 16 solo turns instead of ~6 batched turns measurably inflates wall-clock with no corresponding gain. Skip the re-Read between sibling Edits — Edit's tool result confirms applied state in context. + - **Assign every T-number for the whole section (and, within §4.6, for every stage) before writing the first Edit, then write in that exact T-number order.** Do not jump ahead to a later stage's tasks and loop back to an earlier one — writing out of the assigned order produces a `tasks.md` whose physical layout no longer matches T-number order, which then requires a separate reorder pass (Read-to-locate-anchor + delete-and-reinsert Edits) purely to undo the mistake. That rework is pure waste: it adds Read/Edit turns that produce no new content, whereas planning the write order up front costs nothing. - TaskUpdate marks each T-entry `in_progress` → `completed` as it goes — that is the per-T-entry audit trail, not the file diff. 3. **Inventory finalize.** After last T-entry, Edit the inventory section with class-by-class counts (per §4.0 cross-check table). 4. **`registry-resolved.json`.** Same section-batched discipline — one Read per section, N Edit-appends, no re-Read between siblings. +5. **Verify once, at the end of the whole file, not per section.** A single `grep -nE '^## T[0-9]+|^\| *T[0-9]+' tasks.md` (or equivalent) pass after the last section confirms T-number order and absence of duplicates — §4.2.1 variable T-numbers appear as table rows (`| T05 |`), not `## T` headings, so the gap between the last trigger heading and the first stage heading is expected, not a defect. Running it speculatively after every section that "might" have gone wrong is itself a symptom of not having planned the write order (see the bullet above) — fix the plan, not the symptom. -**T-entry heading contract.** Every declaration is its own level-two heading in the exact form `## T: `. Do not use level-three-or-deeper headings for T-entries, and do not nest a task beneath a stage's T-entry. A task heading must quote its display name, for example `## T08: Add wait-for-timer task "First Step" to "Process"`. This keeps the plan independently addressable by Phase 2 and by plan validators. +**T-entry heading contract.** Every declaration is its own level-two heading in the exact form `## T: ` — EXCEPT §4.2.1 variables/arguments, which serialize as rows of one table under a non-T heading (each row still owns its T-number; see §4.2.1). Do not use level-three-or-deeper headings for T-entries, and do not nest a task beneath a stage's T-entry. A task heading must quote its display name, for example `## T08: Add wait-for-timer task "First Step" to "Process"`. This keeps the plan independently addressable by Phase 2 and by plan validators. -Why: section-batched round-trips keep tool-call transcript reviewable, preserve rollback granularity at section boundary, allow mid-run interruption recovery via re-Read + resume from next un-applied T-entry, and surface omissions before they propagate — without paying a per-T-entry Read tax that inflates inference latency by ~5s per turn. +Why: section-batched round-trips keep tool-call transcript reviewable, preserve rollback granularity at section boundary, allow mid-run interruption recovery via re-Read + resume from next un-applied T-entry, and surface omissions before they propagate — without paying a per-T-entry Read tax that inflates inference latency by ~5s per turn. Turn-batching sibling Edits and writing in assigned T-number order the first time (rather than fixing it after) are the two highest-leverage ways to cut wall-clock on this step. **Hard cap on tasks.md write size.** After the §4.0a Step 1 Seed Write (Inventory placeholder, <1KB), the only legal mutation of `tasks.md` is **Edit-append** per the section-batched contract above. A single Write replacing the whole `tasks.md` is **forbidden** regardless of size. A single Edit-append payload >30KB is also forbidden — split into per-section Edit-appends even when consecutive Edits would total >30KB combined. Rationale: a single 96KB Write of tasks.md emits ~40K output tokens in one turn = ~360s inference latency = ~20% of total session in one tool call. Section-batched Edit-appends spread that cost across ~7 turns of ~50s each, recovers reviewability, and matches the recovery contract (re-Read + resume from next un-applied T-entry). @@ -241,9 +243,7 @@ When `identifier-type: external`, `case-identifier` carries the sdd.md expressio ### 4.2.1 Declare global variables and arguments -Title format: `Declare ""` where category is `In argument`, `Out argument`, or `variable`. - -One T-entry per variable or argument from the sdd.md "Case Variables" table. Place these after the case file (T01) and **all** trigger T-entries (T02+) — i.e., after the last trigger row, before stages. In multi-trigger cases the variables block starts at `T0+1`, not at `T03`. Consult [`plugins/variables/global-vars/planning.md`](plugins/variables/global-vars/planning.md) for the SDD-to-category mapping rules and entry format. +One T-entry per variable or argument from the sdd.md "Case Variables" table, serialized as one row in a single variables table (columns: `T#`, `name`, `category`, `type`, `sourceTriggers`, `sourceFields`, `default`, `producedBy`) — NOT one H2 block per variable. Each row keeps its own T-number and the §4.0 completeness contract applies row-by-row; the per-category `verify:` contract is stated once after the table, never per row. Place the table after the case file (T01) and **all** trigger T-entries (T02+) — i.e., after the last trigger row, before stages. In multi-trigger cases the variables block starts at `T0+1`, not at `T03`. Consult [`plugins/variables/global-vars/planning.md`](plugins/variables/global-vars/planning.md) for the SDD-to-category mapping rules and the table format. ### 4.3 Configure trigger(s) (T02+) @@ -253,39 +253,7 @@ Consult the corresponding trigger plugin (`plugins/triggers//planning.md`) **One T-entry per trigger row in sdd.md.** A case with N entry-point rows in its triggers table emits N trigger T-entries (T02, T03, …) — even when several rows would resolve to `` because the IS connection isn't provisioned. Per §4.0, "value can't be resolved yet" is not a reason to omit a row; it's a reason to mark `` and continue. Regardless of how many triggers a case has, no per-trigger edge is created (Rule 20; §4.5) — the case starts at the first stage's `case-entered` entry condition whenever any trigger fires. -Each trigger row uses its plugin's full field set — see `plugins/triggers//planning.md` for the per-type entry format. Worked example — sdd.md declares 3 entry-point rows (one manual + two events), one of which is unresolved: - -```markdown -## T02: Configure manual trigger "Operator Starts Case" -- display-name: "Operator Starts Case" -- description: "Operator kicks off a case from the portal" -- order: after T01 -- verify: Confirm node appended; capture TriggerId - -## T03: Configure event trigger "New Inbound Email" -- type-id: -- connection-id: -- connector-key: uipath-microsoft-office-365-outlook -- object-name: Email -- event-operation: created -- event-mode: webhooks -- input-values: {"parentFolderId": "AAMkADNm..."} -- filter: "(contains(subject, 'urgent'))" -- order: after T02 -- verify: Confirm trigger configured with correct event parameters - -## T04: Configure event trigger "Jira Issue Created" -- type-id: -- connection-id: -- connector-key: -- object-name: -- event-operation: -- event-mode: -- order: after T03 -- verify: trigger skipped at execution; user attaches after registering connection -``` - -Do **not** collapse the unresolved trigger into a note on T02 or omit it entirely — execution behavior for unresolved event triggers is documented in [`triggers/event/planning.md § Unresolved Fallback`](plugins/triggers/event/planning.md#unresolved-fallback), but the planning row is still required. +Each trigger row uses its plugin's full field set — the per-type entry format (including the resolved event-trigger shape and the `` field-marking shape) lives in `plugins/triggers//planning.md`. Do **not** collapse an unresolved trigger into a note on another trigger's T-entry or omit it entirely — execution behavior for unresolved event triggers is documented in [`triggers/event/planning.md § Unresolved Fallback`](plugins/triggers/event/planning.md#unresolved-fallback), but the planning row is still required, one per sdd.md trigger row. ### 4.4 Create stages @@ -293,7 +261,7 @@ Title format: `Create stage ""` or `Create secondary stage ""` One task per stage. Consult [`plugins/stages/planning.md`](plugins/stages/planning.md) for required fields and the `stage` vs `secondary` decision. Basic properties only — SLA and escalation come later (§4.7). -Every stage T-entry includes `rationale:` copied from the SDD. It must explain the stage-kind decision and routing shape, especially when one interrupting secondary-stage entry handles a global event. +Every stage T-entry carries its rationale — `rationale-ref: SDD §
` when the SDD states it, `rationale:` prose only when synthesized (§4.0). It must cover the stage-kind decision and routing shape, especially when one interrupting secondary-stage entry handles a global event. ### 4.5 Edges — not authored (RETIRED) @@ -308,7 +276,7 @@ One task per task from the sdd.md — do NOT group multiple tasks under a single Every task entry includes at least: - **taskTypeId** — resolved from the registry in Step 3 -- **rationale** — copied from the SDD; explains the task-type and activation/sequencing choice +- **rationale** — `rationale-ref: SDD §
` when the SDD states it; `rationale:` prose only when synthesized (§4.0). Covers the task-type and activation/sequencing choice - **activation-mode** — required on every task. One of `sequential`, `parallel`, `parallel-after-predecessor`, `event-triggered`, `adhoc`, `fan-in`, or `conditional-gate`. This is the user-visible task mode decision, not layout state. - **entry-rule** — required on every task; mirrors the planned task-entry condition rule. Sequential tasks MUST say `runs-sequentially`, event-triggered tasks normally say `wait-for-connector`, adhoc tasks say `adhoc`, parallel stage-start tasks say `current-stage-entered`, parallel siblings after an immediate predecessor say `runs-sequentially`, and fan-in / non-immediate gates say `selected-tasks-completed`. - **inputs** / **outputs** — see [bindings-and-expressions.md](bindings-and-expressions.md) for the two input modes (literal/expression and cross-task reference) @@ -362,11 +330,11 @@ For per-scope fields, consult the corresponding condition plugin: - `plugins/conditions/task-entry-conditions/planning.md` - `plugins/conditions/case-exit-conditions/planning.md` -Every condition T-entry includes `rationale:` copied from the SDD choice it implements. For global events, state why one interrupting secondary-stage entry replaces per-primary-stage exits/tasks. +Every condition T-entry carries its rationale — `rationale-ref: SDD §
` when the SDD states the choice it implements, `rationale:` prose only when synthesized (§4.0). For global events, the rationale must say why one interrupting secondary-stage entry replaces per-primary-stage exits/tasks. ### 4.8 Set SLA and escalation rules -SLA comes last. Consult [`plugins/sla/planning.md`](plugins/sla/planning.md) for the three sub-operations (default SLA, conditional SLA rules, escalation rules) and per-target ordering. Root rules target `metadata.slaRules[]`; stage rules target that stage's `data.slaRules[]`. Every SLA/escalation T-entry includes `rationale:` copied from the SDD's case/stage SLA rationale. +SLA comes last. Consult [`plugins/sla/planning.md`](plugins/sla/planning.md) for the three sub-operations (default SLA, conditional SLA rules, escalation rules) and per-target ordering. Root rules target `metadata.slaRules[]`; stage rules target that stage's `data.slaRules[]`. Every SLA/escalation T-entry carries its rationale — `rationale-ref: SDD §
` when the SDD's case/stage SLA rationale states it, `rationale:` prose only when synthesized (§4.0). ### 4.9 Not Covered section diff --git a/skills/uipath-maestro-case/references/plugins/variables/global-vars/planning.md b/skills/uipath-maestro-case/references/plugins/variables/global-vars/planning.md index 4ce7e67609..f019ae6f26 100644 --- a/skills/uipath-maestro-case/references/plugins/variables/global-vars/planning.md +++ b/skills/uipath-maestro-case/references/plugins/variables/global-vars/planning.md @@ -51,56 +51,37 @@ Phase 3 (implementation) catches spec-dependent issues — see [`impl-json.md`]( ## tasks.md Entry Format -One T-entry per Case Variables row. Place after the case file (T01) and all trigger T-entries (T02+), before stages. T-number for the first variable depends on trigger count. +One T-entry per Case Variables row, serialized as one row in a single variables table — NOT one H2 block per variable. Each row keeps its own T-number; the §4.0 completeness contract (one T-entry per declaration, never group, never omit) applies row-by-row. Place the table after the case file (T01) and all trigger T-entries (T02+), before stages. T-number for the first variable depends on trigger count. ```markdown -## T05: Declare In-argument "applicantName" -- category: In -- type: string -- sourceTriggers: T03 # single T-number; omit to bind the primary trigger (T02) -- default: "" -- verify: inputs[] formal slot + inputOutputs[] companion (elementId = id-map[T03].id) + that trigger node's outputs[] bridge written. - -## T06: Declare Variable "subject" -- category: Variable -- type: string -- sourceTrigger: T02 -- sourceField: response.subject -- verify: inputOutputs[] entry (id=subject, elementId="root"); trigger T02's outputs[] carries Pattern C wire (source="=response.subject", var=id="subject"); no inputs[] entry. - -## T07: Declare Variable "caseStarter" -- category: Variable -- type: string -- sourceTriggers: T02, T03 -- sourceFields: - T02: response.user - T03: response.initiator -- verify: one inputOutputs[] companion (elementId="root") shared across triggers; each listed trigger's outputs[] has its own Pattern C wire targeting the companion. - -## T08: Declare Variable "caseStatus" -- category: Variable -- type: string -- default: "Open" -- verify: inputOutputs[] entry (id=caseStatus, elementId="root", default="Open"); no trigger output entries. - -## T09: Declare Out-argument "finalDecision" -- category: Out -- type: string -- producedBy: T15.outputs.finalDecision # informational reference to the producing task T-entry -- verify: outputs[] formal entry (var=finalDecision); companion in inputOutputs[] ALWAYS emitted (with default="" when Default empty); io-binding validator confirms producer task output has id=finalDecision. +### Variables and arguments (one T-entry per row) + +| T# | name | category | type | sourceTriggers | sourceFields | default | producedBy | +|---|---|---|---|---|---|---|---| +| T05 | applicantName | In | string | T03 | | "" | | +| T06 | subject | Variable | string | T02 | response.subject | | | +| T07 | caseStarter | Variable | string | T02, T03 | T02: response.user; T03: response.initiator | | | +| T08 | caseStatus | Variable | string | | | "Open" | | +| T09 | finalDecision | Out | string | | | | T15.outputs.finalDecision | ``` -**Field semantics on the T-entry:** +**Column semantics:** - `category` — required, one of `In`, `Out`, `Variable` - `type` — required, one of `string`, `integer`, `float`, `double`, `boolean`, `datetime`, `date`, `jsonSchema`, `file` -- `sourceTrigger` — T-number when the value comes from a single trigger's payload (Variable category) -- `sourceTriggers` — for a `Variable`: CSV of T-numbers when multiple triggers populate it. For an `In`-arg: a single `T` selecting the trigger it binds to (blank → primary trigger T02; never a CSV). Replaces the legacy `triggerRef` field. -- `sourceFields` — per-trigger payload paths (Variable only). Single-trigger form is ``; multi-trigger form is a YAML-style sub-block with one `T: ` per line. Empty on `In` rows. +- `sourceTriggers` — for a `Variable`: CSV of T-numbers when one or more triggers populate it. For an `In`-arg: a single `T` selecting the trigger it binds to (blank → primary trigger T02; never a CSV). Replaces the legacy `triggerRef` field. +- `sourceFields` — per-trigger payload paths (Variable only). Single-trigger form is ``; multi-trigger form is `T: ` pairs separated by `; `. Empty on `In` rows. - `default` — initial value (string-encoded for non-string types). Drives the `default` field on the companion `inputOutputs[]` entry. - `producedBy` — informational only (for Out-args). The io-binding validator confirms the named task actually exists with a matching output. -**`verify` text — use exact terms from [`impl-json.md` § Pattern shapes](impl-json.md):** +**Verify contract — per category, stated ONCE after the table, never repeated per row.** Emit one `verify:` line per category present, using exact terms from [`impl-json.md` § Pattern shapes](impl-json.md): + +- `In` → inputs[] formal slot + inputOutputs[] companion (elementId = id-map[source trigger].id) + that trigger node's outputs[] bridge. +- `Variable` with source-triggers → inputOutputs[] companion (elementId="root"); each listed trigger's outputs[] carries its own Pattern C wire targeting the companion; no inputs[] entry. +- `Variable` without source-triggers → inputOutputs[] entry (elementId="root", default carried); no trigger output entries. +- `Out` → outputs[] formal entry; companion in inputOutputs[] ALWAYS emitted (default="" when Default empty); io-binding validator confirms producer task output id. + +**Verify-term glossary — use exact terms from [`impl-json.md` § Pattern shapes](impl-json.md):** - "Bridge" = In-arg formal-arg → companion forwarding (any trigger type; 3-entry shape) on the trigger named by the In row's `sourceTriggers` (blank → primary). NEVER use for Variable rows. - Variable-row trigger.outputs[] entries are "Pattern C wires" (direct payload extraction, 2-entry shape).