diff --git a/AGENTS.md b/AGENTS.md index ce6ea847..77d4a793 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -3,7 +3,7 @@ ## Product - Goal: prevent scope drift, context loss and unsupported completion claims in AI-assisted software changes. -- Product: agentic-development, seven portable Skills: cycle, research, plan, implement, test, judge, iterate. +- Product: agentic-development, seven portable phase Skills: cycle, research, plan, implement, test, judge, iterate; plus optional task-authoring for ticket creation/repair. - Optional Goose hooks observe events/report structure; they are not an enforcement or acceptance engine. - Non-goals: automatic authorization, protected task closure, session launching or release acceptance. - Manifest/schema/version truth: plugin.json; do not repeat a hard-coded version here. @@ -12,7 +12,7 @@ | Path / location | Role / boundary | |---|---| -| plugin.json, skills/*/SKILL.md | Source manifest and seven Skill entrypoints; required resources stay contained. | +| plugin.json, skills/*/SKILL.md | Source manifest, seven phase entrypoints and optional task-authoring; required resources stay contained. | | hooks/hooks.json, scripts/observe.py | Goose-specific rules/handler in this plugin, not a second adapter. | | tools/production.py | Deterministic projection CLI; stdlib observer packaged as scripts/observe.pyz. | | tests/, integration/ | Source/handler checks and evaluation scenarios; integration/ is not an executable harness. | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d7e5e7f8..a7b2a9a6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -103,7 +103,7 @@ suite now includes five adapted integration cases with distinct immutable hypothetical fixtures under skills/cycle/evals/files/. The original integration/ inventory is retained, but is not the direct Skill Creator input. These explain-level cases assess proposed coordination and handoffs, not live -implementation, tracker operations or acceptance of all seven Skills. +implementation, tracker operations or acceptance of the seven phase Skills or optional task-authoring capability. Explanation assertions cover observable final-output properties. Actual read/order and prerequisite requirements remain in canonical execution_assertions metadata; diff --git a/README.md b/README.md index 24c6be60..c319e8ce 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,7 @@ AI coding agents can lose context, drift beyond scope, and mistake passing tests Read the [getting started guide](https://github.com/bioinfornatics/agentic-development/blob/develop/docs/getting-started.md), then give your agent a concrete outcome: > Use Agentic Development to deliver this change: [desired behavior]. -> Clarify scope and acceptance criteria before editing. Verify the result, -> report remaining risks, and ask before actions that need my approval. +> Clarify scope and acceptance criteria before editing. Verify the result, report remaining risks, and ask before actions that need my approval. ## What you get Seven reusable Skills guide the work: six phases and one coordinator. @@ -19,7 +18,6 @@ Goal / need → Research → Plan → Implement → Test → Judge → Scoped ac └── Iterate ←─────┘ if correction is needed ``` - | Phase | Question to resolve | Expected output | | --- | --- | --- | | **Research** | What must we understand before deciding? | Cited findings, risks, unknowns, and constraints. | @@ -33,8 +31,13 @@ Goal / need → Research → Plan → Implement → Test → Judge → Scoped ac Keep requirements, decisions, and restart context explicit; make small, reviewable changes; separate test results from acceptance and report missing evidence. Use the whole cycle or the phase your task needs. These are agent instructions, not an enforcement engine or a guarantee of correct software. Install: `goose plugin install https://github.com/bioinfornatics/agentic-development.git`. -Check: `goose skills list` — only this plugin’s seven Skills, no evaluation fixtures. +Check: `goose skills list` — the generated candidate should expose exactly eight Skills: seven phases plus optional task-authoring, no evaluation fixtures. Update: `goose plugin update agentic-development`. See [Goose Plugins](https://goose-docs.ai/docs/guides/context-engineering/plugins) and [Agent Skills](https://goose-docs.ai/docs/guides/context-engineering/using-skills). +### Optional task-authoring capability +The seven development phases remain Cycle, Research, Plan, Implement, Test, Judge and Iterate. `agentic-development:task-authoring` creates or repairs readable tickets from established scope and returns verified tracker readback or an explicit proposal. +Load it conditionally through the host's Skill loader only for creation/repair, not routine reads, claims, updates or closure. It stops and returns to its caller. +Individual phases retain full contained ticket guidance as a direct-reading fallback when this optional capability is absent; normal use does not load both routes. +Eight physical guidance copies preserve contained portability; this extraction does not claim elimination of all duplication or measured context/behavior improvement. ## Dependencies and workflow tools The Skills are Markdown instructions: use an agent that can load them and your project's own development tools. No package installation or build is required for the Skills. @@ -47,14 +50,11 @@ The Skills are Markdown instructions: use an agent that can load them and your p | Entire, optional | Capture session context and connect it to checkpoints. | Verify support for your agent and worktree; link only observed session/checkpoint IDs to the task. | **Handoff:** user prompt → task with scope and acceptance criteria → execution → evidence, status, and next action recorded in Beads → restart prompt with task ID. -The next session rereads the task: Beads is task truth, not the prompt or a notebook. -Beads adoption is conditional; once chosen, missing access or a failed claim blocks implementation, not permission to continue untracked. Without Beads, agree another tracking approach. +The next session rereads the task: Beads is task truth, not the prompt or a notebook. Beads adoption is conditional; once chosen, missing access or a failed claim blocks implementation, not permission to continue untracked. Without Beads, agree another tracking approach. Entire captures context, not task truth or acceptance; no tool grants permission to commit, push, or close tasks. See the [integration guide](https://github.com/bioinfornatics/agentic-development/blob/develop/docs/integrations.md) for setup checks and boundaries. - ## Learn more - [Development cycle](https://github.com/bioinfornatics/agentic-development/blob/develop/docs/cycle.md): how the phases fit together. - [Integrations](https://github.com/bioinfornatics/agentic-development/blob/develop/docs/integrations.md): Beads, Git, Entire, and optional Goose observation hooks. - [Contributing](https://github.com/bioinfornatics/agentic-development/blob/develop/docs/contributing.md): improve the method on develop. - The main branch contains the generated installation package; develop contains its source and documentation. Both use this same README. Skills need no build; optional observation hooks require Python 3.10+ and use only the standard library. diff --git a/skills/cycle/SKILL.md b/skills/cycle/SKILL.md index 05574b81..663f5f52 100644 --- a/skills/cycle/SKILL.md +++ b/skills/cycle/SKILL.md @@ -66,9 +66,17 @@ a previous permission. This is an agent instruction, not a runtime cache. assumptions. A request to implement this slice authorizes its scoped code changes, not Git commits, remote operations, production actions or unrelated work. - Before creating or repairing task descriptions or acceptance criteria, apply - [ticket authoring](references/ticket-authoring.md); verify readable purpose, - criteria, ordered inputs and restart context without duplicating execution history. + Before creating or repairing task descriptions or acceptance criteria, verify + current scope and write authority. Conditionally Load `agentic-development:task-authoring` + using the host's available Skill-loading mechanism (not a shell command), with + established goal, scope, criteria, native tracker context and current authority. + Reuse its guidance when already available and current; do not load both routes + normally. If the optional capability is unavailable, apply contained + [ticket authoring](references/ticket-authoring.md) directly and report direct + reading, not activation; do not retry loading or block routine work on its absence. + For routine reads, claims, progress updates or closure, do not load task-authoring. + Resume this caller after verified ticket readback or an explicit proposal/error; + retain this phase's scope, ownership, review and evidence gates. Require explicit delivery mechanisms and asset maps for ready implementation work. Route changed scope through consolidated ticket sections and reconciled dependency edges; a populated tracker record alone does not prove execution readiness. diff --git a/skills/implement/SKILL.md b/skills/implement/SKILL.md index c41e4596..b2fc95a3 100644 --- a/skills/implement/SKILL.md +++ b/skills/implement/SKILL.md @@ -42,9 +42,17 @@ a previous permission. This is an agent instruction, not a runtime cache. Verify repository root, local instructions, tools and task goal. - Before creating or repairing task descriptions or acceptance criteria, apply - [ticket authoring](references/ticket-authoring.md); verify readable purpose, - criteria, ordered inputs and restart context without duplicating execution history. + Before creating or repairing task descriptions or acceptance criteria, verify + current scope and write authority. Conditionally Load `agentic-development:task-authoring` + using the host's available Skill-loading mechanism (not a shell command), with + established goal, scope, criteria, native tracker context and current authority. + Reuse its guidance when already available and current; do not load both routes + normally. If the optional capability is unavailable, apply contained + [ticket authoring](references/ticket-authoring.md) directly and report direct + reading, not activation; do not retry loading or block routine work on its absence. + For routine reads, claims, progress updates or closure, do not load task-authoring. + Resume this caller after verified ticket readback or an explicit proposal/error; + retain this phase's scope, ownership, review and evidence gates. If the repository uses Beads, apply [the Beads integration](references/beads-integration.md) before choosing work or mutating task state. Use fresh `bd prime` guidance; diff --git a/skills/iterate/SKILL.md b/skills/iterate/SKILL.md index 4d3035f7..df04d5e8 100644 --- a/skills/iterate/SKILL.md +++ b/skills/iterate/SKILL.md @@ -48,9 +48,17 @@ a previous permission. This is an agent instruction, not a runtime cache. resuming artifact claims or executing consequential actions; verify current permission for the intended action, not historical approval. - Before creating or repairing task descriptions or acceptance criteria, apply - [ticket authoring](references/ticket-authoring.md); verify readable purpose, - criteria, ordered inputs and restart context without duplicating execution history. + Before creating or repairing task descriptions or acceptance criteria, verify + current scope and write authority. Conditionally Load `agentic-development:task-authoring` + using the host's available Skill-loading mechanism (not a shell command), with + established goal, scope, criteria, native tracker context and current authority. + Reuse its guidance when already available and current; do not load both routes + normally. If the optional capability is unavailable, apply contained + [ticket authoring](references/ticket-authoring.md) directly and report direct + reading, not activation; do not retry loading or block routine work on its absence. + For routine reads, claims, progress updates or closure, do not load task-authoring. + Resume this caller after verified ticket readback or an explicit proposal/error; + retain this phase's scope, ownership, review and evidence gates. If the repository uses Beads, apply [the Beads integration](references/beads-integration.md) before choosing work or mutating task state. Use fresh `bd prime` guidance; diff --git a/skills/judge/SKILL.md b/skills/judge/SKILL.md index 6be94339..bb9ae786 100644 --- a/skills/judge/SKILL.md +++ b/skills/judge/SKILL.md @@ -48,9 +48,17 @@ a previous permission. This is an agent instruction, not a runtime cache. resuming artifact claims or executing consequential actions; verify current permission for the intended action, not historical approval. - Before creating or repairing task descriptions or acceptance criteria, apply - [ticket authoring](references/ticket-authoring.md); verify readable purpose, - criteria, ordered inputs and restart context without duplicating execution history. + Before creating or repairing task descriptions or acceptance criteria, verify + current scope and write authority. Conditionally Load `agentic-development:task-authoring` + using the host's available Skill-loading mechanism (not a shell command), with + established goal, scope, criteria, native tracker context and current authority. + Reuse its guidance when already available and current; do not load both routes + normally. If the optional capability is unavailable, apply contained + [ticket authoring](references/ticket-authoring.md) directly and report direct + reading, not activation; do not retry loading or block routine work on its absence. + For routine reads, claims, progress updates or closure, do not load task-authoring. + Resume this caller after verified ticket readback or an explicit proposal/error; + retain this phase's scope, ownership, review and evidence gates. If the repository uses Beads, apply [the Beads integration](references/beads-integration.md) before choosing work or mutating task state. Use fresh `bd prime` guidance; diff --git a/skills/plan/SKILL.md b/skills/plan/SKILL.md index ff536394..5f64dffb 100644 --- a/skills/plan/SKILL.md +++ b/skills/plan/SKILL.md @@ -57,9 +57,17 @@ a previous permission. This is an agent instruction, not a runtime cache. capabilities produce an explicit blocker, never simulated execution evidence. Use the coordinator's verified slice state when available; do not fabricate execution or acceptance. - Before creating or repairing task descriptions or acceptance criteria, apply - [ticket authoring](references/ticket-authoring.md); verify readable purpose, - criteria, ordered inputs and restart context without duplicating execution history. + Before creating or repairing task descriptions or acceptance criteria, verify + current scope and write authority. Conditionally Load `agentic-development:task-authoring` + using the host's available Skill-loading mechanism (not a shell command), with + established goal, scope, criteria, native tracker context and current authority. + Reuse its guidance when already available and current; do not load both routes + normally. If the optional capability is unavailable, apply contained + [ticket authoring](references/ticket-authoring.md) directly and report direct + reading, not activation; do not retry loading or block routine work on its absence. + For routine reads, claims, progress updates or closure, do not load task-authoring. + Resume this caller after verified ticket readback or an explicit proposal/error; + retain this phase's scope, ownership, review and evidence gates. If the repository uses Beads, apply [the Beads integration](references/beads-integration.md) before choosing work or mutating task state. Use fresh `bd prime` guidance; @@ -158,19 +166,14 @@ a previous permission. This is an agent instruction, not a runtime cache. them inline by default; save only at an explicitly authorized destination. Create or update issues only when requested/authorized in the agreed tracker. - Inspect existing issues first, reuse matching work, verify supported fields and - write goals, exclusions, criteria, dependencies, ownership and restart context. - On updates, consolidate current solution/steps/files rather than append competing - designs; move dated findings to notes, preserve criterion IDs/history, reconcile - native edges and check cycles. Readback must pass the human readability gate in - ticket-authoring.md, not merely confirm nonempty fields. - Include Research's verified task-specific reading references: files or authorized - local web captures, entrypoints/sections, reasons, order, source identity and - freshness/accessibility limits. Do not copy full research into tickets or invent - saved resources; record local-only pointers honestly. - Distinguish parent hierarchy from prerequisites. After each write, read back - the issue and verify fields/edges; report actual IDs and errors. If writes are - not authorized, return proposed tickets without claiming they were created. + Use the conditional task-authoring route above with the established planning + baseline; do not repeat its procedure here. It must consolidate current solution/steps/files, + preserve criteria/history and native ownership/edges, and read back actual writes. + Supply Research's verified task-specific reading references, source identity, + order and freshness/accessibility limits; do not invent saved resources. + Retain planning scope, review requirements and verification proof. Distinguish + parent hierarchy from prerequisites; report actual IDs and errors, or proposed + tickets when writes are unavailable. Task authoring does not approve this plan. Verify actual delegated planning completion, source identity and result locator before integration. Reconcile conflicts and retain unresolved decisions and missing diff --git a/skills/research/SKILL.md b/skills/research/SKILL.md index 7d6afbfa..7eb75e2f 100644 --- a/skills/research/SKILL.md +++ b/skills/research/SKILL.md @@ -50,9 +50,17 @@ a previous permission. This is an agent instruction, not a runtime cache. sources. Missing roadmap information is explicit; do not invent goals or expand bounded research to fill hierarchy labels. Resolve decision-blocking context only; roadmap proposals belong to requested planning or a decision-blocking need. - - Before creating or repairing task descriptions or acceptance criteria, apply - [ticket authoring](references/ticket-authoring.md); verify readable purpose, - criteria, ordered inputs and restart context without duplicating execution history. + - Before creating or repairing task descriptions or acceptance criteria, verify + current scope and write authority. Conditionally Load `agentic-development:task-authoring` + using the host's available Skill-loading mechanism (not a shell command), with + established goal, scope, criteria, native tracker context and current authority. + Reuse its guidance when already available and current; do not load both routes + normally. If the optional capability is unavailable, apply contained + [ticket authoring](references/ticket-authoring.md) directly and report direct + reading, not activation; do not retry loading or block routine work on its absence. + For routine reads, claims, progress updates or closure, do not load task-authoring. + Resume this caller after verified ticket readback or an explicit proposal/error; + retain this phase's scope, ownership, review and evidence gates. - If the repository uses Beads, apply [the Beads integration](references/beads-integration.md) before choosing work or mutating task state. Use fresh `bd prime` guidance; diff --git a/skills/task-authoring/SKILL.md b/skills/task-authoring/SKILL.md new file mode 100644 index 00000000..1653ff4c --- /dev/null +++ b/skills/task-authoring/SKILL.md @@ -0,0 +1,44 @@ +--- +name: task-authoring +description: Authors readable, restartable task tickets from established scope. Use when creating a ticket or repairing its description or acceptance criteria, not for routine reads, claims, progress updates or closure. +--- + +# Task authoring + +## Intent and outcome + +Create or repair a ticket from an existing goal, scope and criteria; return an +actual tracker ID with verified readback, or a clearly labeled proposal when +writing is unavailable. This is an optional bounded capability, not an eighth +development phase. Routine reads, claims, progress updates and closure return +to the caller without authoring. + +## Procedure + +1. Verify supplied goal, scope, criteria, native tracker context and current + authority. Before any write, apply the contained + [authorization limits](references/authorization-policy.md). + Inspect matching work and its native fields/history; reuse a matching ticket + rather than create competing work. Consume established decisions, do not invent + missing targets, requirements or approvals. Name decision-blocking gaps. +2. Before drafting or repairing, apply contained + [ticket guidance](references/ticket-authoring.md) for readable purpose, + observable criteria, ordered inputs and executable restart context. Reuse + identical guidance already available and current; do not mechanically reread. + Preserve criterion IDs, native owner/status/relationships and execution history; + scope changes need current permission, not merely a wording repair. + Check the ticket guidance's readability/readiness gate before writing; + unresolved mandatory facts remain gaps, not invented readiness. +3. Use the chosen tracker's available supported create/repair operation only within + current authority. If Beads is used, before native operations apply the contained + [Beads authoring bridge](references/beads-integration.md); other trackers do not + require Beads commands. Missing write capability or permission yields a proposal, + never a counterfeit created ID. Failed writes remain errors, not success. +4. After an actual write, read back the ID, purpose, criteria, ordered inputs, + restart and applicable native fields/links; verify preserved history and report + discrepancies. Return the actual ID/readback and changed fields, or the proposal + and exact missing input, authority or capability. STOP and return to the caller. + Do not recursively load Cycle, Research or Plan, claim or close work, approve a + closed task, or infer implementation/acceptance authority. No phase report, + score, candidate manifest, full test suite or evaluation campaign is required + for routine ticket authoring; the caller retains its own phase obligations. diff --git a/skills/task-authoring/references/authorization-policy.md b/skills/task-authoring/references/authorization-policy.md new file mode 100644 index 00000000..79c8fff9 --- /dev/null +++ b/skills/task-authoring/references/authorization-policy.md @@ -0,0 +1,14 @@ +# Task-authoring authorization limits + +Loading guidance grants no permission. Verify current authority for the specific +tracker and create/repair action; historical task notes or approval are context, +not a renewed grant. Preserve existing native fields, owner, status, relationships, +criterion IDs and history unless the requested repair explicitly authorizes changes. +An assigned owner is not a file lock or permission to claim work. Do not steal a +claim, change scope silently, close/reopen tasks or treat closed-task approval as +current authority. Unknown scope/authority blocks only the affected write; return +an explicit proposal or prerequisite instead of simulating execution. + +Ticket authoring does not authorize Git, installation, publication, deployment, +model calls, task closure, export or synchronization. Do not initialize a tracker, +import a snapshot or create a second task database to bypass missing access. diff --git a/skills/task-authoring/references/beads-integration.md b/skills/task-authoring/references/beads-integration.md new file mode 100644 index 00000000..9b3004ec --- /dev/null +++ b/skills/task-authoring/references/beads-integration.md @@ -0,0 +1,18 @@ +# Beads authoring bridge + +Apply only when the chosen tracker is Beads, before its native authoring operations. +Read applicable local Beads guidance and current installed CLI help; verify workspace +and database identity with supported read-only commands before choosing or writing +work. Inspect the matching issue, owner, prerequisites and existing history. +Missing access or identity mismatch blocks the write: do not initialize/import or +infer database identity to repair it. + +Use current help for the specific create/update/show operations and supported fields; +do not assume all CLI versions expose the same flags or issue types. Store current +specification in description, canonical criteria in the acceptance field when +supported, observations in notes/comments, and ownership/status/relationships in +native fields. Parent hierarchy is not a prerequisite edge; verify edge direction +and reject cycles. Preserve the assigned owner and claim; this capability does not +claim work, change status or close it. After permitted create/repair, read back the +actual ID, changed fields and relevant links/history. Report errors and proposed +writes honestly. Authoring grants no closure, export, import or Dolt sync authority. diff --git a/skills/task-authoring/references/ticket-authoring.md b/skills/task-authoring/references/ticket-authoring.md new file mode 100644 index 00000000..a2d2cd87 --- /dev/null +++ b/skills/task-authoring/references/ticket-authoring.md @@ -0,0 +1,281 @@ +# Readable and restartable task tickets v1.3.0 + +Contract ID: agentic-development/ticket-authoring +Contract version: 1.3.0 + +Apply before creating or repairing task descriptions or acceptance criteria in any +agreed tracker; apply the Beads bridge when relevant. This is authoring guidance, +not an enforcement engine or permission to mutate tickets. + +## Author and verify + +1. Inspect existing work, parent outcome, requirement sources, owner and blockers. + Reuse matching tickets. Write a title with a verb and specific outcome, not + "Improvements" or an implementation detail that hides the user/problem result. +2. Put Why first: observed problem, affected user, impact and desired value. Use + short sections/bullets, one idea per paragraph; separate facts from assumptions. + Explain the situation and what the reader will be able to do or understand + afterward, before naming architecture, storage or fixtures. Use plain language; + explain necessary domain terms. A commit or prior decision is context, not the problem. + Do not paste operational preambles, transcripts or circular justification. + Do not invent an end user for technical/non-behavioral work: identify the + affected maintainer/system, concrete difficulty and verifiable deliverable. +3. Bound one independently reviewable result. Split when outcomes need different + prerequisites or acceptance decisions, not by file or phase mechanically. + Technical detail comes after the problem, expected outcome, limits, success + criteria and open decisions. How describes the approach; acceptance criteria describe results, not + implementation steps such as "edit three files". Detail only the ready frontier; + do not invent paths, owners, estimates, metrics or approvals. +4. For bugs, state current behavior, expected behavior, minimal reproduction and + environment/version. A hypothesis is not an observed cause. If reproduction is + unavailable, name the missing input and next probe, not a confirmed diagnosis. +5. Give each criterion a stable ID, source and check. Use explicit Given/When/Then + with one observable outcome and relevant error/boundary cases. For non-behavioral + tasks use a verifiable Deliverable/Check instead of fabricated user behavior. + Define applicable NFR metric/approved target/unit/workload/environment/method. +6. Record blocking questions as Decision / owner / readiness impact, with the next + resolution action. Mark unknown owners/inputs explicitly. Resolve decision-critical + gaps before readiness; block the affected work, not unrelated permitted work. + Keep product decisions visible in their own section, not hidden in technical + vocabulary or presented as settled implementation details. State which work + can proceed and which depends on the answer; do not invent command names, + output formats or unavailable functionality to make a ticket look ready. +7. Store current specification in the description, canonical criteria in the + acceptance field when available (otherwise in the description), results in + notes/comments, and status/owner/prerequisite edges in native fields. Never + maintain divergent criteria copies. Dated notes contain criterion IDs, candidate, + checks/results, limits and next action; use locators, not full logs or secrets. + Do not copy general work instructions (authorization, review, Git or session + procedure) into every ticket. Reference the applicable shared policy instead; + retain only task-specific restrictions, review/evidence needs and exceptions. + Keep the first restart action specific to this task, not a generic work checklist. + Verify current facts against accessible sources before reusing technical starting + points; mark stale or unverified facts and their readiness impact. Removing a + promised feature or choosing a new storage contract is a scope change, not a wording repair. + Preserve history; explain supersession in a dated note. Do not change criterion IDs, + thresholds, scope, status or ownership merely to reformat; substantive changes + need current scoped authority. Do not bulk-rewrite unrelated tickets or close parents. +8. Read back the rendered ticket and fields after authorized writes. Use the + readiness checklist below. Readiness does not establish acceptance or closure. + +## Concrete execution frontier + +For implementation work, explain the delivery mechanism in the technical second +layer: named service or technology, managed versus self-hosted, execution environment, +and what code creates/configures versus what an operator/runtime injects or executes. +Spell out necessary domain abbreviations. For credentials or data, show the +producer → transport → consumer path and bootstrap/recovery boundary without values. +"Inject externally" or "configure securely" is not a complete How. Unknown provider +capabilities need a decision/probe, not an invented implementation; use a small +text diagram only when it clarifies the flow. + +Detail ready implementation tickets, not every distant roadmap item. Before +calling an implementation ticket ready, provide a verified file/asset map: + +| Action | Required content | +|---|---| +| Read | Repository-relative existing path, relevant symbol/section, why, reading order | +| Create | Exact proposed path, responsibility, expected inputs/outputs; confirm no equivalent exists | +| Modify | Existing path and bounded change; identify shared-file coordination | +| Preserve | User changes, shared infrastructure/state, credentials and compatibility contracts | +| Exclude | Adjacent work owned by another ticket, with the relevant dependency | + +Existing inputs must be inspected; distinguish inspected paths from suggested or +unavailable references. Proposed files are not existing assets or automatically +approved architecture. Resolve architecture/ownership prerequisites before fixing +new paths; use a bounded decision/research ticket when they are unknown. Non-code +or provider-side tasks name the exact documents/resources/operations instead of +inventing source files to satisfy the table. A broad folder list and "read the +repository" are not a restart plan. + +Use ordered steps with an observable intermediate result and dependencies, not +an exhaustive script or generic phase boilerplate. The first restart action must +name its input, operation and expected result; "inspect inputs then implement" is +insufficient. Scope and estimated size follow one reviewable outcome; split when +bootstrap, runtime integration and production rollout require different inputs, +authority or acceptance. Do not duplicate all consumer implementations in a +foundation ticket. Choose task names that expose the delivered capability. + +## Consolidate updates, do not append competing specifications + +Read the current description, criteria and native dependency edges before editing. +When a decision or audit changes the design, rewrite the affected current sections +into one consistent specification. Put dated findings, previous decisions and +execution history in notes/comments or a linked evidence artifact. Do not append +successive "architecture update" blocks that contradict How, exclusions or criteria. +Preserve prior history and stable criterion IDs; explain supersession, deduplicate +checks and obtain authority for substantive scope/target changes. Never silently +weaken acceptance or archive away evidence still needed to prove it. + +Recompute prerequisite edges when scope changes. Keep native edges and text +consistent, reject cycles, and do not make architecture selection depend on the +implementation whose design it must select. Parent/epic hierarchy is not a blocker +edge. Record actual owner/claim in native fields; do not retain "owner unassigned" +boilerplate that contradicts the tracker. A new current user authorization may +supersede a ticket's historical planning-only grant for the bounded action; +verify and record it, without inferring deployment, rotation or Git permission. + +## Readability gate before writing and after readback + +A human unfamiliar with this conversation must be able to answer in a quick scan: +why, what replaces what, which service runs where, how data/credentials flow, +which files/assets change, what stays untouched, the first step and the success check. +Prefer a short summary, ordered implementation steps and a file table over repeated +policy paragraphs. Link common security/review contracts and specialize only the +risks of this task; never use a word limit to omit decision-critical facts. +Follow the project's content-language policy; otherwise author in the user's +language while keeping identifiers/API names exact. + +If these answers are missing, repair the ticket before implementation or clearly +mark the exact unresolved input and its decision owner. Do not declare a roadmap +item execution-ready merely because it has no native blockers. Readback checks +meaning and contradictions, not only nonempty fields or a passing JSON schema. + +## Description template + +Preserve the required facts; combine headings for small tasks. Omit non-applicable +optional detail with a reason; do not leave unexplained placeholders. The product +questions come first; technical detail is a short second layer, not another work +protocol. Use native fields for owner, status, parent and prerequisite edges; when +unavailable, add a compact task-specific ownership/dependencies section below. + +~~~markdown +## Why + + + +## Expected outcome + + + +## Scope and non-goals +- In: +- Out: + +## Acceptance criteria + + + +## Open decisions + + + +## Technical starting point + + + + + +## File / asset map + + + +## Reading references +1. + +## Verification + check/seam and independent expected result> + + +## Restart + + +~~~ + +If criteria live in a separate acceptance field, read the description and that field +as one ticket; do not duplicate or hide them behind a technical report. Necessary +execution metadata remains recoverable through native fields and resolvable references, +not repeated policy text in the product explanation. + +Keep references small and ordered. Separate source, product/specification docs and +external references; explain each reading decision. Include canonical URLs for +local captures; mark ephemeral/local-only availability and source freshness. +Suggested unread references are not evidence. Do not auto-capture web content or +assume an installed package/current page matches a recorded source identity. + +## Acceptance scenario template + +~~~markdown +### — +Source: +Given: +When: +Then: +Check: +~~~ + +For non-behavioral criteria use Deliverable and Check. Missing facts/proof remain +unresolved or N/A with reason, never passed. + +## Filled example + +Hypothetical ticket, not execution evidence. This example keeps one result narrow; +inline output and missing-destination behavior would need separate criteria if in scope. + +~~~markdown +Title: Preserve the previous report when its destination already exists + +## Why +A user saving a new report to an occupied destination could lose an earlier report +without choosing to replace it. + +## Expected outcome +The user receives an explicit conflict message and keeps the earlier report intact. + +## Scope and non-goals +In: saving to an existing report destination without overwrite approval. +Out: approved replacement, renaming, inline output and missing destinations. + +## Acceptance criteria +### REPORT-1 — Preserve existing content +Source: This hypothetical task's no-implicit-overwrite requirement. +Given: The requested destination already contains an earlier report. +When: The user requests saving a new report without explicit overwrite permission. +Then: The earlier report's bytes remain unchanged. +Check: Compare the original bytes after the attempt; execution not-run. + +### REPORT-2 — Explain the conflict +Source: This hypothetical task's explicit-conflict-message requirement. +Given: The requested destination already contains an earlier report. +When: The user requests saving a new report without explicit overwrite permission. +Then: The response identifies the occupied destination as the reason saving was refused. +Check: Inspect the response for that destination and reason; execution not-run. + +## Open decisions +Exact conflict-message wording -> owner unknown -> decide before message-specific +assertions; REPORT-1 does not depend on that wording. + +## Technical starting point +Locate the existing report-saving entrypoint; its path is not yet verified. +A conflict check is a proposed approach, not the acceptance criterion. + +## Restart +Locate the saving entrypoint and a conflict-reproduction seam before implementation. +Native fields: owner unknown; no verified parent or prerequisite issue IDs. +~~~ + +"Add a conflict-check function" belongs in technical detail, not in Then. Do not +turn an uncertain approach into a product promise or mix future scoring/replacement +capabilities into a read-only/preservation result. + +## Readiness checklist + +- [ ] With only the ticket and its resolvable references, a new reader can explain + the problem, expected change, how success is observed and what remains to decide + without technical vocabulary or generic work instructions obscuring them. +- [ ] Limits precede technical detail; the task-specific starting point is short, + current or explicitly unverified, and identifies where to start. +- [ ] Title/outcome and task size are coherent; bug facts/reproduction are separated + from hypotheses when applicable. +- [ ] Criterion IDs/sources map to independent checks; relevant errors/boundaries + and approved NFR definitions are present, without implementation-only acceptance. +- [ ] File/asset map separates inspected inputs, proposed outputs, modifications, + preserved work and exclusions; service/runtime and delivery flow are explicit + where relevant, with ordered steps or an exact design prerequisite. +- [ ] Current sections are consolidated, criteria/history preserved, native owner + and prerequisites consistent and cycle-free; no unblocked-but-undesigned readiness. +- [ ] Required inputs resolve; owner, parent/prerequisite direction, permissions + and blocking decisions are explicit. Missing mandatory facts block readiness. +- [ ] Readback confirms fields/links, preserved history and unchanged criteria; + first restart action is executable or names its exact prerequisite. diff --git a/skills/test/SKILL.md b/skills/test/SKILL.md index 238f2831..d84778e7 100644 --- a/skills/test/SKILL.md +++ b/skills/test/SKILL.md @@ -42,9 +42,17 @@ a previous permission. This is an agent instruction, not a runtime cache. Verify repository root, local instructions, tools and task goal. - Before creating or repairing task descriptions or acceptance criteria, apply - [ticket authoring](references/ticket-authoring.md); verify readable purpose, - criteria, ordered inputs and restart context without duplicating execution history. + Before creating or repairing task descriptions or acceptance criteria, verify + current scope and write authority. Conditionally Load `agentic-development:task-authoring` + using the host's available Skill-loading mechanism (not a shell command), with + established goal, scope, criteria, native tracker context and current authority. + Reuse its guidance when already available and current; do not load both routes + normally. If the optional capability is unavailable, apply contained + [ticket authoring](references/ticket-authoring.md) directly and report direct + reading, not activation; do not retry loading or block routine work on its absence. + For routine reads, claims, progress updates or closure, do not load task-authoring. + Resume this caller after verified ticket readback or an explicit proposal/error; + retain this phase's scope, ownership, review and evidence gates. If the repository uses Beads, apply [the Beads integration](references/beads-integration.md) before choosing work or mutating task state. Use fresh `bd prime` guidance; diff --git a/tests/test_candidate_identity.py b/tests/test_candidate_identity.py index fe263fe7..8d0b8934 100644 --- a/tests/test_candidate_identity.py +++ b/tests/test_candidate_identity.py @@ -175,7 +175,8 @@ def test_all_skill_resources_are_identical_and_example_valid(self): "references/candidate-identity.schema.json", "references/candidate-identity.example.json", "references/candidate-scope.example.json"): baseline = (ROOT / "skills/cycle" / relative).read_bytes() - for skill in (ROOT / "skills").iterdir(): + for phase in ("cycle", "research", "plan", "implement", "test", "judge", "iterate"): + skill = ROOT / "skills" / phase self.assertEqual(baseline, (skill / relative).read_bytes(), str(skill)) self.cli("validate", ROOT / "skills/cycle/references/candidate-identity.example.json") diff --git a/tests/test_payload_inventory.py b/tests/test_payload_inventory.py index aba5320d..129a4fd5 100644 --- a/tests/test_payload_inventory.py +++ b/tests/test_payload_inventory.py @@ -169,7 +169,14 @@ def test_real_repository_inventory_excludes_eval_and_evidence(self): self.assertEqual(result.returncode, 0, result.stderr) files = [x["path"] for x in json.loads(result.stdout)["files"]] self.assertIn("scripts/observe.py", files) - self.assertEqual(sum(p.endswith("/SKILL.md") for p in files), 7) + expected_skills = { + "skills/cycle/SKILL.md", "skills/research/SKILL.md", "skills/plan/SKILL.md", + "skills/implement/SKILL.md", "skills/test/SKILL.md", "skills/judge/SKILL.md", + "skills/iterate/SKILL.md", "skills/task-authoring/SKILL.md", + } + skill_files = [p for p in files if p.endswith("/SKILL.md")] + self.assertEqual(len(skill_files), 8) + self.assertEqual(set(skill_files), expected_skills) for path in files: parts = path.split("/") self.assertNotIn(parts[0], ("tests", "integration", "research", "evidence"), path) diff --git a/tests/test_phase_final_report.py b/tests/test_phase_final_report.py index e580a7b8..95c1b3b4 100644 --- a/tests/test_phase_final_report.py +++ b/tests/test_phase_final_report.py @@ -58,7 +58,7 @@ def test_closure_is_evaluation_not_permission(self): self.assertIn(required, text, name) self.assertNotIn("bd create --", text) self.assertNotIn("bd close <", text) - refs = list((ROOT / "skills").glob("*/references/beads-integration.md")) + refs = [ROOT / "skills" / name / "references/beads-integration.md" for name in NAMES] self.assertEqual(len({p.read_bytes() for p in refs}), 1) if __name__ == "__main__": diff --git a/tests/test_production_discovery.py b/tests/test_production_discovery.py index 861df13e..3a7610f2 100644 --- a/tests/test_production_discovery.py +++ b/tests/test_production_discovery.py @@ -48,7 +48,13 @@ def test_repository_fixtures_excluded_but_operational_templates_preserved(self): files = [row["path"] for row in json.loads((self.out / "distribution.json").read_text())["files"]] self.assertFalse(any("fixture" in name or "synthetic-sessions" in name for name in files)) self.assertIn("skills/cycle/assets/output-template.md", files) - self.assertEqual(len(list(self.out.rglob("SKILL.md"))), 7) + self.assertEqual(len(list(self.out.rglob("SKILL.md"))), 8) + + def test_unknown_top_level_capability_rejected(self): + self.put("skills/unapproved/SKILL.md", "unapproved capability") + result = self.call("project") + self.assertNotEqual(result.returncode, 0) + # Rejection is the allowlist contract; no new atomic-output guarantee. def test_unclassified_nested_skill_variants_rejected_before_output(self): for name in ("SKILL.md", "SKILL.md.fixture", "skill.md", "SKILL.md.backup"): diff --git a/tests/test_skill_operability.py b/tests/test_skill_operability.py index 1697e0da..b8bb59bc 100644 --- a/tests/test_skill_operability.py +++ b/tests/test_skill_operability.py @@ -3,10 +3,11 @@ import unittest ROOT = Path(__file__).resolve().parents[1] +PHASE_NAMES = ('cycle', 'research', 'plan', 'implement', 'test', 'judge', 'iterate') class SkillOperability(unittest.TestCase): def test_every_entrypoint_selects_actions_and_explicit_transitions(self): - entries = list((ROOT / 'skills').glob('*/SKILL.md')) + entries = [ROOT / 'skills' / name / 'SKILL.md' for name in PHASE_NAMES] self.assertEqual(len(entries), 7) for path in entries: text = path.read_text() @@ -52,8 +53,8 @@ def test_coherent_units_have_task_bound_commit_decisions(self): self.assertIn(rule, text) class ShortSkillNames(unittest.TestCase): - def test_exact_seven_short_entrypoints(self): - names = {'cycle', 'research', 'plan', 'implement', 'test', 'judge', 'iterate'} + def test_exact_seven_phases_plus_optional_capability(self): + names = set(PHASE_NAMES) | {'task-authoring'} self.assertEqual({p.parent.name for p in (ROOT / 'skills').glob('*/SKILL.md')}, names) for name in names: path = ROOT / 'skills' / name / 'SKILL.md' @@ -85,13 +86,13 @@ def test_contribution_guide_directs_operable_authoring(self): class PhaseScope(unittest.TestCase): def test_phase_only_request_returns_instead_of_auto_executing_handoff(self): - for path in (ROOT / 'skills').glob('*/SKILL.md'): + for path in (ROOT / 'skills' / name / 'SKILL.md' for name in PHASE_NAMES): with self.subTest(skill=path.parent.name): self.assertIn('For a phase-only request', path.read_text()) self.assertIn('proposed handoff, then stop', path.read_text()) def test_safety_gates_precede_execution(self): - for path in (ROOT / 'skills').glob('*/SKILL.md'): + for path in (ROOT / 'skills' / name / 'SKILL.md' for name in PHASE_NAMES): text = path.read_text() from test_cycle_disclosure import workflow_steps steps = workflow_steps(text) @@ -116,7 +117,7 @@ def test_safety_gates_precede_execution(self): class CanonicalExecutionOrder(unittest.TestCase): def test_entrypoints_reference_one_artifact_format(self): - for path in (ROOT / 'skills').glob('*/SKILL.md'): + for path in (ROOT / 'skills' / name / 'SKILL.md' for name in PHASE_NAMES): text = path.read_text() self.assertEqual(text.count('references/requirements-output.md'), 1, path) self.assertIn('apply their checklists and selected delivery form', text, path) @@ -125,7 +126,7 @@ def test_entrypoints_reference_one_artifact_format(self): self.assertNotIn('Use ' + filename + ' headings:', text, path) def test_handoff_is_last_after_lifecycle_safeguards(self): - for path in (ROOT / 'skills').glob('*/SKILL.md'): + for path in (ROOT / 'skills' / name / 'SKILL.md' for name in PHASE_NAMES): from test_cycle_disclosure import workflow_steps steps = workflow_steps(path.read_text()) self.assertEqual(steps[-1][1], 'Execute the handoff or stop', path) diff --git a/tests/test_task_authoring.py b/tests/test_task_authoring.py new file mode 100644 index 00000000..6fa9f5bd --- /dev/null +++ b/tests/test_task_authoring.py @@ -0,0 +1,93 @@ +"""User-scope source checks and hypothetical routes; no agent/tracker execution.""" +from pathlib import Path +import re +import unittest + +ROOT = Path(__file__).resolve().parents[1] +PHASES = ('cycle', 'research', 'plan', 'implement', 'test', 'judge', 'iterate') +CAPABILITY = ROOT / 'skills/task-authoring' + +# Independently specified natural requests, not generated activation commands. +SCENARIOS = ( + ('Create a ticket for the approved report-preservation fix.', 'create', True), + ('Repair this ticket so its criteria describe the expected outcome.', 'repair', True), + ('Read this existing ticket.', 'read', False), + ('Claim this task for the assigned worker.', 'claim', False), + ('Record progress on the task.', 'progress', False), + ('Close the completed task.', 'closure', False), +) + + +class TaskAuthoring(unittest.TestCase): + def test_discovery_and_natural_route_scenarios(self): + text = (CAPABILITY / 'SKILL.md').read_text() + metadata = text.split('---', 2)[1] + self.assertIn('name: task-authoring', metadata) + for word in ('creating', 'repairing', 'routine reads', 'claims', 'progress updates', 'closure'): + self.assertIn(word, metadata) + self.assertEqual([intent for _, intent, load in SCENARIOS if load], ['create', 'repair']) + self.assertLessEqual(len(text.splitlines()), 500) + for phase in PHASES: + source = (ROOT / 'skills' / phase / 'SKILL.md').read_text() + with self.subTest(phase=phase): + self.assertEqual(source.count('Load `agentic-development:task-authoring`'), 1) + self.assertIn('Before creating or repairing task descriptions', source) + self.assertIn('For routine reads, claims, progress updates or closure, do not load task-authoring.', source) + self.assertIn('established goal, scope, criteria, native tracker context and current authority', source) + + def test_unavailable_and_already_loaded_routes(self): + for phase in PHASES: + source = (ROOT / 'skills' / phase / 'SKILL.md').read_text() + with self.subTest(phase=phase): + for rule in ('already available and current', 'do not load both routes', + 'If the optional capability is unavailable', + 'references/ticket-authoring.md', 'not activation', + 'do not retry loading', 'Resume this caller'): + self.assertIn(rule, source) + canonical = (CAPABILITY / 'references/ticket-authoring.md').read_bytes() + for phase in PHASES: + self.assertEqual((ROOT / 'skills' / phase / 'references/ticket-authoring.md').read_bytes(), canonical) + + def test_bounded_output_and_denied_failed_write_scenarios(self): + text = (CAPABILITY / 'SKILL.md').read_text() + for rule in ('actual tracker ID with verified readback', 'clearly labeled proposal', + 'Failed writes remain errors', 'After an actual write, read back', + 'verify preserved history', 'STOP and return to the caller', + 'Do not recursively load Cycle, Research or Plan', + 'Missing write capability or permission yields a proposal', + 'Preserve criterion IDs, native owner/status/relationships', + 'do not invent', 'No phase report'): + self.assertIn(rule, text) + self.assertNotRegex(text, r'Load `agentic-development:(cycle|research|plan)`') + for absent in ('requirements-output.md', 'common-output.md', 'review-policy.md', + 'candidate-identity.md', 'commit-report.md'): + self.assertNotIn(absent, text) + + def test_contained_authority_and_conditional_native_bridge(self): + text = (CAPABILITY / 'SKILL.md').read_text() + for link in re.findall(r'\]\(([^)]+)\)', text): + path = (CAPABILITY / link).resolve() + self.assertTrue(path.is_relative_to(CAPABILITY.resolve())) + self.assertTrue(path.is_file()) + self.assertIn('If Beads is used, before native operations', text) + self.assertNotRegex(text, r'`bd [^`]+`') + authority = (CAPABILITY / 'references/authorization-policy.md').read_text() + for rule in ('Loading guidance grants no permission', 'historical task notes', + 'Do not steal a', 'close/reopen tasks', 'second task database'): + self.assertIn(rule, authority) + bridge = (CAPABILITY / 'references/beads-integration.md').read_text() + for rule in ('current installed CLI help', 'database identity', + 'Preserve the assigned owner and claim', 'read back the', 'reject cycles'): + self.assertIn(rule, bridge) + + def test_inventory_exact_allowlist_not_eighth_phase(self): + import sys + sys.path.insert(0, str(ROOT / 'tools')) + from production import SKILLS + self.assertEqual(SKILLS, frozenset(PHASES) | {'task-authoring'}) + self.assertEqual({p.parent.name for p in (ROOT / 'skills').glob('*/SKILL.md')}, SKILLS) + self.assertFalse((CAPABILITY / 'evals/evals.json').exists()) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_workflow_contracts.py b/tests/test_workflow_contracts.py index fac34d9f..0b1685c7 100644 --- a/tests/test_workflow_contracts.py +++ b/tests/test_workflow_contracts.py @@ -4,6 +4,7 @@ import unittest ROOT = Path(__file__).resolve().parents[1] +PHASE_NAMES = ('cycle', 'research', 'plan', 'implement', 'test', 'judge', 'iterate') SKILLS = ROOT / "skills" @@ -13,7 +14,7 @@ def test_boundary_reports_are_contained_and_consistent(self): paths = sorted(SKILLS.glob("*/references/" + name)) self.assertEqual(len(paths), 7, name) self.assertEqual(len({p.read_bytes() for p in paths}), 1, name) - for p in SKILLS.glob("*/SKILL.md"): + for p in (SKILLS / name / "SKILL.md" for name in PHASE_NAMES): with self.subTest(skill=p.parent.name): self.assertIn("references/commit-report.md", p.read_text()) self.assertIn("references/session-report.md", p.read_text()) @@ -84,7 +85,7 @@ def test_common_output_contract_is_direct_and_identical(self): refs = list(SKILLS.glob("*/references/common-output.md")) self.assertEqual(len(refs), 7) self.assertEqual(len({p.read_bytes() for p in refs}), 1) - for p in SKILLS.glob("*/SKILL.md"): + for p in (SKILLS / name / "SKILL.md" for name in PHASE_NAMES): self.assertIn("references/requirements-output.md", p.read_text()) self.assertIn("references/common-output.md", p.read_text()) @@ -131,7 +132,9 @@ def test_all_source_markdown_links_resolve(self): def test_shared_safety_policies_and_budget_guard_remain(self): for name in ("authorization-policy.md", "review-policy.md"): - paths = list(SKILLS.glob("*/references/" + name)) + # These shared phase policies stay identical across the seven phases; + # task-authoring has separately scoped minimal authorization limits. + paths = [SKILLS / phase / "references" / name for phase in PHASE_NAMES] self.assertEqual(len(paths), 7) self.assertEqual(len({p.read_bytes() for p in paths}), 1) text = (SKILLS / "iterate/SKILL.md").read_text() diff --git a/tools/production.py b/tools/production.py index 16b04806..6758ac22 100644 --- a/tools/production.py +++ b/tools/production.py @@ -12,7 +12,7 @@ import zipfile ROOT = Path(__file__).resolve().parents[1] -SKILLS = frozenset(("cycle", "research", "plan", "implement", "test", "judge", "iterate")) +SKILLS = frozenset(("cycle", "research", "plan", "implement", "test", "judge", "iterate", "task-authoring")) DEVELOPMENT_COMPONENTS = frozenset(("AGENTS.md", "evals", "evaluations", "tests", "__pycache__", "evidence", "research", "integration", "evaluation-fixtures", "conformance-fixtures", "fixtures")) diff --git a/website/tests/test_skill_discovery.py b/website/tests/test_skill_discovery.py index 109cc1e7..c800ef36 100644 --- a/website/tests/test_skill_discovery.py +++ b/website/tests/test_skill_discovery.py @@ -3,7 +3,7 @@ import unittest from pathlib import Path ROOT = Path(__file__).resolve().parents[2] -EXPECTED = {'cycle', 'research', 'plan', 'implement', 'test', 'judge', 'iterate'} +EXPECTED = {'cycle', 'research', 'plan', 'implement', 'test', 'judge', 'iterate', 'task-authoring'} class SkillDiscovery(unittest.TestCase): def test_exact_names_and_matching_frontmatter(self): skills = ROOT / 'skills'