# DogdouSpec v1 CLI Contract Status: Normative implementation contract ## Quick Task Entry `task quick` accepts `--title`, repeatable `--scope`, `--done-when`, `--why`, optional repeatable `--origin`, `--depends-on`, and `--term key=value`, plus `--iteration`, `--expected-revision`, `--start`, and `--dry-run`. It auto-selects exactly one active iteration when omitted. Requirement origins are iteration `implements` references; no origin generates exactly one current-iteration `supports` origin for operational work. Operational tasks never satisfy product Requirement coverage, but remain normal non-terminal readiness blockers. `--start` is one writer transaction and one tasks revision: the stored Task is already `in-progress`, has equal create/update/start timestamps, generated start history, and durable creation receipt. `--dry-run` returns the generated task-add representation and leaves documents, revisions, and transaction temporary state unchanged. To make a write replayable, supply both `--id` and `--operation-id`; the operation ID must begin with a UTC `YYYYMMDDTHHmmssZ` timestamp, which becomes the generated request time. Dry-run emits canonical XML with `--format xml`; `--format human` emits a stable preview summary and directs callers to XML for the request. This document defines the first usable repository-local CLI. XML is the machine-facing request and result format. The CLI is a secure XML/XPath engine with a small set of schema-aware atomic helpers; it is not an autonomous project manager. ## 1. Invocation and discovery The repository wrapper is: ```text dogdouspec.cmd ``` It invokes the pinned local executable without global installation. From the working directory, commands walk ancestors to the nearest `.dogdouspec` directory. `--workspace-root` overrides discovery and must name that exact directory or its parent project directory. All persisted document paths in commands and results are normalized `/` separated paths relative to `.dogdouspec`: ```text 20260823-xpath-core/spec.xml 20260823-xpath-core/tasks.xml knowledge.xml backlog.xml ``` Absolute document paths, `..`, alternate data streams, device paths, and paths escaping through symlinks or junctions are rejected. ## 2. v1 command surface ```text dogdouspec workspace discover dogdouspec workspace init dogdouspec iteration list dogdouspec iteration create dogdouspec iteration constraint add dogdouspec iteration constraint list dogdouspec iteration constraint remove dogdouspec iteration readiness dogdouspec iteration confirm --stdin|--file dogdouspec query dogdouspec search dogdouspec validate dogdouspec schema show dogdouspec schema status dogdouspec schema sync dogdouspec template show dogdouspec append --stdin|--file dogdouspec task update --stdin|--file dogdouspec task review --stdin|--file dogdouspec task add --stdin|--file dogdouspec task quick dogdouspec task revise --stdin|--file dogdouspec task split --stdin|--file dogdouspec task start dogdouspec task verify dogdouspec task finish dogdouspec task block dogdouspec task resume dogdouspec task blockers dogdouspec task context dogdouspec task next dogdouspec task scope dogdouspec requirement propose --stdin|--file dogdouspec change propose --stdin|--file dogdouspec change apply --stdin|--file dogdouspec backlog add|list|schedule|complete|cancel dogdouspec transaction apply --stdin|--file ``` `transaction apply` is the low-level escape hatch. The Skill normally uses templates, `task quick`, `task add/revise/split`, `requirement propose`, `change propose/apply`, `append`, `task update`, and `iteration confirm`. Every mutating command identifies itself as mutating in help output and uses revision protection for each existing document it may change. Low-level writes require explicit expected revisions; porcelain helpers may resolve current revisions as documented below. ### 2.1 Read-only task selection and scope verification `task next` derives one actionable Task without writing managed state: ```powershell .\dogdouspec.cmd task next --iteration "" --format xml ``` It returns the first `in-progress` or `verification` Task in document order. If none exists, it returns the first `pending` Task whose `depends-on` references resolve to terminal Tasks across the declared `document`, `iteration`, or `project` boundary. A local XPath pending-task expression cannot establish cross-document dependency readiness and must not substitute for this helper. `task scope` compares changed repository-relative paths with a selected Task's declared `` and writes nothing: ```powershell .\dogdouspec.cmd task scope --iteration "" --task "" --path src/DogdouSpec.Core/Tasks/TaskUpdater.cs --format xml .\dogdouspec.cmd task scope --iteration "" --task "" --git-ref HEAD --format xml .\dogdouspec.cmd task scope --iteration "" --task "" --git-range main...HEAD --format xml ``` Exactly one input source is required. `--path` is repeatable and names concrete changed paths. `--git-ref REV` resolves `REV` to one commit and compares that commit to the current index and working tree; it reports tracked changes only and deliberately excludes untracked files. `--git-range A..B` uses Git's two-endpoint diff and `A...B` uses Git's merge-base diff. The command resolves each user revision to a commit before diffing, accepts neither option-like revisions nor malformed ranges, uses `--name-only -z --no-renames`, and bounds its read-only Git child process to 30 seconds. External diff drivers and text conversion filters are explicitly disabled with `--no-ext-diff --no-textconv`. A scope repository `path` is a literal repository-relative base (`.` is the root). Includes and excludes are evaluated relative to that base. `/` and `\` normalize to `/`; redundant `.` components normalize away; `*` matches within one segment, `?` one non-separator character, and `**` zero or more complete path segments. `.` and `**` include every concrete repository path. Use `directory/**` for recursive directories; a trailing slash is not a recursive shorthand. On Windows matching is case-insensitive; elsewhere it is ordinal case-sensitive. If any applicable repository block excludes a path, that exclusion wins globally over every include. Absolute, traversal, device, ADS, control-character, and wildcard changed-path inputs are rejected. Output lists are ordinal-sorted. A valid scope report exits 0. A completed report containing one or more out-of-scope paths exits 1; argument, Git, XML, and workspace errors retain their normal diagnostic exit codes. ### 2.1.1 Blocker management and recheck queues `task block` transitions an active Task to `status="blocked"` and records a structured finding record under ``: - Encodes blocker category (`--blocker-kind`), responsible owner (`--blocker-owner`), and target recheck timestamp (`--blocker-review-at`) as index terms adhering to `TokenValueType` (compact UTC `yyyyMMddTHHmmssZ`). - Preserves resolution condition and next action in the record body. - Mutates `tasks.xml` atomically with revision protection. `task resume` resolves one or all active blocker findings and transitions the Task back to `status="in-progress"`: - Requires explicit resolution intent (`--finding ` or `--all`) and a non-empty caller-supplied `--summary` when resolving active findings (fails closed with `INVALID_ARGUMENT` if omitted). - Creates a `` covering the finding with `relation="resolves"`, or sets finding `status="resolved"`. - Resumes the task only when no other active blockers remain, upstream dependencies remain satisfied, origin requirements remain approved, and the iteration is not in `replanning`. `task blockers` is a read-only query helper: - Aggregates active task blockers, unmet upstream dependencies, and general active findings. - Sorts items deterministically: overdue items first, then upcoming due items, then undated items. - Supports filtering by `--owner`, `--task`, `--kind`, and `--due-only`. ### 2.1.2 Bounded task recovery context `task context` produces a deterministic, bounded XML or human view for starting or resuming work without loading transient external reports. The Skill requires this read before execution of each selected or resumed Task; use `--no-history` when supplemental records are unnecessary: - **Essential Context (Non-truncatable)**: Always contains task identity, objectives, rationale, scope, constraints, origin requirements with key points, acceptance criteria, dependency statuses, active blockers/findings, latest status records, and progression assessment (action category, reason code, recommended/permitted/prohibited actions, and authority boundaries). Constraints are emitted in document order, iteration constraints first (`scope="iteration"` from `spec.xml`), then Task constraints (`scope="task"`), retaining IDs, text, and optional `kind`. Both scopes apply with no implicit override or deduplication. Raw Task queries and `task show` expose only Task-local data and cannot replace this context read. - **Fail-Closed Limit Enforcement**: If Essential Context alone exceeds `--max-bytes` (default: 32,768), the command refuses to truncate and fails closed with `LIMIT_EXCEEDED` (exit code 7). - **Greedy Supplemental Budgeting**: Historical execution records are budgeted greedily into the remaining byte limit; omitted records are reported with `truncated="true"`, `omitted_records=""`, and a copy-pasteable follow-up XPath locator. - **Read-Drift Protection**: Verifies snapshot consistency between `tasks.xml` and `spec.xml`, retrying bounded transient drift and failing closed on persistent conflict. Re-read context after a constraint change. Resolve conflicting constraints before execution; if essential context exceeds the limit, increase `--max-bytes` instead of bypassing the failed context query. ### 2.1.3 Bounded history and structured check authoring `task records --task ID [--iteration ID] [--last N] [--kind KIND ...] [--fields id,kind,created_at,summary,checks,covers] [--max-summary N] [--max-bytes N]` reads persisted records in document order. Filtering precedes last-N selection (default 20, maximum 10000). Default fields are `id,kind,status,created_at,summary`; supported children include index, summary, context, options, impact, outcome, checks, covers and sources. The derived `task-records` envelope reports source tasks revision and total/matching/count/ omitted counts. Optional summary truncation reports `summary_truncated` and `summary_original_characters` (UTF-16 code units, without splitting surrogate pairs). Byte overflow fails with `LIMIT_EXCEEDED`, rather than dropping records. This read never replaces effective `task context` before execution. `task record` supports `--check-command`, `--check-result passed|failed|skipped`, `--check-exit-code`, `--check-kind` (default command), and `--check-summary` (default record summary). Any check flag requires result; exit code requires a command. The flags create the existing checks/check structure and `--covers` retains criterion links. They do not pass acceptance or supply review approval. Task add/update/revise/review reject new timestamps beyond current UTC plus five minutes, allowing continuation at already-committed legacy future metadata. Generated task operations clamp to committed create/update time. Verified replays preserve original identity and timestamp. ### 2.2 Backlog lifecycle helpers `backlog add`, `schedule`, `complete`, and `cancel` are bounded mutating helpers; `backlog list` is read-only. Every mutation requires the exact positive `backlog.xml` revision plus stable `--id`, `--operation-id`, `--actor`, and `--occurred-at` values at the core boundary. Porcelain may generate omitted identity fields: add's item ID and operation ID are unique, actor defaults to `DOGDOUSPEC_ACTOR` or `agent`, and time is UTC now. Transitions require the target item ID. With an explicit operation ID and omitted time, a valid `yyyyMMddTHHmmssZ` prefix supplies deterministic time; otherwise pass time explicitly. `` on the mutation result returns exact replay parameters. Omitting operation ID on retry generates a new operation, so retain the receipt. `kind` is an open token, not an enum; defect-specific rules still apply. An identical retry at the current or immediately prior revision returns `already_applied="true"`; changed payload, reused operation ID, or stale unrelated revision fails closed. ```powershell .\dogdouspec.cmd backlog add --id --operation-id --actor --occurred-at --kind defect --severity p1 --summary --statement --rationale --impact --source-iteration --source-task --review-condition --expected-revision --format xml .\dogdouspec.cmd backlog list --status open --kind defect --severity p1 --format xml .\dogdouspec.cmd backlog schedule --id --operation-id --actor --occurred-at --resolving-task --expected-revision --format xml .\dogdouspec.cmd backlog complete --id --operation-id --actor --occurred-at --resolving-task --expected-revision --format xml .\dogdouspec.cmd backlog cancel --id --operation-id --actor --occurred-at --expected-revision --format xml ``` Every item requires a source iteration or Task, non-empty impact, and exactly one target iteration or review condition. Defect items additionally require a `kind=defect` index term and severity `p0` through `p3`. Scheduling permits only `open -> scheduled`; completion and cancellation permit `open|scheduled` to a terminal state. Terminal items are immutable. `--resolving-task` writes a `resolved-by` reference on the backlog receipt as traceable evidence; it never changes Task origin or any `tasks.xml` document. Actor separation is recorded provenance, not authenticated identity. ## 3. Result and diagnostic envelope Preview mutations use `dry_run="true"` on the envelope and human heading `DRY RUN, nothing written`. Public `transaction apply --dry-run` validates prospective documents without publishing. Quick dry-run XML instead retains the canonical task-add request with a leading XML comment identifying the preview; it remains consumable by `task add`. `task finish` performs missing start/verify/complete transitions sequentially, one revision per transition. Its result reports the full document revision range and ordered `` elements. If a later step fails, earlier committed transitions remain: stdout contains `partial="true"` and their receipts, stderr contains diagnostics, and exit status is nonzero. Re-query before retrying. Independent review gates remain enforced. V1 formats are `xml` and `human`. `xml` is the default when stdout is not an interactive terminal. Skills explicitly request `--format xml`. A successful mutation returns changed documents and idempotency state: ```xml ``` Failures return diagnostics on stderr: ```xml Reload the target document and rebuild the update. ``` Exit codes: | Code | Meaning | |---:|---| | 0 | Success, including a verified idempotent retry | | 1 | Read-only scope verification completed with one or more out-of-scope paths | | 2 | Command, XML request, XPath, or argument error | | 3 | Schema or semantic validation failure | | 4 | Revision, lock, cardinality, or idempotency conflict | | 5 | Protected product decision or authority gate | | 6 | Filesystem commit or recovery failure | | 7 | Input, query, projection, or output limit exceeded | Stable codes are more important than prose wording. ## 4. Workspace and Iteration commands ### 4.1 Discover ```powershell dogdouspec workspace discover --format xml ``` ```xml ``` Discovery performs no write. ### 4.2 Initialize ```powershell dogdouspec workspace init --format xml ``` Initialization creates `.dogdouspec`, `_schema`, `_skill`, `knowledge.xml`, and `backlog.xml`, and installs the embedded Skill under `.agents/skills/dogdouspec/`. It fails without mutation if managed state already exists. `_schema` receives readable version-matched schema copies; the embedded CLI schemas remain authoritative. The installed Skill includes constraint authoring and required effective-context guidance; `AGENTS.md` is reconciled by the caller, not generated by the CLI. ### 4.3 List and create ```powershell dogdouspec iteration list --format xml dogdouspec iteration create ` --id 20260823-xpath-core ` --kind feature ` --constraint "environment: .NET 10 is required" ` --format xml ``` `iteration create` (alias: `iteration new`) requires `--id` to be explicit and follow the `TimeFirstIdType` grammar (`YYYYMMDD-name` or `YYYYMMDDTHHmmssZ-name`, e.g., `20260823-feature` or `20260825T143000Z-feature`). `kind` is `feature` or `research`. Creation atomically creates the directory, `spec.xml`, and `tasks.xml`; it never chooses a suffix silently. `--file PATH` accepts a UTF-8 `` document (max 16 MiB), available via `template show --name iteration.create`. It contains exactly one matching `product` or `research` body plus optional `index`, `constraints`, and `design`. It cannot supply lifecycle metadata, confirmations or operation receipts. Requirements and design decisions must be proposed, questions open, criteria pending. The resulting managed spec still passes complete existing schema and semantic validation before any directory is published. Acceptance comes from the file or repeatable `--criterion`, never both. Missing acceptance inherits generated criteria; activation requires defined text. Explicit owner-authorized `--activate` approves baseline requirements/design and generates confirmation targets from the supplied IDs; product criteria remain pending. This is creation intent, not a new managed document schema or transaction request. Generated activation confirmation IDs include the iteration slug to avoid collisions among same-day iterations. Iteration listing discovers candidate iteration direct child directories matching the time-first pattern and returns summaries in deterministic ascending chronological order based on `created_at` timestamp (parsed as UTC), with ordinal directory/iteration `id` as the tie-breaker. Both `xml` (as `@created_at` attribute on ``) and `human` output formats expose `created_at`. It reports malformed candidate directories as structured diagnostics rather than hiding them. ### 4.4 Iteration constraints `iteration create` accepts optional repeatable `--constraint ` for both feature and research iterations. Later authoring uses: ```powershell dogdouspec iteration constraint add --iteration --text [--kind ] [--constraint-id ] [--expected-spec-revision ] --format xml dogdouspec iteration constraint list [--iteration ] --format xml dogdouspec iteration constraint remove --iteration --constraint-id [--expected-spec-revision ] --format xml ``` All three commands accept `--workspace-root` and `--format xml|human`. `--iteration` may be omitted when exactly one candidate can be resolved; ambiguous or missing candidates require an explicit iteration. - Constraints live in `/iteration/constraints` in `spec.xml` and apply to all Tasks in that iteration. Add generates a time-first ID unless `--constraint-id` supplies one. List is read-only and returns IDs, optional kinds, and text in document order; XML uses an `` envelope. Remove requires an exact ID and removes the wrapper after its last constraint is removed. - Constraint `kind` is an optional open token matching `[a-z][a-z0-9-]*`, not an enumeration. Creation and add without explicit `--kind` recognize `kind: text` and `[kind] text`, lowercase the kind, and strip the prefix from stored text. Without a recognized prefix the text remains untyped. Add with explicit `--kind` lowercases that value and preserves the complete supplied text apart from outer whitespace. Creation's `--kind feature|research` selects the iteration type. - Add/remove change only `spec.xml` through the validated atomic writer and advance its revision once. `--expected-spec-revision` checks that document's exact positive revision; it is independent of `tasks.xml` and is not named `--expected-revision`. When omitted the helper resolves the current revision automatically; no `--revision latest` flag is required. A stale explicit revision fails with `REVISION_CONFLICT`. - Add/remove reject terminal iterations (`completed`, `cancelled`, `superseded`). Technical constraints do not approve Requirements, waive product acceptance, change protected design decisions, or override owner rules. Material product changes still use change proposal and owner gates. - `task context` always includes both iteration and Task constraints in its essential section, even with `--no-history`; neither scope overrides the other. The Skill must read that context before starting or resuming work. Fresh workspaces receive these embedded schema and Skill resources. Existing workspaces refresh them through the Guide-first `schema status/sync` and `skill status/sync` upgrade contract. The optional XML extension requires no managed-document migration; synchronization does not edit existing XML or `AGENTS.md`. Callers reconcile repository or shared bootstrap instructions to require the effective-context read. ## 5. XPath query contract ### 5.1 Evaluation The CLI compiles the full XPath expression through .NET `System.Xml.XPath`. V1 is XPath 1.0. A custom `XsltContext` provides string variables and the two projection functions. Standard axes, predicates, unions, conversions, and composition remain owned by the .NET engine. The fixed extension binding is: ```text prefix: ds URI: urn:dogdouspec:xpath:functions:1 ``` Managed documents themselves have no namespace. Variables are supplied as `--var name=value`. Names match `[a-z][a-z0-9_]*`, are case-sensitive, and omit the XPath `$`. V1 variables are XPath strings. Duplicate, invalid, and unbound variables are errors. ### 5.2 Structural projection ```xpath ds:filter(node-set, member, ...) ds:filter-out(node-set, member, ...) ``` The first argument must contain only element nodes. At least one string member is required. A member is exactly: ```text @attribute-name direct-child-name ``` Members do not contain paths, predicates, axes, wildcards, functions, or namespace prefixes. `ds:filter` preserves each selected root and retains only named direct attributes and direct children. A retained child keeps its complete subtree. `ds:filter-out` preserves each selected root and removes named direct attributes and direct children. Other members remain complete. A valid absent member is ignored. Duplicate members are coalesced. Input root, attribute, and child order is preserved. The result is a read-only composable XPath node-set, not a mutation address. Examples: ```xpath ds:filter(//task[@status='pending'], '@id', '@status', 'index') ``` ```xpath ds:filter-out(//task[@id=$task_id], 'records')/context ``` ```xpath ds:filter(//task, '@id', '@status', 'index') [index/term[@key='topic' and @value=$topic]] ``` ### 5.3 Single-document query ```powershell dogdouspec query ` --document 20260823-xpath-core/tasks.xml ` --var task_id=20260823-task-xpath-projection ` --xpath '//task[@id=$task_id]' ` --format xml ``` An all-element node-set uses one wrapper and embeds results directly: ```xml ... ``` `derived="true"` means an extension function produced projected values. Scalar results use one `result` element. Attribute, text, comment, processing-instruction, or mixed node-sets use minimal typed item wrappers. No successful result is silently truncated. Both `query` and `search` accept exactly one of `--xpath EXPR` or `--xpath-file PATH` (UTF-8 file, max 16 MiB). Variable bindings and XPath limits are identical. File input avoids shell interpolation and Git Bash/MSYS path rewriting. `query --warn-empty` is opt-in: an empty node-set emits a warning `EMPTY_QUERY_RESULT` on stderr with the document root/direct children while stdout and exit status remain unchanged. Scalar zero is not an empty node-set. Backlog item queries use `/backlog/items/item`. ### 5.4 Project search `search` evaluates the same XPath independently against every document in a declared boundary: ```powershell dogdouspec search ` --scope project ` --var topic=xpath-projection ` --xpath "ds:filter(//*[@id and index/term[@key='topic' and @value=$topic]], '@id', 'index')" ` --format xml ``` Scopes are `iteration` and `project`; iteration scope also requires `--iteration`. Documents are visited in normalized relative-path order. Each non-empty document result receives one compact document wrapper. One XPath never crosses documents. Search excludes `_schema`, `_skill`, temporary files, and unsupported document types unless explicitly requested by a future command. ### 5.5 Limits V1 defaults: - Managed XML document: 16 MiB. - Final serialized query output: 4 MiB. - Final result nodes: 10,000. - Total intermediate projected nodes: 50,000. Exceeding a limit fails with no partial success output and recommends a narrower XPath or structural projection. Limits are checked before expensive serialization where possible. ## 6. Schema and template discovery ```powershell dogdouspec schema show --name tasks --version 1.0 dogdouspec schema status --version 1.0 --format xml dogdouspec template show --name record.discussion --version 1.0 ``` `schema show`, `schema status`, and `template show` are read-only. `schema show` and `template show` write exact embedded resources to stdout. `schema status` reports whether each optional readable copy under `.dogdouspec/_schema` is matching, modified, or missing; exit code `1` means differences were found. Templates are valid examples, not hidden scripts. An Agent copies a template, replaces example identity and content, validates it, then submits it. After the calling Agent reads `dogdouspec skill guide --all`, assesses the repository, and determines that readable schema copies should be refreshed, it may invoke: ```powershell dogdouspec schema sync --expected-version 1.0 --format xml ``` This command acquires the workspace writer lock, runs startup recovery, verifies that every managed document declares the expected supported schema version, stages every changed known XSD, writes a recovery marker, and either publishes the set or restores the previous copies. It is idempotent when all copies match. It never changes the schema version or content of managed XML documents. V1 templates include: - `record.discussion` - `record.finding` - `record.verification` - `task.update` - `task.review` - `iteration.confirmation` - `iteration.create` (creation intent for `iteration create --file`) - `knowledge.entry` - `backlog.item` ## 7. Generic append Most durable history is appended. The generic append command takes one complete schema-known element from stdin or a file: ```powershell dogdouspec append ` --document 20260823-xpath-core/tasks.xml ` --parent-xpath "//task[@id=$task_id]/records" ` --var task_id=20260823-task-xpath-projection ` --expected-revision 8 ` --stdin ``` stdin: ```xml Compared two projection implementations. Focused tests are required before selecting one. ``` Rules: - The parent XPath is evaluated against the current source and must select exactly one element. - The CLI resolves the selected node's schema declaration and validates the appended element in the resulting document context. - The appended root must have a project-unique ID. - The CLI increments the document revision and updates only schema-defined automatic root metadata. - Append cannot write protected product state. - Multiple top-level stdin nodes are rejected. Atomic combinations use `task update` or `transaction apply`. Append retry is identity-based. If the submitted root ID already exists and its canonical content is identical, the command returns success with `already_applied="true"`. If content differs, it returns `IDEMPOTENCY_CONFLICT`. ## 8. Atomic Task update ## 8. Atomic Task update `task update` handles the atomic combination of optional Task-state transition, Task acceptance criterion result updates, active Task-local record resolution, context replacement/update, and one or more appended structured records stamped with the request operation ID. ```powershell dogdouspec task update ` --iteration ID ` --task TASK_ID ` --expected-revision N ` (--stdin | --file PATH) ` [--workspace-root PATH] ` [--format xml|human] ``` Request schema: ```xml Updated context summary. Updated design snapshot. Implemented and verified deterministic projection. ``` Rules: 1. **State Machine Transitions**: - `start`: `pending` -> `in-progress` - `block`: `in-progress` | `verification` -> `blocked` - `resume`: `blocked` -> `in-progress` - `verify`: `in-progress` -> `verification` - `complete`: `verification` -> `done` - `transfer` / `supersede` / `cancel`: `pending` | `in-progress` | `blocked` | `verification` -> `transferred` | `superseded` | `cancelled` - Omitted `transition` leaves the state unchanged. - Illegal and same-state transitions are rejected as semantic conflicts (`TASK_TRANSITION_CONFLICT`, exit 4). 2. **Timestamps**: - Sets `task/@updated_at` to `task-update/@occurred_at`. - `start` sets `task/@started_at` to `occurred_at` only if `started_at` was absent. - `complete` sets `task/@completed_at` to `occurred_at`. 3. **Record Stamping & Anti-Spoofing**: - Every appended record is stamped with `operation_id="task-update/@id"`. - Supplying a conflicting `record/@operation_id` is rejected. - Generic `append` rejects any fragment containing `record/@operation_id` to prevent receipt spoofing. 4. **Durable Idempotency**: - Operations are derived directly from Task records carrying `operation_id = request.id`. - An exact retry with either the original pre-commit expected revision or the current revision returns `already_applied="true"` with exit code 0 if the Task state, criteria, record resolutions, context, timestamps, and stamped records match canonically. - Partial receipts, mismatched content, cross-Task collisions, or cross-document collisions are rejected as `IDEMPOTENCY_CONFLICT` (exit 4). 5. **Prospective Validation & Authority Gate**: - Root revision of `tasks.xml` is incremented exactly once per successful commit. - Whole-project prospective validation enforces all schema constraints, time-first grammar, ID uniqueness, and completion predicates before live file replacement. - `task update` mutates only `tasks.xml` under the target iteration and never mutates `spec.xml` or product decision state. - Terminal tasks (`done`, `transferred`, `superseded`, `cancelled`) are immutable; metadata changes, transitions, and non-informational record appends fail with `TASK_IMMUTABLE` (exit 4). - When iteration `status="replanning"`, execution transitions (`start`, `resume`, `verify`, `complete`) fail closed with `ITERATION_REPLANNING_EXECUTION_FROZEN` (exit 5). ## 8.1 Structured Task review gate Tasks may opt in with immutable implementer attribution and a review gate: ```xml ... ... ``` Submit the `task.review` request template while the Task is in `verification`: ```powershell dogdouspec task review --iteration ID --task TASK_ID --expected-revision N (--stdin | --file PATH) ``` An `approved` submission is accepted only when its actor differs from Task `@agent`, no active finding remains, and the operation ID is unused across the workspace. A `changes-requested` submission appends an active finding, moves the Task to `in-progress`, and requires correction, a new verification transition, and a fresh approval. Completion readiness reports missing approvals and active review findings. Legacy Tasks without `` retain their existing lifecycle. Actor separation is durable provenance, not authenticated or cryptographic identity. DogdouSpec does not prove who controls an actor string; repositories needing authenticated review must enforce that in their surrounding Git/CI or identity system. ## 8.2 Task addition, revision, and splitting ```powershell dogdouspec task add ` --iteration 20260823-xpath-core ` --expected-revision 12 ` (--stdin | --file PATH) dogdouspec task revise ` --iteration 20260823-xpath-core ` --task 20260823-task-xpath-projection ` --expected-revision 12 ` (--stdin | --file PATH) dogdouspec task split ` --iteration 20260823-xpath-core ` --task 20260823-task-xpath-projection ` --expected-revision 12 ` (--stdin | --file PATH) ``` 1. `task add`: Appends a pending task to `tasks.xml`. Requires `` referencing an existing requirement in `spec.xml`. Newly added task must have `status="pending"`. 2. `task revise`: Elaborates `rationale`, `scope`, `add_dependencies`, `add_constraints`, `add_acceptance`, and appends discussion records on active/pending tasks. Fails with `TASK_IMMUTABLE` if target task is in terminal status. Porcelain `--add-scope` merges deduplicated includes into repository `.` and preserves all other repositories and exclusions; raw XML scope remains whole-scope replacement. `--add-dependency` resolves one target and supplies `scope="document"` in the same tasks document or `scope="project"` across iterations. The merged request uses the observed exact revision to reject concurrent edits. 3. `task split`: Sets a parent task terminal disposition (`superseded`, `transferred`, `cancelled`) with rationale and records, and atomically appends 2 or more pending subtasks. These helper requests are bounded by the normal XML document-size limit before parsing or reading any managed input. Their `occurred_at` must not precede the `updated_at` of every task or document they modify. A newly added successor/task must be pending, stamped with `created_at` and `updated_at` exactly equal to request `occurred_at`, and must not supply `started_at` or `completed_at`. ## 8.2 Requirement proposal ```powershell dogdouspec requirement propose ` --iteration 20260823-xpath-core ` --expected-revision 5 ` (--stdin | --file PATH) ``` Appends a new requirement to `spec.xml` under ``. Requires `status="proposed"`. Attempting to supply non-proposed statuses fails with `OWNER_DECISION_REQUIRED` (exit 5). ## 8.3 Mid-flight change proposal and application ```powershell dogdouspec change propose ` --iteration 20260823-xpath-core ` --expected-spec-revision 5 ` --expected-tasks-revision 12 ` (--stdin | --file PATH) dogdouspec change apply ` --iteration 20260823-xpath-core ` --expected-spec-revision 6 ` --expected-tasks-revision 13 ` (--stdin | --file PATH) ``` 1. `change propose`: A recovery-backed multi-document mutation across `spec.xml` and `tasks.xml`, valid only while the iteration is `active`. It requires at least one active `finding` record, freezes target tasks to `blocked`, persists each freeze reason, and adds proposed requirements to `spec.xml`. The first finding task receives a deterministic receipt containing the change summary and a canonical-request `request-sha256` fingerprint. An identical immediate replay returns `already_applied`; any semantic payload difference or later revision drift fails. 2. `change apply`: Applied during iteration `status="replanning"`. It must resolve a finding, dispose a task, or add a successor (no-op requests fail); it resolves active finding records, persists every disposition rationale, sets terminal task dispositions (`superseded`/`transferred`/`cancelled`), adds successor tasks, and appends one deterministic receipt with the canonical-request fingerprint. Fails with `CHANGE_APPLICATION_INVALID` (exit 4) if iteration status is not `replanning`. `request-sha256` is an idempotency fingerprint over canonical request XML. It does not provide a signature, authenticity guarantee, or evidence integrity claim. ### 8.3.1 Deterministic public-CLI replanning smoke Run this drill only in a disposable workspace. It demonstrates the public command sequence; it does not authorize an Agent to make the two owner confirmations. Start from the `change.propose`, `change.apply`, and `iteration.confirmation` templates, replace every placeholder, and re-query the returned revisions before each subsequent write. 1. In an **active** iteration with an approved requirement and a started Task, submit `change propose --expected-spec-revision --expected-tasks-revision --file change-propose.xml`. The request creates an active finding, freezes each affected Task, and may propose a replacement requirement. 2. After an explicit owner decision, submit `iteration confirm --file owner-replan.xml` with `action="replan"`, the current revisions, and decisions that supersede/approve the relevant requirements. The iteration becomes `replanning`; execution transitions are frozen. 3. Submit `change apply --expected-spec-revision --expected-tasks-revision --file change-apply.xml`. Resolve the finding, dispose affected Task(s), and add successor Task(s) with origins pointing to approved requirements. 4. Run the read-only gate and require `technically_ready="true"` with required action `continue`: ```powershell dogdouspec iteration readiness --iteration --phase activation --format xml ``` 5. Only after a further explicit owner decision, submit `iteration confirm --file owner-continue.xml` with `action="continue"` and the current revisions. Confirm that a successor can be selected or started through the normal public Task commands. `TaskChangeWorkflowCliTests.ChangeProposeAndApply_Cli_EndToEndLifecycle_Succeeds` is the deterministic integration counterpart: it performs this public CLI sequence against an isolated workspace and verifies the readiness gate before continuation. ## 9. Readiness and product confirmation ```powershell dogdouspec iteration readiness ` --iteration 20260823-xpath-core ` --phase activation|completion ` --format xml ``` Readiness is read-only. It reports exact source revisions, technical facts, pending product decisions, and the required owner action. “Ready for review” is never serialized as “completed.” After explicit owner review: ```powershell dogdouspec iteration confirm --stdin ``` The confirmation request names expected source revisions and every decision to apply. The CLI cannot authenticate a human owner; `actor` is attribution and Skill invocation after current owner instruction is the authority boundary. The command validates inputs and gates, updates only protected `spec.xml` state, appends confirmation provenance, and commits once (leaving `tasks.xml` byte-identical). It never infers product acceptance from Task state. An Agent may prepare or display a confirmation template. The Skill must not invoke it without an explicit owner instruction in the current interaction. ## 10. Low-level transaction `transaction apply` remains available for schema migrations and atomic combinations not covered by v1 helpers: ```powershell dogdouspec transaction apply ` (--stdin | --file PATH) ` [--workspace-root PATH] ` [--format xml|human] ``` The request root is ``. Its operation ID is a time-first correlation ID for the commit and recovery marker. The request and operation ID are not retained as a durable business ledger after a successful commit, so a retry using stale pre-commit revisions fails with `REVISION_CONFLICT`. A request that is a semantic no-op at the exact current revisions returns `already_applied="true"` without rewriting a file. The engine supports: - Expected document revisions. - String variables. - Boolean XPath 1.0 assertions. - `append-child`, `replace-node`, `set-attribute`, and `remove-node`. - Pre-commit whole-workspace validation. - One recovery-backed commit for all changed documents. Documents are processed in request order. Operations within one document run sequentially against that document's working tree, so later XPath expressions observe earlier operations. Every mutating selector must return a real node-set from the current managed document and match its non-negative `expect` exactly. `append-child` and `set-attribute` target elements; `replace-node` targets non-root elements; `remove-node` targets non-root elements or attributes. Projection results from `ds:filter` and `ds:filter-out` are read-only clones and cannot be used as mutation addresses. Assertions may use ordinary XPath scalar or node-set effective-boolean semantics. The engine owns root `revision`: requests cannot set, remove, or replace it. Each semantically changed document increments once; assert-only and no-op documents do not increment and are omitted from the mutation document list. Payloads cannot contain `operation_id`, and existing Task-update receipt records cannot be modified or removed by the low-level transaction path. The transaction engine resolves all selected nodes before checking protected state. It compares the actual before/after XML trees, not the XPath spelling. Iteration lifecycle and confirmations remain protected. Decided Requirements, Research questions, design decisions, product acceptance, verified Knowledge, and disposed Backlog items cannot be changed through this helper. Draft and proposed planning content may be edited, and structured history records may be appended, without turning the edit into product approval. The Skill does not choose low-level transaction XML when an equivalent v1 template or helper exists. ## 11. Atomic filesystem behavior Writers acquire one `.dogdouspec` project lock. They load and validate expected revisions, stage complete replacement files in a workspace-local temporary directory, flush them, and replace targets. Single-document mutations must leave either the complete old file or complete new file after interruption. During a low-level multi-document publish, readers may temporarily observe a mix of complete old/new document revisions. The next writer's startup recovery converges the transaction to one complete valid old or new set. Iteration creation and low-level multi-document transactions use a minimal recovery marker under a CLI-owned temporary area; transaction requests are not retained as project history. Startup recovery completes or rolls back an interrupted prepared commit before serving another write. Reads do not take the writer lock but must observe a complete old or new document. ## 12. Secure input behavior All XML requests and managed documents use secure readers with DTD and external resolution disabled. XPath is read-only. Extension functions have no file, network, environment, process, or mutation access. Malformed XML, unsupported schemas, invalid XPath, cardinality mismatch, protected writes, and limit violations fail closed without modifying managed documents.