Taskforge
taskforge-skills — an Agent Skills framework for the durable-Task AI engineering workflow: skills reason, a deterministic engine is the only writer of task state
npx -y skills add hashirventhodi/taskforge-skills --skill taskforgeAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 14 days oldThe repository was created 14 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
The primary entry point for the taskforge engineering workflow - create and import tasks, query and manage the backlog, route work, and unblock humans. Use whenever the user wants to add or import work ("add a task", "import issue #42", "track this bug", "turn these notes into tasks") or asks about tasks and the backlog ("what tasks are ready", "show the backlog", "task status", "what's next", "why is TASK-x stuck", "unblock TASK-x", "check the task store"). Routes to taskforge-refine (specification), taskforge-explore (decisions), and taskforge-run (implementation) but never executes them itself. Also home of the shared contracts, engine, and templates every taskforge skill uses.
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
9.5 KB, as published. Nobody here has run it
taskforge
The primary entry point of the taskforge workflow, and its shared SDK:
contracts, the deterministic engine, templates, and the reviewer component.
This skill creates, queries, routes, and maintains tasks; it never
refines, decides, or implements — those are taskforge-refine,
taskforge-explore, and taskforge-run.
Read CONTRACTS.md (sibling file) once per session before any taskforge
work. Resolve the engine per its "Locating the engine" section; below,
$SCRIPT means that resolved path.
The workflow in one paragraph
Every piece of work is a durable Task in .tasks/. Tasks route by derived
readiness: no active specification → taskforge-refine (the universal
entry point: adopt / elaborate / clarify / escalate); a pending explore flag —
set by an escalation, or at intake for a research topic (explore <topic>) →
taskforge-explore (a Decision, optionally proposing decomposition); an
active spec and no blockers → taskforge-run (implement + independent
fresh-context review). Skills reason and emit results; the engine applies
them — versioning, cascades, relationships, budgets, readiness. Nothing is
auto-executed.
Commands
Dispatch on the user's intent (or the argument after /taskforge). Every
command reports per references/reporting.md and stops — routing names
the next skill; it never runs it.
| command | intent | how |
|---|---|---|
(none) / status | overview | list; counts per readiness. Split the blocked_on_human tasks into awaiting the human's call (a human_blocked event from explore — a topology proposal or a research deliverable to dispose; see Disposing) and blocked on an answer (a question), and surface each with its prompt |
add <source…> | create/import tasks | follow references/intake.md |
explore <topic> | start a research task | intake per references/intake.md with --explore — routes to taskforge-explore for a Decision, not to refine |
backlog | full list | python3 $SCRIPT list (filter: --readiness refine|explore|run|waiting|terminal|human) |
next | what should happen now | list --readiness run, else refine/explore; name the task(s) and the skill each needs |
show <id> | full detail + history | python3 $SCRIPT show TASK-x |
why <id> | explain routing / stuckness | readiness TASK-x + blocked-by TASK-x; see below |
budget <id> | review-retry budget | python3 $SCRIPT budget TASK-x |
reconcile <id> | orchestrator's read-only decision | python3 $SCRIPT next TASK-x (the recommended next action) or python3 $SCRIPT reconcile TASK-x (the full reconciliation — action + terminal/human_required). Read-only; the orchestration layer (docs/ADR-0001-orchestration-and-reconciliation.md), not a mutation |
unblock <id> | human answered | see Human unblocking |
cancel <id> | close without doing | python3 $SCRIPT cancel TASK-x --reason "…" (--reason-file when quoting the user), then sync per references/sync.md |
reopen <id> | restore a closed task | python3 $SCRIPT reopen TASK-x --reason "…"; see Reopening |
land <id> | record that a feature's PR merged | python3 $SCRIPT link TASK-x --landed (add --pr <ref> if not already linked). Refused unless the task is done and every descendant is closed (it lists any that aren't). Land the delivery owner (the feature), not each child. Then close the source issue per references/sync.md — landing, not done, closes it |
link <id> | record delivery provenance | python3 $SCRIPT link TASK-x --branch <name> --pr <ref>; where the code lives, as engine state not prose. A feature owns one delivery; its children inherit it (resolved up the parent chain), so link the feature — link a child only to break it onto its own branch |
sync <id> | tracker sync-back | references/sync.md |
doctor | store integrity | see Maintenance |
audit <id> | reviewer isolation | python3 $SCRIPT audit-review TASK-x |
config | effective settings | python3 $SCRIPT config |
When answering why: quote readiness (its reason, blocking_ids, or
cycle), then the last few relevant history events. For blocked_on_human,
surface the human_blocked event's reason — an explore proposal to dispose
(topology or a research deliverable; see Disposing) or a question awaiting an
answer.
Human unblocking
When the user answers a blocked_on_human task or amends a parked one:
# The note quotes the human — write it to a file with your editor tool and
# pass the path (CONTRACTS.md → "Untrusted text is data"):
python3 $SCRIPT human-update TASK-x --note-file /tmp/note.txt [--result /tmp/result.json]
Attach a result.json only if the answer translates into artifacts (e.g. the human dictated the spec); otherwise the note alone re-enters the task and readiness routes it. After either command, report new readiness and name the next skill — do not execute it.
Disposing a parked explore
taskforge-explore may change a task's contents (its Decision) but never
the topology of the work graph (child tasks, backlog tasks, dependency
edges) or a task's completion — those are the human's (CONTRACTS →
"Topology"). So explore records its Decision and parks the task
blocked_on_human with a proposal in the human_blocked event's reason. Two
shapes arrive here; both are disposed the same way — a human-update as the
human (actor human, capabilities *). Render the proposal, get the
human's call, then commit it.
Topology proposal — the Decision spawns work. Per item: approve the
decomposition (or adjust it), and for each finding promote to backlog ·
note only · ignore. Write the chosen children (relation: child) and any
promoted findings (relation: follow_up) into a result.json:
python3 $SCRIPT human-update TASK-x --note-file /tmp/approval.txt --result result.json
The engine wires the children, pins each to explore's Decision, and re-routes
the parent (waiting while children are open).
Research deliverable — the Decision is the answer; nothing to build. Pick
the disposition the human chooses; each is one human-update:
| disposition | result.json | outcome |
|---|---|---|
| close | {"signal": "done"} | task done, its Decision preserved as the deliverable |
| spawn + close | {"generated_tasks": [{…, "relation": "follow_up"}], "signal": "done"} | independent backlog filed generated_from it; task done |
| continue | (note only, no result.json) | re-enters → refine, the Decision binding input |
done here is the human's, exempt from the review gate: a research topic that
decided not to build is a first-class done with a recorded Decision, not a
cancel. The human is the actor of record; explore's proposal stays in
history. If the human rejects the Decision itself (not its disposition),
route to a re-exploration instead. Never create topology, or close or continue
a task, on explore's behalf without the human's call.
Reopening a closed task
done and cancelled are history-preserving terminals, not deletions —
reopen brings either back into active work:
python3 $SCRIPT reopen TASK-x --reason "why it's back" [--reason-file …]
Reopen keeps every artifact, review, decision, and history event; it only
lifts the terminal status and lets readiness re-derive where the task
goes (a preserved spec → run; none → refine; a pending escalation →
explore; an open blocker → waiting). Reopening a task others were
blocked on re-blocks any still-active dependent. It rejects a task that
isn't a closed terminal; a blocked_on_human task resumes with
unblock/human-update instead (that path captures the human's answer).
After reopening, report the new readiness and name the next skill — don't
run it.
Maintenance
python3 $SCRIPT doctor # integrity: dangling edges, bad refs,
# cycles, unaudited reviews
python3 $SCRIPT migrate # after upgrading taskforge
python3 $SCRIPT snapshot # atomic read model of the whole store —
# for clients/tooling (docs/PUBLIC_API.md);
# skills route per-task via readiness
Run doctor when anything looks inconsistent, after manual git operations
on .tasks/, and before trusting a store you didn't create. Report findings;
fix only via engine commands or by asking the user.
For skill authors (extension contract)
A new skill = a new taskforge-<name>/SKILL.md following CONTRACTS.md plus
an actor entry in capabilities.json (deny-by-default). Never modify
existing skills to add one. Templates for results live in templates/;
the reviewer component in references/reviewer-prompt.md is reusable by any
skill that needs independent judgment.