Repository navigation
Remove requires_spec from task; the spec rule applies only to a task that links a spec (closes #3718) - #3725
Conversation
Pragmatic Code Review: PR #3725
SummaryThe change does what the issue asks and is a clear net improvement: one workflow's marker leaves the core task type, the rule narrows to tasks that link a spec, and every layer of the node type sequence is touched (schema, wire type, typed update, proto, daemon, app-lib, generated TypeScript, hand-written TypeScript, dev-proxy, tests, and the sheet). No compatibility read, no migration, no literal Requirements Check
Code Review Findings🔴 CriticalNone. 🟡 Important1. A schema can still declare
🟢 Suggestions2. The refusal skips a user subtype's own bucket, where the field is just as unreadable
3. Two neighbouring read-name collisions the check does not reach (pre-existing, not introduced here; from reading)
4. Test coverage of the shadow refusal
Nitpicks
What is done well
RecommendationAPPROVE, with finding 1 recommended before merge (or an explicit decision to defer it). Findings 2 to 4 and the nits are optional. Reminder: push the |
malibio
left a comment
There was a problem hiding this comment.
Automated pragmatic-code-review: APPROVE (posted as a comment — GitHub blocks self-approval). Full findings in the review comment above.
Review addressedAddressed
Not done
Verification: Re-Review DecisionDecision: NO RE-REVIEW NEEDED Rationale: No critical finding. The changes narrow one check by two conditions and widen it to the buckets the reviewer named, each pinned by a new test, one of them mutation-checked. The rest is comments and a test assertion. |
…that links a spec (closes #3718) The task spec Play now rejects moving a task to in_progress only when the task links at least one spec and none of them is approved (ADR-097 §1). A task that links no spec is an ordinary to-do and starts with nothing set. The requires_spec field is deleted from the task schema, the wire type and typed update, the proto, the daemon, app-lib and the generated TypeScript. The rejection message and the two seeded skills name no marker. A write that sets an extension field named after a declared field of a core type (custom:status on a task) is refused, naming the declared field: a rule reads an extension field by its bare name and the declared field wins it (ADR-097 §6). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… shadowed name in every bucket of the chain - A key the schema declares under its prefixed name is not refused, so a declared field's default no longer fails every create. - A bare name that is itself prefixed is not compared. - The refusal covers a user subtype's own bucket. - Tests: bucketed write, inherited field, schema-declared field. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ce38200 to
85fee9f
Compare
Closes #3718
What changed
The task spec Play applies only to a task that links a spec. Moving a task to
in_progressis rejected when the task links at least one spec and none of them hasspec_statusapproved(ADR-097 §1). A task that links no spec is an ordinary to-do and starts with nothing set on it (§6).requires_specis deleted. No replacement field, no compatibility read.An extension field named after a declared field is refused on write.
custom:status(ororg:/plugin:+ any declared field name) on a core type is rejected, naming the declared field. A rule reads an extension field by its bare name and the declared field always wins that name, so such a field could be stored and never read.Node type sequence
task, flat core type, category unchanged.requires_spec(boolean, defaulttrue). Task now declares seven fields.reject-starting-a-task-whose-spec-is-not-approved; conditions arenode.status == 'in_progress',has(node.spec) && size(node.spec) > 0, and!node.spec.exists(s, has(s.spec_status) && s.spec_status == 'approved').core_schemas.rs), wire type and typed update (nodespace-types), proto, daemon, app-lib, generated TypeScript (bun run gen:types), the hand-written TypeScript around it, dev-proxy.tasksheet incomponents/node-types.mdis updated in the docs working tree and is pushed to docsmainjust beforebun run merge. ADR-097 is already on docsmain.Other changes
implementing-a-task,breaking-a-plan-into-tasks) name no marker. The next step in the message is to ask the user to approve the spec.permittedfilter.requires_spec: falseonly to be startable no longer set it. Thespec_gated_tasktest helper is gone: every test task is a plain task.Tests
a_task_with_no_spec_starts_with_nothing_set,a_task_with_a_draft_spec_and_no_plan_cannot_start,a_task_with_several_specs_starts_when_one_is_approved, and the Ready queue test (offers a task with no spec, withholds one whose spec is a draft).an_extension_field_named_after_a_declared_field_is_rejected: create and update, all three prefixes, and the same name accepted on a type that declares no such field.bun run test:changedpasses (frontend, scripts, browser,types:check,node-types:check, Rust workspace).Worth a reviewer's attention
custom:statusontask(existing tests cover that path), and a write that sets it is now refused. Refusing the name at schema-edit time is a non-goal of the issue.🤖 Generated with Claude Code