osdlc

task-auto-define

Drive one or more task documents toward the implementation-ready contract (solutions/ontological/lib/model/entities/task/implementation-ready.md) by synthesizing best-effort content from each task's existing prose plus codebase context, without prompting the user. Multiple tasks run in sequence, one commit and one slug-namespaced terminal marker each. --make-pr pushes the run's commits on a chore/ branch and opens a PR (default off — commit on the current branch only). Stamps a discoverable machine-authored marker on every synthesized spec. Never changes state: /sdlc:task-ensure-ready promotes to open/ready and stamps readiness_verified_at in one commit. Dispatched by /sdlc:task-ensure-ready when a task is autonomy: autonomous/pr and the deterministic verify reports a gap.

osdlc 3 Actualitzat fa 5 d

Recursos

1
GitHub

Instal·la

npx skillscat add osdlc/osdlc/task-auto-define

Instal·la des del registre de SkillsCat.

SKILL.md

$sdlc:task-auto-define

Usage:

$sdlc:task-auto-define <task> [<task> ...] [--make-pr]
  • <task> — slug, filename, or absolute path (use absolute paths when
    invoking from another skill). Each task runs the per-task flow (Steps
    2–7) in sequence; a failure on one task does not abort the rest.
  • --make-pr (default off) — after all tasks are processed, push the run's
    commits on a chore/ branch and open a PR. Without it the skill commits
    on the caller's current branch and never pushes.

Fill each task's readiness gaps with content synthesized from its existing
prose and the surrounding codebase, mark the result as machine-authored, and
commit. This is how an autonomy: autonomous/pr task self-readies instead
of parking at a spec gap.

References:

  • ${CLAUDE_PLUGIN_ROOT}/lib/model/entities/task/implementation-ready.md — the contract this skill
    fills gaps against.
  • sdlc task resolve <arg> — resolves each task argument to an absolute
    path (its spec doc is ${CLAUDE_PLUGIN_ROOT}/lib/model/entities/task/file-resolution.md;
    see scripts/sdlc task resolve --help).

Terminal markers (slug-namespaced per ${CLAUDE_PLUGIN_ROOT}/skills/CLAUDE.md; one per
task, plus the PR marker when --make-pr produced one):

Marker Meaning
TASK-AUTO-DEFINE-DEFINED: <basename> The doc was edited (gap fills), validated, and committed.
TASK-AUTO-DEFINE-NO-CHANGES: <basename> No fillable gap; no edit, no commit.
TASK-AUTO-DEFINE-INSUFFICIENT: <basename> A gap exists but cannot be plausibly synthesized from the available prose + codebase context; no edit, no commit.
TASK-AUTO-DEFINE-PR: <url> --make-pr pushed the run's commits and opened a PR.
ERROR reason="..." Shared cross-skill failure marker (bad argument, no task found, validator rejected the synthesized doc). Names the failing task in a multi-task run.

1. Parse the invocation

Split arguments into task references (positional) and flags. No task
reference → exit ERROR reason="no task argument". Run Steps 2–7 for each
task in argument order, recording its terminal marker; on a per-task
failure, continue with the next task. Then run Step 8 once.

2. Resolve the task file

Run sdlc task resolve <argument> per
${CLAUDE_PLUGIN_ROOT}/lib/model/entities/task/file-resolution.md — the canonical
call + outcome contract (no pipe — gate on the bare exit code, per
${CLAUDE_PLUGIN_ROOT}/skills/CLAUDE.md). On success capture the absolute
path and basename and continue to Step 3.

This skill uses the non-interactive ambiguous-policy mode — it never
prompts. Map each failure to this skill's ERROR marker, then move to
the next task:

  • AMBIGUOUS: → ERROR reason="ambiguous: <comma-separated candidates>".
  • NO TASK FOUND → ERROR reason="no task found for <argument>".

3. Read inputs

  1. Read the task file end-to-end.
  2. Read ${CLAUDE_PLUGIN_ROOT}/lib/model/entities/task/implementation-ready.md (once
    per run is enough).

4. Identify gaps

Apply the contract from
${CLAUDE_PLUGIN_ROOT}/lib/model/entities/task/implementation-ready.md. This skill
computes the same gap-detection FACTS the gate will re-verify — collapsed
from the four former separate op calls into one sdlc task gap-report call
(plus the separate corpus advisory), so this skill's notion of "gap" matches
what the gate that re-verifies immediately after would reject. Gap detection
is TWO calls: the deterministic gap-report composite (this section) plus the
separate LLM-judged corpus advisory (last bullet). Run each directly (no pipe
— gate on the bare exit code, per ${CLAUDE_PLUGIN_ROOT}/skills/CLAUDE.md):

  • Deterministic readiness-gap composite — shell out to the task noun's
    gap-report op, which runs scan-placeholders + check-claims (plus a
    read of parse-touchpoints for informational-only ## Areas shape) PLUS
    required-section presence in ONE read-only, no-LLM call and returns ONE
    structured object:

    scripts/sdlc task gap-report <path> --output json

    (scripts/sdlc task gap-report --help; the
    bare CLI prints a GAP-REPORT gaps=N sections=N placeholders=N claims=N marker, exit 0; a missing file is INVALID_INPUT,
    exit 1.) The op reports deterministic FACTS only — it makes none of the
    interpretation calls below; this skill owns them, reading the unified
    output:

    • Body sections / frontmatter — read each sections[] entry:
      present == false is a required-section gap. That array is the authority
      on what is required; a section absent from it is optional and its absence
      costs nothing. Separately read the doc and mark each present section thin
      (header exists but body is empty, unchanged <...> template text, or too
      vague to inform the implementer); check each required frontmatter field.
    • Touchpoint shape — read touchpoints.areas_kind and
      touchpoints.parse_errors[]. As of v7, ## Today is fully free-form
      prose and ## Areas is advisory — NEITHER is resolved against the
      working tree, and no shape or content of either ever becomes a gap.
      These fields are informational only.
    • Placeholders — each entry in placeholders[] (TBD / pick-one /
      angle-bracket / empty-table-cell) is a gap. No further filtering.
    • Claim resolvers — read claims[]: each severity: "disqualifier"
      finding is a gap (relay its message / line); severity: "warning"
      findings are informational only. The flat gaps[] array already aggregates
      every disqualifier across all of the above (section / placeholder /
      claim) for direct iteration — the per-category objects carry the detail.
  • Corpus-assumption candidates (advisory). See
    ${CLAUDE_PLUGIN_ROOT}/conventions/corpus-assumptions-scanner.md for what
    the scanner checks and how to confirm a candidate. Shell out to it as its
    own separate call:

    scripts/sdlc task scan-corpus-assumptions <path>

    Only a candidate you CONFIRM against the cited line is a gap.

For each requirement that fails or disqualifier that triggers, record an entry
with:

  • the section or field involved,
  • the nature of the gap (missing / thin / wrong-value / disqualified-by),
  • what an acceptable resolution looks like.

If the gap list is empty, report TASK-AUTO-DEFINE-NO-CHANGES: <basename>
and move to the next task. The caller can run $sdlc:task-ensure-ready to
promote and stamp.

5. Synthesize gap fills (best-effort)

For each gap, synthesize content from two sources, in priority order:

  1. The task's own prose. The Goal, Discovery context, any existing
    Approach/Today content, and the headline usually carry enough intent to
    draft the missing sections. Stay faithful to what the author wrote — do
    not invent scope the prose doesn't support.
  2. Codebase context. Use Grep / Glob / Read to ground synthesized
    content in real paths — this makes the spec USEFUL even though neither
    ## Today nor ## Areas is resolved against the codebase by any op:
    • For ## Today, write free-form prose describing the current state.
      No required shape.
    • For ## Areas, name the packages/directories/modules this task
      expects to touch, with a one-line note each — prose, a bulleted list,
      or a | Area | Note | table, whichever reads best. Advisory only: an
      area doesn't have to be a path you've confirmed exists.
    • For ## Approach, write concrete ordered steps a competent engineer
      could execute — not "investigate X".
    • For ## Acceptance criteria, write objectively verifiable - [ ] AC-N:
      bullets (assertable / observable / demonstrable), never subjective ones.
    • For ## Out of scope, enumerate obvious near-misses, or a single
      - none bullet if nothing is excluded.

Write each fill with sdlc task set-section <task> "<Section>" --text - (the
section text on stdin), which replaces one ## Section, leaves every other
byte alone and refuses a result that still has a placeholder or lacks a
required section. Do not hand-edit a section the op can write.

Goal and Acceptance criteria are locked once the task is open/ready or
later.
They say what the task asks for; definition fills gaps around them and
never rewrites them. Do not reword, reorder, add or drop either, even to
"improve" them: set-section refuses with TASK_INTENT_LOCKED, and the
orchestrator holds a task whose Goal or criteria changed during define. If a
criterion looks wrong, report TASK-AUTO-DEFINE-INSUFFICIENT naming it and
leave it alone. Ticking a criterion's checkbox is not a change.

Do NOT touch the task-state frontmatter fields owned elsewhere:
readiness_verified_at:, touchpoints_verified_at:, definition_gap:,
completion_note:, prs:, and state:. This skill edits body content
only, plus the machine-authored note (Step 6).

Insufficient-context bail-out

If a required gap cannot be plausibly synthesized — there is no prose intent
to draw on AND no codebase anchor to infer from, so any fill would be
fabricated rather than best-effort — do NOT write low-quality filler. Revert
any partial edits, report TASK-AUTO-DEFINE-INSUFFICIENT: <basename> naming
the unfillable gap, and move to the next task without committing.

6. Stamp the machine-authored marker

Stamp a discoverable "spec auto-defined — review carefully" note in the body
so a human reviewer (and later tooling) can tell the spec was
machine-synthesized.

Place the note immediately after the # headline and before ## Goal —
outside every required section, so it neither satisfies nor trips the
readiness verifier's per-section checks. Use this exact shape, substituting
today's UTC date:

> AUTO-DEFINED: this spec was best-effort machine-authored by
> $sdlc:task-auto-define on <YYYY-MM-DD> because the task is
> autonomy: autonomous/pr. Review the Goal, Approach, Today,
> Areas, and Acceptance-criteria carefully before trusting it.

If a prior AUTO-DEFINED: note already exists (a re-run), refresh its date
rather than stacking a second note.

7. Commit

Reached with pending edits (Steps 5–6).

Do not set state: here. Promotion to open/ready is
$sdlc:task-ensure-ready's job: it flips the state and stamps
readiness_verified_at: in one commit. It does nothing to a task that is
already open/ready, so a state flip here would leave the task ready with
no stamp.

  1. With --make-pr, before the run's first commit, create
    chore/auto-define-<stem> from the current HEAD and switch to it —
    <stem> is the task basename (single task) or batch-<YYYYMMDD-HHMM>
    UTC (multiple). Later tasks in the run commit on the same branch.

  2. Run the validator (no pipe — gate on the bare exit code, per
    ${CLAUDE_PLUGIN_ROOT}/skills/CLAUDE.md "Don't pipe commands you gate on"):

    scripts/sdlc entities validate <path>

    If it fails, fix and re-run. If it cannot be made to pass, revert the
    task's edits, report
    ERROR reason="synthesized doc failed frontmatter validation", and move
    to the next task.

  3. Stage only the task file: git add <path> (the commit op commits the
    staged index — it does NOT narrow scope).

  4. Commit on the current branch with the model-generated message routed
    through sdlc commit create --message - (stdin heredoc; see
    ${CLAUDE_PLUGIN_ROOT}/conventions/commit-messages.md):

    scripts/sdlc commit create --message - <<'EOF'
    docs(tasks): auto-define <basename>
    
    <one-line summary of which sections were synthesized>
    EOF
  5. Report:

    TASK-AUTO-DEFINE-DEFINED: <basename>
    sections synthesized: <list>

8. Open the PR (--make-pr only)

Skip when the flag is absent or the run made no commits (then no branch was
created either). Otherwise:

  1. git push -u origin <branch>.
  2. sdlc pr create against main. Title: the single commit's subject, or
    docs(tasks): auto-define <N> tasks for a multi-task run. Body: the
    per-task marker lines plus a pointer to review the AUTO-DEFINED: notes
    before trusting the specs.
  3. Switch the checkout back to the original branch.
  4. Report TASK-AUTO-DEFINE-PR: <url>.

In either mode the skill never merges; the human stays at the merge gate.

9. Hand off

Print one pointer line per DEFINED task:

Next: run $sdlc:task-ensure-ready <basename> to verify and stamp.

Notes

  • Best-effort, not authoritative. The AUTO-DEFINED: note is the
    human's signal to review before trusting the spec. This skill leaves
    state: and readiness_verified_at: to $sdlc:task-ensure-ready.
  • One commit per task, touching only that task file.
  • Skill-authoring conventions. See ${CLAUDE_PLUGIN_ROOT}/skills/CLAUDE.md
    — slug-namespaced markers, no duplicated prose, gate on bare exit codes.
  • Committing model-generated messages. Step 7 routes the per-task message
    through sdlc commit create --message - (stdin heredoc). See
    ${CLAUDE_PLUGIN_ROOT}/conventions/commit-messages.md.
  • Commit the body before the gate runs. Step 7 commits the synthesized
    body on the current branch as its own commit. This is what lets the
    downstream readiness gate stay frontmatter-only: $sdlc:task-ensure-ready's
    Step 3b precondition refuses (exit 19) to stamp readiness_verified_at: while
    the task file still carries uncommitted body edits, so the gate's stamp
    commit and this skill's body commit must be two separate commits, body
    first. Never hand the gate an uncommitted synthesized body. See
    T-XBJY-ensure-ready-refuses-with-unstaged-body-edits and
    ${CLAUDE_PLUGIN_ROOT}/skills/task-ensure-ready/SKILL.md Step 3b.
  • Gap detection computes the same gap facts the gate will re-verify. Step 4
    calls one sdlc task gap-report (the composite that runs
    scan-placeholders + check-claims + required-section presence, plus an
    informational-only read of parse-touchpoints' ## Areas shape, in one
    no-LLM call) plus the separate corpus advisory — two calls total. The
    interpretation layer (severity filtering, placeholders, claims) reads
    gap-report's unified output field-for-field, so what this skill flags as
    a gap matches what the gate that re-verifies right after would reject.
    ## Today and ## Areas shape is never part of that gap set (v7).
  • Corpus-assumption scanner. See
    ${CLAUDE_PLUGIN_ROOT}/conventions/corpus-assumptions-scanner.md — stays its
    own Step 4 call, deliberately outside gap-report's deterministic composite.
  • Branch naming. See ${CLAUDE_PLUGIN_ROOT}/conventions/branch-naming.md.
    Default mode commits on whatever branch the caller is on; --make-pr
    uses the bulk-work chore/<skill>-<stem> shape.

Finish the session

If the SDLC_SESSION environment variable is set, this run is an sdlc-tracked
session, and the orchestrator learns the task is finished only from you. Check
echo "$SDLC_SESSION"; when it is empty, skip this section.

Run it only when this skill was the session's own top-level task (your first
message asked for it). If you loaded this skill from inside another skill or a
sub-agent, do not run it: the invoker finishes the session.

When all of this skill's work is complete, as the last thing you do:

  • Success: sdlc session done --outcome ok
  • Failure, or the work cannot continue: sdlc session done --outcome failed --note "<one line why>"

Never run it before the work is complete: the orchestrator treats done as
"go on to the next step". Do not run it while a question to the person is
open. Headless runs run it too, which is harmless.