CANP-WP-0002 T01: input defaults, static and derived
Closes the gap that made optional inputs unusable: rendering rule 5.1(4) made any unresolved placeholder an error while inputs had no `default`, so an input marked `required: false` and referenced from the template failed every render in which the caller omitted it — including the spec's own section 4 example. Section 10 already carried the derivation mechanism (`requirement: generate`, resolution deliberately undefined), so a derived default needed a binding rather than a new concept: the input's default names a declared prompt dependency. Spec: - 5.1 rewritten as "Resolution and rendering". Resolution may be non-deterministic and must report what it derived; rendering is deterministic and must not derive. A tool that handles only supplied values and static defaults is stated to be conforming. - 6.1 (new) covers both declaration forms. Reference form is preferred, with the reason stated — an inline prompt is anonymous, so unversioned, unprovenanced and un-evaluable — and validators should warn when a published package derives inline. - A derived default may declare a static fallback `value`. Without one the input stays unresolved, which is an error; derivation never silently yields empty content. - 4, 10, 18 (rules 11-13), 19 (two new MUST NOTs), 21 updated accordingly. Reference CLI: - New `resolve` verb reporting the origin of every value. - `Resolution` dataclass and `resolve_inputs`; `resolve_values` kept as a wrapper so existing callers are unaffected. - `render` refuses with a specific error naming underivable inputs rather than substituting empty text. - Tests 3 -> 11. Example package lifecycle re-verified end to end. INTENT.md is unchanged: splitting resolve from render preserves success criterion 4 (deterministic rendering) as written. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bjefh8NUiEiahN4JLwoSKM Assistant: claude-code Assistant-Model: opus Assistant-Process: 388925@bnt-lap001 Assistant-Session: 3507023f-e0fd-4a1e-9d90-a0d4217d1502
This commit is contained in:
parent
0caf065544
commit
169db25d25
6 changed files with 600 additions and 36 deletions
|
|
@ -40,7 +40,7 @@ or execution engine that satisfies it.
|
|||
|
||||
```task
|
||||
id: CANP-WP-0002-T01
|
||||
status: todo
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "e49bf036-0aee-5bb2-abbd-3d3f683df298"
|
||||
```
|
||||
|
|
@ -62,22 +62,56 @@ allow that default to be either
|
|||
|
||||
Unresolved-with-no-default remains an error.
|
||||
|
||||
**Design note.** § 10 already carried the derivation mechanism:
|
||||
`dependencies` accepts `requirement: generate`, defined as "a resolver MAY
|
||||
satisfy a missing dependency by invoking an appropriate generation process",
|
||||
with resolution left undefined. A derived default therefore did not need a new
|
||||
concept, only a binding — the input's default names the dependency, and the
|
||||
dependency records what may be generated and at which version.
|
||||
|
||||
**Follow-up decisions (operator, 2026-09-06):**
|
||||
|
||||
- *Both declaration forms are allowed.* A derived default may reference a
|
||||
declared prompt dependency, or carry an inline `prompt`. The reference form
|
||||
is preferred and the spec says why (an inline prompt is anonymous —
|
||||
unversioned, unprovenanced, un-evaluable), and a validator SHOULD warn when a
|
||||
**published** package derives inline. Inline is for local and draft packages.
|
||||
- *Error unless static fallback.* A derived default MAY declare a static
|
||||
`value`. A consumer that does not derive uses it; with no fallback the input
|
||||
stays unresolved, which is an error. Derivation never silently yields empty
|
||||
content.
|
||||
- *Split render from resolve.* Resolution decides values and may be
|
||||
non-deterministic; rendering substitutes and always is. Rendering MUST NOT
|
||||
derive. This preserves INTENT success criterion 4 verbatim — no change to
|
||||
`INTENT.md` was needed.
|
||||
|
||||
Work:
|
||||
|
||||
1. Extend § 6 with `default`, and state the two default kinds.
|
||||
2. Specify the derived-default declaration form so it stays inert data: the
|
||||
package declares *what* to derive and the prompt to derive it with; it never
|
||||
names or requires a specific resolver, model, or runtime. A consumer that
|
||||
cannot derive must report the input as unresolved rather than guess.
|
||||
3. Reconcile § 5.1: rules 1–2 gain input defaults; rule 4 keeps unresolved as
|
||||
an error; § 5.1's "no conditionals, loops, filters, or functions" and
|
||||
§ 19's "MUST NOT execute code merely because it appears in a package" must
|
||||
survive the change — a derived default is a *request to a consumer*, not
|
||||
template-embedded execution. Say so explicitly.
|
||||
4. Extend § 18 validation accordingly.
|
||||
5. Implement static defaults in `reference/canned_prompts.py` `resolve_values`
|
||||
and add tests. Derived defaults: validate and surface them; the reference
|
||||
CLI never calls a model, so it reports them as unresolved-by-design.
|
||||
Delivered:
|
||||
|
||||
1. § 5.1 rewritten as "Resolution and rendering" — six resolution rules and
|
||||
four rendering rules, with rendering explicitly deterministic and forbidden
|
||||
from deriving (rule 10). Resolution must report which values were derived
|
||||
(rule 6). A tool that resolves only supplied values and static defaults is
|
||||
stated to be conforming.
|
||||
2. § 6 gains `default` in the field table plus a new § 6.1 covering both
|
||||
declaration forms, the static fallback, and why the reference form is
|
||||
preferred.
|
||||
3. § 4 manifest surface updated: `repository_context` — the field that
|
||||
demonstrated the original defect — now carries a derived default with a
|
||||
fallback, backed by a `requirement: generate` prompt dependency.
|
||||
4. § 10 states the binding between `requirement: generate` and a referenced
|
||||
derived default.
|
||||
5. § 18 gains validation rules 11–13 and the publish-time inline warning.
|
||||
6. § 19 gains two MUST NOTs: a derived default's prompt text is not an
|
||||
instruction addressed to the consuming tool, and derivation must be visible
|
||||
to the caller.
|
||||
7. § 21 documents the new `resolve` verb.
|
||||
8. `reference/canned_prompts.py`: `Resolution` dataclass, `resolve_inputs`
|
||||
(with `resolve_values` kept as a wrapper), `input_default_kind`,
|
||||
`prompt_dependency_ids`, `validate_input_default`, a `resolve` command, and
|
||||
a specific render-time error naming the underivable inputs. Tests: 3 → 11,
|
||||
all passing. Both READMEs document the split.
|
||||
|
||||
## Registry namespaces and ownership
|
||||
|
||||
|
|
@ -113,6 +147,10 @@ capture") and the `dependencies.prompts` field both promise composition, but
|
|||
v0.1 defines no mechanism — `dependencies` is a declared field with no
|
||||
semantics.
|
||||
|
||||
T01 has since settled one corner of this: a derived default binds an input to
|
||||
a prompt dependency declared `requirement: generate`, so package-to-package
|
||||
reference already exists for that one case. Build on it rather than around it.
|
||||
|
||||
Decide what composition means at the *artifact* level: how one package
|
||||
references another, whether references are includes, extends, or plain
|
||||
declared prerequisites, and how versions are pinned. Leaning: declaration only
|
||||
|
|
@ -154,9 +192,10 @@ manifest surface with no semantics whatsoever in v0.1, and § 9
|
|||
|
||||
Decide: what a context dependency declares, how it differs from an input, how
|
||||
it relates to `compatibility.capabilities`, and whether capability names are
|
||||
free strings in v0.2 (model capability vocabularies stay deferred). Coordinate
|
||||
with T01 — a derived default is a consumer-resolved context requirement, and
|
||||
the two mechanisms must not describe the same thing twice.
|
||||
free strings in v0.2 (model capability vocabularies stay deferred). T01 is now settled and partly answers this: a derived default is a
|
||||
consumer-resolved context requirement expressed through `dependencies.prompts`
|
||||
rather than through `dependencies.context`. Decide whether `context` is still a
|
||||
distinct concept or collapses into the prompt-dependency mechanism.
|
||||
|
||||
## Rewrite specification section 23
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue